- 谈及背景
int a[3]; sizeof(arr) = 12B
,这个让我很不理解,后来通过一系列调查研究出了sizeof 一些性质:- sizeof()是单目运算符,和‘++’一样,不是库函数。
- sizeof()算结构体的大小 有对应的规则
- 算结构体大小与结构体中成员排列的顺序有关系,这里引入一个概念偏移量(结构体中成员地址与结构体地址的偏移量,结构体中第一个成员变量地址就是结构体地址,所以第一个成员变量的偏移量为0),基于存储变量时地址要求对齐,所以要遵循两个条件:
- 每个成员变量的偏移量是其自身大小整数倍
- 结构体大小要是所有成员变量大小的整数倍
- 结构体中嵌套结构体时,计算sizeof要把所有的成员变量都拿出来再计算,并且同样遵循每个成员变量的偏移量是其自身大小整数倍,和上面不同的是结构体总体的大小要是成员变量中最大的变量的整数倍即可。
- 当结构体中包含数组时 规则同上展开即可,偏移量规则不是结构体整个数组大小,而是结构体中数组中单个元素大小的整数倍,整个结构体大小遵循结构体中单个元素的最大大小,数组整体大小不参与比较,这里同嵌套结构体了。
- 算结构体大小与结构体中成员排列的顺序有关系,这里引入一个概念偏移量(结构体中成员地址与结构体地址的偏移量,结构体中第一个成员变量地址就是结构体地址,所以第一个成员变量的偏移量为0),基于存储变量时地址要求对齐,所以要遵循两个条件:
- 回归正题数组名的含义
int a[3];
- 先给出答案a的类型是int[3],是一个包含三个int的数组类型,但大多数时候编译器都会把数组名隐式转换成一个指向数组首元素的指针来处理,只有在以下两种情况下以int[3]类型处理:
- 第一种情况直接对应问题背景,sizeof函数处理数组名获得的类型就是int[3]所以输出就是12B,解答了背景的疑问。
- 第二种情况则为&a 的含义为整个数组的地址,其在数值上等于数组中第一个元素的地址,这里和结构体也类同,结构体的地址在数值上也等于结构体中第一个元素的地址,但含义却是大不相同了。
- 讨论隐式转为指向数组首元素指针的情况
- 最直接就是a的数值等于&a[0],但是和普通指针不同的是,a不可以被再次赋值,也就是说数组的地址一经确立就不可改变了,可以看成 const int* 类别,关于常量指针与指针常量,可以这样区分:
const int *p 是常量指针,我们把*号和p归结到一块,意思就是*p是一个常量,即p指向的值不能改变。
int * const p 是指针常量,这里const 修饰的p ,即p是常量,p本身不可以改变
- 最直接就是a的数值等于&a[0],但是和普通指针不同的是,a不可以被再次赋值,也就是说数组的地址一经确立就不可改变了,可以看成 const int* 类别,关于常量指针与指针常量,可以这样区分:
- 先给出答案a的类型是int[3],是一个包含三个int的数组类型,但大多数时候编译器都会把数组名隐式转换成一个指向数组首元素的指针来处理,只有在以下两种情况下以int[3]类型处理: