1.结构体的大小并不是简单的成员大小的相加,而是有两个规则要符合的。
规则一:结构体成员的偏移量必须是该成员的大小的整数倍(0被认为是任何数的整数倍)
穿插一点补充:记住偏移量是指当前成员前面成员所占的字节数,例如下面Test1那里,int前面已 经有char了,按道理说其偏移量是1的,但为了对齐,必须在加多3形成4与int对齐,所以1+3 = 4,int的偏移量为4,最后一个char的偏移量为4+4为8,8+1为9,那么9是不是这个结构体的大小呢,显然不是,其实是12,继续看原则二。
规则二:结构体大小必须是结构体成员大小的整数倍(数组,结构体除外)
对齐方式虽然浪费了内存空间,但是对齐方式提高了计算机对程序的访问效率
任何一个结构体的大小都要符合上述两个原则。
struct Test1{
char i; //1
int ch; //4 +3
char k; //1
};
2.接下来我们分类看一下结构体的大小的计算方式
(1)简单类
struct Test1
{
char ch; //1
int i; //4 +3
char chr;//1
};//这时结构体的大小为12
由于最后一个char的偏移量是8,但8+1 = 9并不是int大小的整数倍,
所以要继续往后移,到12时就合适了是所有成员大小的整数倍了,所以其大小为12
(2)简单类2
struct Test2
{
char che; //1
char cha; //1
int i; //4 +2
};//这时候结构体大小为8
由于int前面的偏移量为2,但2并不是int大小的整数倍,所以要加2偏移量变为4,所以4+4 = 8,
8即是1的倍数,也是4的倍数,所以这个结构体大小为8
(3)结构体含数组1
struct Test3
{ /*这时候这个结构体的大小是136,因为数组不要求偏移量是
其大小整数倍,数组大小直接加上前面的成员大小即可*/
int studentId; //4
char name[128]; //128
int scores; //4
};
这时候这个结构体的大小是136,因为数组不要求偏移量是其大小整数倍,
数组大小直接加上前面的成员大小即可,由于132是最后int的倍数,所以其大小为132+4 = 136
切记,结构体的大小不需要是数组大小的整数倍
(4)结构体数组2
struct Test4
{结构体的大小不要求是数组的整数倍,只要是其他成员大小的整数倍即可
char id; //1
int num; //4 +3
char name[10]; //10
}; 大小为20,如果是18的话,其不是int的整数倍,所以要偏移到20才行
(5)结构体里嵌套结构体
struct Test5
{
char ch; //1
int i; //4
struct s //16
{
char ae;//1
int j; //4
double h;//8
}temp;
float f; //4
};//这时结构体大小为32
其实这是按照不同编译器,其大小不一样的,
但嵌套在里面的结构体当它不存在即可,嵌套结构体里的成员按照顺序参与计算即可
(6)结构体里有联合体
struct Test6
{
char ch; //1
int i; //4
union//我们知道联合体的大小就是里面最大成员的大小,这时候联合体的大小是4
{
char cj; //1
int g; //4
};
};//这时大小为12
联合体大小计算是遵循联合体里最大的成员是多少,其联合体大小就是多少
所以8+4 = 12,这结构体大小为12
(7)指定与什么对齐1
#pragma pack(4) 这里是指定跟什么对齐的意思
切记,与什么对齐,偏移量就是什么的整数倍
struct Test7
{
char ch; //1
int j; //4
float a; //4
double d;//8
};这里如果有指定与4对齐的话,大小是20,如果没指定的话就是24
指定与什么对齐,即其偏移量跟结构体大小都要是其指定对齐数的整数倍即可
(8)指定与什么对齐2
#pragma pack(16)
/*这里有个小插曲,如果指定对齐的数比结构体里最大的成员大小小的话,就按照对齐数来对齐
相反,如果指定的对齐数比结构体里最大成员还大的话,那么就按照结构体里的对齐方式来。
*/
struct Test8
{
char ch; //1
int j; //4
float h; //4
double g;//8
};//这时候的大小为24
这里有个小插曲,如果指定对齐的数比结构体里最大的成员大小小的话,就按照对齐数来对齐
相反,如果指定的对齐数比结构体里最大成员还大的话,那么就按照结构体里的对齐方式来。
完整代码:
#include
//计算结构体大小要遵循两个原则
//结构体成员的偏移量必须是该成员的大小的整数倍(0被认为是任何数的整数倍)
/*记住偏移量是指当前成员前面的空间数,例如下面的char name前面已经有int,
因为int是占四个字节的,所以其偏移量是4*/
//结构体大小必须是(数组,结构体除外)结构体成员大小的整数倍。
//对齐的方式虽然浪费了空间,但是对齐方式提高了计算机对程序的访问效率
//任何一个结构体都要符合上面两条规则
struct Test1
{
char ch; //1
int i; //4 +3
char chr;//1
};//这时结构体的大小为12
struct Test2
{
char che; //1
char cha; //1
int i; //4 +2
};//这时候结构体大小为8
struct Test3
{ /*这时候这个结构体的大小是136,因为数组不要求偏移量是
其大小整数倍,数组大小直接加上前面的成员大小即可*/
int studentId; //4
char name[128]; //128
int scores; //4
};
struct Test4
{//结构体的大小不要求是数组的整数倍,只要是其他成员大小的整数倍即可
char id; //1
int num; //4 +3
char name[10]; //10
}; //大小为20,如果是18的话,其不是int的整数倍,所以要偏移到20才行
struct Test5
{
char ch; //1
int i; //4
struct s //16
{
char ae;//1
int j; //4
double h;//8
}temp;
float f; //4
};//这时结构体大小为32
struct Test6
{
char ch; //1
int i; //4
union//我们知道联合体的大小就是里面最大成员的大小
{
char cj; //1
int g; //4
};
};//这时大小为12
#pragma pack(4) //这里是指定跟什么对齐的意思
//切记,与什么对齐,偏移量就是什么的整数倍
struct Test7
{
char ch; //1
int j; //4
float a; //4
double d;//8
};//这里如果有指定与4对齐的话,大小是20,如果没指定的话就是24
#pragma pack(16)
/*这里有个小插曲,如果指定对齐的数比结构体里最大的成员大小小的话,就按照对齐数来对齐
相反,如果指定的对齐数比结构体里最大成员还大的话,那么就按照结构体里的对齐方式来。
*/
struct Test8
{
char ch; //1
int j; //4
float h; //4
double g;//8
};//这时候的大小为24
//ctrl s+d是复制当行内容到下一行
int main()
{
//计算结构体的大小的方式
printf("the size of int:%d\n",sizeof(int));
printf("the size of char:%d\n",sizeof(char));
printf("the size of float:%d\n",sizeof(float));
printf("the size of double:%d\n",sizeof(double));
printf("\n");
printf("the size of Test1 :%d\n",sizeof(struct Test1));
printf("the size of Test2 :%d\n",sizeof(struct Test2));
printf("the size of Test3 :%d\n",sizeof(struct Test3));
printf("the size of Test4 :%d\n",sizeof(struct Test4));
printf("the size of Test5 :%d\n",sizeof(struct Test5));
printf("the size of Test6 :%d\n",sizeof(struct Test6));
printf("the size of Test7 :%d\n",sizeof(struct Test7));
printf("the size of Test8 :%d\n",sizeof(struct Test8));
return 0;
}
结果:
the size of int:4
the size of char:1
the size of float:4
the size of double:8
the size of Test1 :12
the size of Test2 :8
the size of Test3 :136
the size of Test4 :20
the size of Test5 :32
the size of Test6 :12
the size of Test7 :20
the size of Test8 :24
以上内容很重要,耐心观看。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)