结构体中如何计算结构体大小呢?那么首先应该理解并掌握结构体的对齐规则,为什么数组中不需要对齐有人会问,这是因为数组中放入的是同类型的数据,比如字符串数组,字符数组,指针数组,数值数组等。而结构体中存放的是不同类型的数据,比如结构体成员列表可为数组,指针,整型,字符型,浮点型等组合。总体来说结构体的内存对齐是拿空间来换取时间的做法,那么在设置结构体时,我们既要满足对齐,又要节省空间如何做到呢?只能让占用空间小的成员尽量集中在一起。那么结构体在对齐方式不合理时我们可以修改默认对齐数。
一.结构体对齐规则:
1.第一个成员在与结构体变量偏移量为0的地址处 。 (第一个成员也有对齐数)
2.其他成员变量要对齐到对齐数的整数倍的地址处。
(对齐指存放该变量时的起始偏移量必须能整除该变量的对齐数,通常是能整除对齐数的最小整数)
对齐数 =编译器默认的一个对齐数与该成员大小的较小值。
(VS中默认为8,Linux中的默认值为4,默认参数只能设置成1,2,4,8,16)
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体 的整体大小就是所有最大对齐数(含有嵌套结构体的对齐数)的整数倍。
(一个结构体的对齐数是结构体中最大的对齐数)
二. 修改默认对齐数
#pragma 这是个预处理指令,可以修改默认对齐数
# include <stdio.h>
# include <stdlib.h>
//# pragma pack(1)
//# pragma pack(2) //设置默认对齐数为2
//# pragma pack(4)
//# pragma pack(8)
//# pragma pack(16)
struct s1 //结构体
{
char c1;
int i;
char c2;
};
struct s2
{
char c1;
char c2;
int i;
};
struct s3
{
double c1;
char c2;
int i;
};
//#pragma pack() //取消设置的默认对齐数,还原为默认设置
struct s4
{
char c1;
struct s3 s3;
double d;
};
struct s5
{
struct s4 s4;
int e;
char f[5];
char* h;
void(*g)(int); //空类型指针函数
};
int main ()
{
printf ("s1=%d\n",sizeof(struct s1)); //输出结构体大小
printf ("s2=%d\n",sizeof(struct s2));
printf ("s3=%d\n",sizeof(struct s3));
printf ("s4=%d\n",sizeof(struct s4));
printf ("s5%d\n",sizeof(struct s5));
system ("pause");
return 0;
}
1.VS默认对齐数运行结果
2.修改默认对齐数为1运行结果
3.修改默认对齐数为2的运行结果
4.修改默认对齐数为4的运行结果
5.修改默认对齐数为4的运行结果,在s4上面还原默认对齐数
6.修改默认对齐数为8或16的运行结果 (与VS默认对齐数运行结果一样)