#include <stdio.h>
/*
结构体的大小:最后一个成员的大小加上最后一个成员的偏移量
偏移量:结构体变量中的一个成员的地址和结构体变量的地址的字节之差
由于地址对齐的要求,编译器在编译时会遵守以下两条规则:
1.结构体变量的成员的偏移量是该成员大小的整数倍
2.结构体大小必须是任何成员大小的整数倍
*/
int main(void){
struct stu1{
int i;//偏移量为0
char j;//偏移量为4
int k;//偏移量为5,但不是其整数倍,编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成8
};
printf("%d\n", sizeof(struct stu1));//12
struct stu2{
int a;
short b;//偏移量为4
};
//大小为6,但不是成员a大小的整数倍,因此编译器会在成员b后面补上2个字节,使得结构体的大小变成8
只需把其展开即可。但有一点需要注意,【展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的偏移量的整数倍!】
*/
struct stu3{
short i;
struct{
char a;//偏移量为4(被展开结构体最大成员b的整数倍),而不是2!
int b;//偏移量为6,不是其整数倍,变为8
}x;
int j;//偏移量为12
};
printf("%d\n", sizeof(struct stu3));//16
/*
结构体的大小:最后一个成员的大小加上最后一个成员的偏移量
偏移量:结构体变量中的一个成员的地址和结构体变量的地址的字节之差
由于地址对齐的要求,编译器在编译时会遵守以下两条规则:
1.结构体变量的成员的偏移量是该成员大小的整数倍
2.结构体大小必须是任何成员大小的整数倍
*/
int main(void){
struct stu1{
int i;//偏移量为0
char j;//偏移量为4
int k;//偏移量为5,但不是其整数倍,编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成8
};
printf("%d\n", sizeof(struct stu1));//12
struct stu2{
int a;
short b;//偏移量为4
};
//大小为6,但不是成员a大小的整数倍,因此编译器会在成员b后面补上2个字节,使得结构体的大小变成8
printf("%d\n", sizeof(struct stu2));//8
/*
如果结构体中的成员又是另外一种结构体类型时应该怎么计算呢?只需把其展开即可。但有一点需要注意,【展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的偏移量的整数倍!】
*/
struct stu3{
short i;
struct{
char a;//偏移量为4(被展开结构体最大成员b的整数倍),而不是2!
int b;//偏移量为6,不是其整数倍,变为8
}x;
int j;//偏移量为12
};
printf("%d\n", sizeof(struct stu3));//16
return 0;
}
/*
计算机在内存中是按照一个固定长度的方式存取数据,如32位系统下,为4个字节存取数据,即4字节对齐
C语言字节对齐模式还可以通过#pragma pack(n)设定按n字节对齐(默认为4)。
如:
#include <stdio.h>
#pragma pack(push)
#pragma pack(1)
int main(void){
struct stu1{
int i;//偏移量为0
char j;//偏移量为4
int k;//偏移量为5
};
printf("%d\n", sizeof(struct stu1));//9
return 0;
}
#pragma pack(pop)
*/
//学生初来乍到,文章若有瑕疵,还请各位看官多多指教!谢谢!