20240712
最近开始看候捷的c++视频,视频是从类开始讲的,过程中发现很多c的知识有点忘了,而且c++也有很多新的语法特性。因此看完前几个视频后花点时间过一下c++ primer前六章,记录一下需要学习的c++新特性和代码规范。
- 学引用时有点乱,抽时间搞一下值类型的总结
#第二章
基本类型
long long类型:64位
- 数值不为负时使用unsinged,这里尤其要注意循环的使用
错误例子:
//死循环代码
for(unsigned a =10; a>=0; a--)
-
最优先使用的类型:整数int,浮点数double,超越int范围long long
-
char在一些机器上是有符号的而一些上是无符号的,因此使用时要明确指定signed char或者unsigned char
变量
-
字面值常量,其形式和类型决定它的数据类型,可以使用前缀或者后缀进行指定
-
c++11新特性,列表初始化
-
统一语法:使用花括号
{}
进行初始化。 -
自动避免窄化转换:在列表初始化中,如果初始化过程会导致数据丢失(如,从 double 到 int 的转换),编译器会报错。
int a{1.1};
-
适用于所有类型:包括 POD(Plain Old Data)类型、聚合类型、类类型等。
- 变量的声明与定义:用于分离式编译
-
变量声明规定变量的类型与名字,使用关键字 extern
-
定义则在声明的基础上为之申请存储空间
extern int a;/声明
int a;//声明并定义
extern int a = 1;//定义
变量只能被定义一次,但能够进行多次声明。在多个文件中使用同一个变量时,其定义只能出现在一个文件中,其他使用时需进行声明。
- 类型检查:c++作为静态类型语言,编译器在编译阶段对变量进行类型检查,因此在使用变量时必须进行声明,也就是说赋予其类型。
- 注意作用域与作用域操作符
复合类型
这里由于&,*这两个符号的多重意义,在作为声明的一部分出现时最好和数据类型写在一起
引用
c++11中分为左值引用、常量左值引用、右值引用。这里先只学习左值引用
- 左值引用(即通常意义下的引用)
语法:
int a=1;
int& refa1=a;//refa是对a的引用
int b=1;
-
引用即别名:引用不是新定义一个变量,而是给已存在的变量取了一个别名,它和它引用的变量共用同一块内存空间。引用只能绑定对象,而引用本身不是对象,是别名。
-
引用在定义时必须初始化,而不能先声明再赋值。而且类型必须严格匹配。只能绑定左值而不能绑定。
int& refa2; refa = 2a;//报错 double& dref = a;//报错 int& ref10 = 10;//错误,10为字面值常量,右值 string str = "abc"; string &s = str;//正确。字符串字面值为左值
-
引用不能重新绑定
&refa1=b;//报错 lvalue required as left operand of assignment,=的左值是一个常量
-
一个变量可以有多个引用,同时一个引用也可以继续引用。
int& refa2=a;//正确 int& ref=refa1;//正确。refa1即使a的别名,均会与a进行绑定
指针
- 语法:数据类型* 指针变量名;
指针是一个变量,存储另一个变量的内存地址。声明中指针的类型用于指定它所指向对象的类型
int a=1;
int* p1;
p1 = &a;//&作为取址符,p中存放a的地址。因此p是一个指向int的指针
p1 = a;//报错
double* p2 = &a;//报错
std::cout<<*p1;//输出1,解引用符*来访问指针指向的对象。
*p1 = 2;
std::cout<<a;//输出2
- 指针值总会是下列四种状态之一:
-
指向一个对象的地址
-
指向紧邻对象所占空间的下一个位置
-
空指针,意味着指针没有指向任何对象。其地址为0,任何程序数据都不会存储在地址为0的内存块中,它是被操作系统预留的内存块。
int* p = NULL; int* p = nullptr;//优先使用 int* p = 0; std::cout<<p;//输出0
-
无效指针(野指针),上述情况之外的其他值。未经初始化的指针就是个无效指针,任何一个指针变量在做解地址操作前,都必须保证它指向的是有效的、可用的内存块,否则会出现无法预料的错误,而编译器无法检查出此类错误。所以在定义指针变量的时候一定要进行初始化。如果实在是不知道指针的指向,则初始化为空指针。
-
void* 指针
void* 可以存放任何类型的地址,而不能访问其对象
int a=1; void* p = &a; std::cout<<p;//正确,输出a的地址 std::count<<*p;//报错 'void*' is not a pointer-to-object type
-
指向指针的指针
通过*的个数区分指针的级别,
int a = 1; int* p = &a; int** pp = &p;
-
指向指针的引用
int i = 1; int* p = nullptr; int*& r = p;//从右往左读,&说明r是一个引用,*说明r引用的是一个指针,int说明r引用的指针的类型是int r = &i;//相当于令p指向了i; *r = 0;//将i的值改为0;