结构体的定义
不同类型的结合称为 结构体,相当于数组。但数组中的每个元素都是同一个类型,但结构体中的成员可以是不同类型。
同类型的两个结构体变量可以直接赋值,相当于 浅拷贝 memcpy()
1 | struct 结构的类型名称 |
结构体的定义只是类型的定义,不占内存的空间。
只有在描述具体的结构体实体时,才会占用内存。
结构体的内存占用是线性的,但可能不是连续的。
结构体的偏移地址 Offset
结构体的 . 运算访问结构体成员变量,相当于对结构体进行偏移地址的计算
结构体的首个成员的偏移地址 offset 为0
在 VC6 中 Struct member alignment 中设置 对齐地址,默认为 8byte
如果编译器为 VS2013 则在 属性类容-C/C++-代码生成-结构体成员对齐 中设置
计算偏移地址
计算公式
设编译选项设定的对齐值为 Zp(默认8byte),每个结构体成员的偏移量为 Offset
必须满足 (上一个成员的offset + 上一个成员的size) % min(sizeof(member type),Zp) == 0
如果为嵌套结构体,结构体名为 StruAli1 则Offset % min(StruAli1 ,Zp) == 0
结构体StruAli1 的对齐值为 *max(sizeof(member1 type),sizeof(member2 type)…sizeof(memberNtype)) *
member1,member2,member3 为 StruAli1 的成员
如果 offset + size 不满足 取模运算 == 0
则 offset + size +1 直到可以 == 0
计算过程
- 定义结构体
设置对齐地址为 4
1 | struct Person |
- 计算偏移量
计算首个成员 szName 的偏移量为 0 ,大小为 6
计算成员 nAge 的偏移量: ( 0(szName的偏移量) + 6(szName的大小)) % min(sizeof(nAge) , 4(对齐地址)) == 6 % min(4, 4)
6 % 4 ! = 0,则6 + 1 % 4
7 % 4 != 0,则7 + 1 % 4 == 0
所以成员 nAge 的偏移量为 8
计算成员 fHeight 的 偏移量:( 8(nAge的偏移量) + 4(nAge的大小)) % min (sizeof(float) , 4) == 12 % min(4, 4)
12 % 4 == 0
所以成员 fHeight 的偏移量为 12
计算 dblWeight 的偏移量:(12+4) % min(8, 4) == 16 % 4 == 0
成员 dblWeight 的偏移量为 16
计算 cGender 的偏移量:(16+8) % min(1, 8) == 24 % 1 == 0
成员 cGender 的偏移量为 24
成员 | 偏移量 offset | 大小 size |
---|---|---|
szName[6] | 0 | 6 |
nAge | 8 | 4 |
fHeight | 12 | 4 |
dblWeight | 16 | 8 |
cGender | 24 | 1 |
计算结构体的大小sizeof(struct)
计算公式
设 Zp 为设定的对齐值为 4
MaxValue= max(sizeof(member1 type),sizeof(member2 type)……sizeof(member3 type))
MinValue = min(MaxValue,Zp)
Size % MinValue == 0
Size 为结构体最后一个成员的偏移量 + 最后一个成员的大小
如果 Size % MinValue != 0 则Size ++
最终的 Size 为结构体的大小
计算过程
例如 Person 结构体
MaxValue = max(sizeof(szName), sizeof(nAge), sizeof(fHeight), sizeof(dblWeight), sizeof(cGender)) == sizeof(dblWeight) == 8
MinValue = min(8,4) == 4
Size % MinValue == (24 + 1) % 4 != 0
Size ++
(25 + 1) % 4 != 0
Size ++
(26+ 1) % 4 != 0
Size ++
(27+ 1) % 4 == 0
所以在对齐值为 4 时,Person 的大小为 28