多维数组
一个多维数组在语义上并不等价于一个指向其元素类型的指针,相反他等价于一个“指向数组的指针"
int b[3][4] <=> int(*const b)[4]
int c[3][4][5] <=> int(*const c)[4][5]
char *p1 = new char[5][3]; // ERROR!语义不等价
int *p2 = new int[4][5]; // ERROR!语义不等价
char (*p3)[2] = new char[5][2]; // OK!退化第一维,语义等价
int (*p4)[5][7] = new char[20][5][7]; // OK!退化第一维,语义等价
同理不能用:
delete [][]p3;
delete [][][]p4
来释放,正确应该是:
delete []p3;
delete []p4;
字符串,字符数组,字符指针
字符数组:就是元素为字符(char)类型变量的数组。
字符串:以字符‘\0’结尾的字符数组。或者说存放字符常量的字符数组。
字符指针:执行字符类型变量的指针。
字符串函数(strlen,strcpy,strcmp等等)的参数类型为字符指针,但函数实现默认实参为字符串变量
当字符指针str作用在标准输出函数printf("%s",str), cout << str <<endl;也认为实参为字符串变量。
位域
C中位域必须是int, unsigned int, signed int ,C++还允许是char ,long
位域中定义非具名位域成员,相当于占位符。长度为0的位域用于迫使下一个成员从下一个完整的机器字(word)
开始。位域成员不能取地址(&),位域对象(变量)是可以的。
结构体/类的成员对齐
理解这句话:编译器在考虑一个类型的大小的时候不仅要考虑一个对象的对齐要求,还要考虑该类型
数组的对齐要求。尽量按照从大到小的顺序从前向后依次声明数据成员,并吸纳尾填充来提高内存使用效率。
程序设计时,库(动态库,静态库)和可执行程序之间,成员的对齐方式要一致。
头文件包含的合理顺序
在头文件中:
1)包含当前工程自定义的头文件;
2)包含第三方程序头文件;
3) 包含标准头文件;
在源文件中:
1)包含该源文件对应的头文件;
2)包含当前工程自定义的头文件;
3)包含第三方程序头文件;
4) 包含标准头文件;
#和##运算符
#叫做构串操作符,修饰带参数的红的形参,它将实参的字符转成字符串常量。
#define STRING(x) #x #x
char *s = STRING(abc); // *s="abcabc"
#define TEXT(x) "class" #x
char *s = TEXT(abc); // *s="classabc"
##合并操作符,将出现在其左右的字符序列合成一个新的标识符
#define CLASS_NAME(name) cl_##name
CLASS_NAME(event) 等效cl_evnet
一个多维数组在语义上并不等价于一个指向其元素类型的指针,相反他等价于一个“指向数组的指针"
int b[3][4] <=> int(*const b)[4]
int c[3][4][5] <=> int(*const c)[4][5]
char *p1 = new char[5][3]; // ERROR!语义不等价
int *p2 = new int[4][5]; // ERROR!语义不等价
char (*p3)[2] = new char[5][2]; // OK!退化第一维,语义等价
int (*p4)[5][7] = new char[20][5][7]; // OK!退化第一维,语义等价
同理不能用:
delete [][]p3;
delete [][][]p4
来释放,正确应该是:
delete []p3;
delete []p4;
字符串,字符数组,字符指针
字符数组:就是元素为字符(char)类型变量的数组。
字符串:以字符‘\0’结尾的字符数组。或者说存放字符常量的字符数组。
字符指针:执行字符类型变量的指针。
字符串函数(strlen,strcpy,strcmp等等)的参数类型为字符指针,但函数实现默认实参为字符串变量
当字符指针str作用在标准输出函数printf("%s",str), cout << str <<endl;也认为实参为字符串变量。
位域
C中位域必须是int, unsigned int, signed int ,C++还允许是char ,long
位域中定义非具名位域成员,相当于占位符。长度为0的位域用于迫使下一个成员从下一个完整的机器字(word)
开始。位域成员不能取地址(&),位域对象(变量)是可以的。
结构体/类的成员对齐
理解这句话:编译器在考虑一个类型的大小的时候不仅要考虑一个对象的对齐要求,还要考虑该类型
数组的对齐要求。尽量按照从大到小的顺序从前向后依次声明数据成员,并吸纳尾填充来提高内存使用效率。
程序设计时,库(动态库,静态库)和可执行程序之间,成员的对齐方式要一致。
头文件包含的合理顺序
在头文件中:
1)包含当前工程自定义的头文件;
2)包含第三方程序头文件;
3) 包含标准头文件;
在源文件中:
1)包含该源文件对应的头文件;
2)包含当前工程自定义的头文件;
3)包含第三方程序头文件;
4) 包含标准头文件;
#和##运算符
#叫做构串操作符,修饰带参数的红的形参,它将实参的字符转成字符串常量。
#define STRING(x) #x #x
char *s = STRING(abc); // *s="abcabc"
#define TEXT(x) "class" #x
char *s = TEXT(abc); // *s="classabc"
##合并操作符,将出现在其左右的字符序列合成一个新的标识符
#define CLASS_NAME(name) cl_##name
CLASS_NAME(event) 等效cl_evnet