在构建结构体时,如果其中存在多种类型时,就需要注意成员变量定义的顺序以及大小。因为不同类型变量顺序不同时,可能会造成整个结构体的大小不同。下面举例进行说明:
struct sbita { struct sbitb {
short a; char a[2];
char b; char b;
}c1; }c2;
c1,c2的size分别为多少呢?答案是:sizeof(c1)--4byte, sizeof(c2)--3byte.
大家可以考虑一下为什么二者的size会不同。下面我们在写个小程序来验证一下。
#include <stdio.h>
struct sbit1 {
short a;
int c;
char d;
}e1;
struct sbit2 {
char b;
short a;
int c;
char d;
}e2;
struct sbit3 {
short a;
char b;
char d;
int c;
}e3;
int main()
{
printf("size: [%d],[%d],[%d]/n", sizeof(e1),sizeof(e2),sizeof(e3));
return 0;
}
执行结果如下:
size: [12],[12],[8]
可以看出,e1比e2少了变量b,但是二者size相同;e2与e3的变量个数及类型都相同,只是顺序不同,结果造成二者的size不同。我们把上面三个结构体的存储结构示意图画出来以便理解。
0 7 15 23 31
|-----|-----|-----|-----|
| a |-----|-----|
|-----|-----|-----|-----|
| c |
|-----|-----|-----|-----|
| d |-----|-----|
|-----|-----|-----|-----|
以上是e1的存储结构:总size为12byte,有效size为7byte。
0 7 15 23 31
|-----|-----|-----|-----|
| b | a |-----|
|-----|-----|-----|-----|
| c |
|-----|-----|-----|-----|
| d |-----|-----|-----|
|-----|-----|-----|-----|
以上是e2的存储结构:总size为12byte,有效size为8byte。
0 7 15 23 31
|-----|-----|-----|-----|
| a | b | d |
|-----|-----|-----|-----|
| c |
|-----|-----|-----|-----|
以上是e3的存储结构:总size为8byte,有效size为8byte。
由上面的例子可以看出成员变量位置以及类型的不同,会造成结构体的实际size不同。
我们来总结一下规律:
①:每个结构体的size总是其成员变量类型中最大size的整数倍。
②:成员变量与上一个变量之间不一定是紧连的,即二者之间有可能会存在空闲的无效空间。
根据上面的存储示意图可以看出,只有按照合理地顺序以及类型定义成员变量,才有可能达到最优化,不浪费空间,也避免因为隐式地分配的空间造成不可预知的错误。