1 c++基础知识
1.1变量:给一段指定的内存空间起名字,方便操作这段内存
语法:数据类型 变量名 = 初始值;
1.2常量:用于记录程序中不可更改的数据
两种定义方式:
1.#define宏常量:#define 常量名 常量值 通常在文件的上方定义表示一个常量
2.const修饰的变量:const 数据类型 常量名 = 常量值(const关键字修饰则该常量不可修改)
例: #define day 7
int main() {
cout << “一周里总共有 " << day << " 天” << endl;
//day = 8; //报错,宏常量不可以修改
//2、const修饰变量
const int month = 12;
cout << “一年里总共有 " << month << " 个月份” << endl;
//month = 24; //报错,常量是不可以修改的
system(“pause”)
1.3关键字:c++预先保留的单词(标识符)
给变量起名字的时候不可以和关键字同名。
1.4标识符命名的规则:标识符不能是关键字
标识符只能由字母、数字、下划线组成
第一个字符必须是字母或下划线
标识符区分大小
2.数据类型
2.1整型:short(短整型)2字节、int 4字节、long (Windows 下4字节、Linux下、4字节32位、8字节64位)、long long长长整型 8字节
2.2 sizeof关键字:利用sizeof关键字可以统计数据类型所占内存大小:sizeof(数据类型或变量)
short<int<=long<=long long
2.3浮点型:用于表示小数
1.单精度float
2.双精度double
两者的区别在于表示的有有效数字的范围不同
float:占用4字节空间、可以表示7位有效数字
double:占用8字节空间、可以表示15–16有效数字
2.4字符型:用于显示单个的字符
char ch=‘a’;
1.显示字符型常量时用单引号、千万不要用双引号
2.单引号内只能有一个字符,不可以是字符川串
3.字符型变量只占用1个字节
4.字符型变量并不是字符本身放到内存中存储,而是把对应的ASCII编码放入存储单元
例:char ch = ‘a’;
cout << ch << endl;
cout << sizeof(char) << endl; 查看内存1字节
cout << (int)ch << endl; //查看字符a对应的ASCII码
2.5 字符串型:用于表示一串字符
1.c语言风格:char 变量名[]=“字符串值”
2.c++风格:string 变量名 = “字符串值” (注意包含头文件)
2.6 布尔类型bool:表示真或假
真true:1、假false:0
bool类型占一个字节大小
2.7从键盘获取数字关键字:cin
cin>>变量
3.运算符
算术运算符:四则运算
赋值运算符:表达式的值给变量
比较运算符:表达式的比较、返回一个真值或假值
逻辑运算符:根据表达的式的值返回真值或假值
3.1算数运算符
取模(即取余数%):10%3=1 只有整型变量才可以进行取模运算
前置递增、递减:++a:
a=2;
b=++a;
a=3;
b=3;
–a:
a=2;
b=–a;
a=1;
b=1;
后置递增、递减:a++:
a++:
a=2;
b=a++;
b=2;
a=3;
a–:
a=2;
b=a–;
a=1;
b=2;
前置与后置的区别:
前置是先对变量进行操作改变之后在进行表达式运算
后置是先对表达式运算再对变量进行操作改变
3.2赋值运算符
模等于:%=
a=3;
a%2;
a=1;
3.3比较运算符:用于表达式的比较返回真或假
3.4逻辑运算符:根据表达式的值返回真或假
!非 !a:如果a为假,则!a为真; 如果a为真,则!a为假。
&& 与 a && b 如果a和b都为真,则结果为真,否则为假
|| 或 a || b 如果a和b有一个为真,则结果为真,二者都为假时,结果为假。
4程序流程结构
顺序结构:按顺序执行不发生跳转
选择结构:根据条件是否满足有选择执行相应功能
循环结构:依据条件是否满足,循环多次执行某段代码
4.1选择结构
4.1.1 if语句:执行满足条件的语句(if
条件表达式后不要加分号)
多行if:if(条件){ 条件满足执行的语句 }else{ 条件不满足执行的语句 };
多条件if语句:if(条件1){ 条件1满足执行的语句 }else if(条件2){条件2满足执行的语句}…
else{ 都不满足执行的语句}
if (score > 600)
{
cout << “我考上了一本大学” << endl;
}
else if (score > 500)
{
cout << “我考上了二本大学” << endl;
}
else if (score > 400)
{
cout << “我考上了三本大学” << endl;
}
else
{
cout << “我未考上本科” << endl;
}
4.1.2三目运算符:通过三目运算符实现简单的判断
表达式1 ? 表达式2 :表达式3
如果表达式1的值为真,执行表达式2,并返回表达式2的结果;
如果表达式1的值为假,执行表达式3,并返回表达式3的结果。
4.1.3 switch语句:执行多条件分支语句
1:switch语句中表达式类型只能是整型或者字符型
2:case里如果没有break,那么程序会一直向下执行
总结:与if语句比对于多条件判断时,switch的结构清晰,执行效 率高,缺点是switch不可以判断区间
4.2循环结构
4.2.1while循环语句:while(循环条件){ 循环语句 }
只要循环条件的结果为真,就执行循环语句
4.2.2 do…while语句:与while的区别在于do…while会先执行一次循环语句,再判断循环条件
4.2.3 for循环语句
for(起始表达式;条件表达式;末尾循环体) { 循环语句; }
注意:for循环中的表达式,要用分号进行分隔
总结:while , do…while, for都是开发中常用的循环语句,for循环结构比较清晰,比较常用
4.2.4嵌套循环
//外层循环执行1次,内层循环执行1轮
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
cout << “*” << " ";
}
cout << endl;
}
4.3跳转语句
4.3.1 break语句
出现在switch条件语句中,作用是终止case并跳出switch
出现在循环语句中,作用是跳出当前的循环语句
出现在嵌套循环中,跳出最近的内层循环语句
//1、在循环语句中用break
//for (int i = 0; i < 10; i++)
//{
// if (i == 5)
// {
// break; //跳出循环语句
// }
// cout << i << endl;
//}
//在嵌套循环语句中使用break,退出内层循环
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (j == 5)
{
break;
}
cout << "*" << " ";
}
cout << endl;
}
system("pause");
return 0;
4.3.2 continue语句:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
注意:continue并没有使整个循环终止,而break会跳出循环
5数组
5.1数组就是一个集合,里面存放了相同类型的元素
1.数组的每个元素的类型都一样
2.数组是由连续内存位置组成的
5.2一维数组
5.2.1一维数组的定义方式:
1.数据类型 数组名[ 数组长度 ];
2. 数据类型 数组名[ 数组长度 ] = { 值1,值2 …};
3. 数据类型 数组名[ ] = { 值1,值2 …};
注意:数组的下标是从0开始索引的
5.2.2一维数组数组名
一维数组名称的用途:
1. 可以统计整个数组在内存中的长度
2. 可以获取数组在内存中的首地址
//数组名用途
//1、可以获取整个数组占用内存空间大小
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
cout << "整个数组所占内存空间为: " << sizeof(arr) << endl;
cout << "每个元素所占内存空间为: " << sizeof(arr[0]) << endl;
cout << "数组的元素个数为: " << sizeof(arr) / sizeof(arr[0]) << endl;
//2、可以通过数组名获取到数组首地址
cout << "数组首地址为: " << (int)arr << endl;
cout << "数组中第一个元素地址为: " << (int)&arr[0] << endl;
cout << "数组中第二个元素地址为: " << (int)&arr[1] << endl;
注意:数组名是常量,不可以赋值
总结1:直接打印数组名,可以查看数组所占内存的首地址
总结2:对数组名进行sizeof,可以获取整个数组占内存空间的大小
5.3二维数组
二维数组定义的四种方式:
1. 数据类型 数组名[ 行数 ][ 列数 ];
2. 数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
3. 数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
4. 数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4}
5.3.2二维数组数组名
查看二维数组所占内存空间
获取二维数组首地址
int arr[2][3] =
{
{1,2,3},
{4,5,6}
};
cout << "二维数组大小: " << sizeof(arr) << endl;
cout << "二维数组一行大小: " << sizeof(arr[0]) << endl;
cout << "二维数组元素大小: " << sizeof(arr[0][0]) << endl;
cout << "二维数组行数: " << sizeof(arr) / sizeof(arr[0]) << endl;
cout << "二维数组列数: " << sizeof(arr[0]) / sizeof(arr[0][0]) <<
cout << "二维数组首地址:" << arr << endl;
cout << "二维数组第一行地址:" << arr[0] << endl;
cout << "二维数组第二行地址:" << arr[1] << endl;
总结1:二维数组名就是这个数组的首地址
总结2:对二维数组名进行sizeof时,可以获取整个二维数组占用的内存空间大小
6函数
6.1:函数就是将一段经常使用的代码封装起来,减少重复代码
6.2:函数定义步骤
1.返回值的类型
2.函数名
3.参数列表
4.函数体语句
5.return语句表达式
6.3形参与实参:函数定义小括号里称为形参,函数在调用时传入的参数称为实参。
6.4函数的值传递
所谓值传递,就是函数调用时实参将数值传入给形参
值传递时,如果形参发生改变,并不会影响实参
6.5函数的常见样式
1.无参无返
2.有参无返
3.无参有返
4.有参有返
6.6函数的声明:告诉编译器函数名称以及如何调用函数,函数的主题可以单独定义。
注意:函数的声明可以有多次,但函数的定义只能有一次。
6.7函数的分文件编写
四个步骤:
1.创建.h的头文件
2.创建.cpp的源文件
3.在头文件中写函数的声明
4.在源文件中写函数的定义也就是具体实现(开头要用#include关键字将函数的头文件包含)
5.main函数文件如果使用该函数只要用#include关键字将函数头文件进行包含即可
7.指针:可以通过指针间接访内存、指针也是一种数据类型
1.内存编号是从0开始记录的,一般用十六进制数字表示(一般进行(int)转换称为int十进制数查看)
2.可以利用指针变量保存地址
7.1指针变量的定义和使用
数据类型 * 变量名
1.指针定义
int a = 10;定义整型变量a
int * p;
p = &a;将指针p指向变量a的地址
cout<<&a; 打印a的地址
cout<<p; 打印指针变量p
经过实验可以看出打印指针变量p是一个十六位地址003AFC68打印&a的地址也是003AFC68。
2.指针的使用
可以通过*操作指针变量指向的内存cout<<*p; 可以看到打印出的是10也就是a所存储的数据,也就是变量a这块内存所存储的数据
总结:指针指向变量的地址,对指针进行解引用操作之后可以对该地址的内存所存放的数据进行操作
指针变量和普通变量的区别
普通变量存放的是数据,指针变量存放的是地址
指针变量可以通过" * "操作符,操作指针变量指向的内存空间,这个过程称为解引用
7.3指针所占内存空间
利用sizeof可以进行查看,不管是什么类型的指针都是4字节的(32位操作系统)、8字节(64位操作系统)。在vs编译器中,x86则是32位操作系统,x64则是64操作系统。
7.4空指针和野指针
空指针:指针变量指向内存中编号为0的空间(0—255号不可以访问)
用途:初始化指针变量
注意:空指针所指向的内存是不可以访问的
int * p=NULL;
野指针:指针变量指向非法的内存空间
例如:int * p=(int *)0x1100 此段代码就是将指针直接指向地址编号为0x1100的空间
7.5 const修饰指针
三种情况:const 修饰指针——常量指针
const修饰常量——指针常量
const即修饰指针又修饰常量
常量指针:const int * p=&a;const修饰的是指针,指针的指向可以改,但指针指向的值不可以进行更改
p=&b; 正确 因为允许指针p由指向变量改为指向变量b
*p=100;错误 解引用操作试图更改指针指向的值,不允许
指针常量:int * const p=&a;const修饰的是常量,指针的指向不可以进行更改,指针指向的值可以进行更改
p=&b;错误 因为试图将指针常量p的指向由变量a指向b;
*p=100; 正确,允许通过解引用操作将指针指向的值进行更改
const即修饰指针又修饰常量:const int * const p=&a;
指针的指向和指针所指向的值都不能更改
总结:主要看const关键字右侧是什么进行判断指针的指向,指针指向的值是否可以更改。
7.6指针和数组
利用指针访问数组:
int main() {
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int * p = arr; 将指针指向数组的首地址即第一个元素的地址
第一个元素: " << arr[0] << endl;
cout << "指针访问第一个元素: " << *p << endl; 通过解引用可以查看指针指向的值
for (int i = 0; i < 10; i++)
{
//利用指针遍历数组
cout << *p << endl;
p++; 让指针的指向每次偏移一位
}
7.7 指针和函数
利用指针做函数的参数,可以修改实参的值
值传递
void swap1(int a ,int b)
{
int temp = a;
a = b;
b = temp;
}
//地址传递
void swap2(int * p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main() {
int a = 10;
int b = 20;
swap1(a, b); // 值传递不会改变实参
swap2(&a, &b); //地址传递会改变实参 指针做形参,需要传入地址
8.结构体
1.结构体可以理解为用户自己定义的数据类型,和int、double一样
2 .注意:结构体和类比较相似,两者的区别在于结构体成员在默认情况下是公共的,而类成员在默认权限下是私有的。