结构心中时满时不满,心中装人心更大,究竟海王或专一,详解干货把理讲。
除了C语言的基础数据类型以外,还允许用户创建自定义类型,而对于最常用的自定义类型:结构体 的大小计算自然就非常重要了。
结构体
结构体是一些值的集合,这些值被称为成员变量。
//例如描述一个学生:
struct Student{
char name[20];
int age;
char sex[5];
char id[20];
};
匿名结构体
在声明结构体的时候,可以省略结构体标签。
struct{
int a;
char b;
float c;
};
结构体大小计算
结构体大小的计算并非是简单的将成员变量的大小相加而得到,而是需要通过对齐数来计算。
struct S1{
int a;
char c;
};
struct S2{
char c1;
int a;
char c2;
};
struct S3{
char c1;
int a;
char c2;
char c3;
};
printf("%d,%d,%d\n",sizeof(S1), sizeof(S2), sizeof(S3));
//结构体的类型大小是如何计算的? 8 12 12
为什么上面3个是 8 12 12?
结构体的内存对齐:
1.结构体的第一个成员永远在0偏移量处进行存放。
2.从第二个成员开始,以后的每个成员都要对齐到某个对齐数的整数倍处。(这个对齐数是编译器默认对齐数与成员自身大小的较小值)VS默认对齐数为8。 gcc没有默认对齐数,这样默认对齐数就是成员本身。
3.成员全部存放后,结构体总大小必须是成员中最大对齐数的整数倍。如果不够则浪费空间对齐。
4.如果有结构体嵌套,嵌套的结构体成员要对齐到自身成员的最大对齐数的整数倍处。整个结构体的大小必须是最大对齐数(包含嵌套结构体内的成员)的整数倍。
对于结构体S1 a放在0-3偏移量处 c放在4偏移量处 此时占5个字节 但最终字节数应该是最大对齐数(a 也就是int 对齐数为4)的整数倍 所以为8。
对于结构体S2 c1放在0处 a在4-7处 c2在8处 字节为9 最大对齐数4整数倍为12。
对于结构体S3 c1放在0 a放在4-7 c2放在8 c3放在9 字节为10 最大对齐数4整数倍为12。