结构体大小的计算
规则(内存对齐)
-
第一个成员在与结构体变量偏移量位0的地址处。
-
其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认对齐数 与 该成员(对比的) 较小值。
(编者的编译器中默认的值为8) -
总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
-
如果嵌套,嵌套的结构体对齐到自己的最大对齐数的整数倍处
-
结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
以下用于举例,图片便于理解
#include <stdio.h>
struct s1
{
char a; // 对齐数 1
int b; // 4
char c;// 1
}sss;//整体最大对齐数为4
int main()
{
printf("%d", sizeof(sss)); //结果为12
return 0;
}
编者将模拟的表格放在下面
int main()
{
struct S2
{
char c1;
char c2;
int i;
};
printf("%d\n", sizeof(struct S2)); //8
struct S3
{
double d; //8
char c;
int i;
};
printf("%d\n", sizeof(struct S3)); //16
struct S4
{
char c1;
struct S3 s3; //对齐数为8(取较小值) 偏移量为16(大小)
double d; //8
};
printf("%d\n", sizeof(struct S4));//32
return 0;
}
S4的对齐图解
掌握以上规则就可以推算结构体的大小
其目的是为了节约时间
所以,合理的设计结构体成员变量来满足对齐规则
可以既节省空间又节省时间
也可以通过
#pragma 来修改默认对齐数
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{
//结果改变
printf("%d\n", sizeof(struct S1)); //12
printf("%d\n", sizeof(struct S2)); //6
return 0;
}
传参
无论传值传参还是传址传参,都能调用结构体。
但由于结构体过大,为了提高性能,多用传址传参(指针)。