在没有#pragma pack(n)宏的情况下,字节对齐应遵循以下三个基本原则:
1、数据成员对齐规则:结构体(struct)或联合体(union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始。
2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。
3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍(若求结构体B的大小,B中包含结构体A,A中最大成员字节数为8,则B的大小必为8的整数倍)。
#include <iostream>
using namespace std;
//#pragma pack(1) //结果:sizeof(A) = 21, sizeof(B) = 37(1字节对齐,其实就是没有对齐规则)
//#pragma pack(2) //结果:sizeof(A) = 22, sizeof(B) = 38
//#pragma pack(4) //结果:sizeof(A) = 24, sizeof(B) = 44
//#pragma pack(8) //结果:sizeof(A) = 32, sizeof(B) = 56(VS编译器默认n是8)
typedef struct a
{
int id; //[0]....[3],补齐[4]...[7]
double weight; //[8].....[15](原则1)
float height; //[16]..[19]
char gender; //[20],补齐[21]...[23]
int IQ; //[24]...[27],总长要为8的整数倍,所以要补齐[28]...[31](原则3)
}A;
typedef struct b
{
char name[2]; //[0],[1],补齐[2][3]
int id; //[4]...[7](原则1)
double score; //[8]....[15]
short grade; //[16],[17],补齐[18]...[23]
A a; //[24]......[55](原则2)
}B;
int main()
{
cout << sizeof(A) << endl;//结果:32
cout << sizeof(B) << endl;//结果:56(注意:B的大小不是A结构体大小的倍数)
return 0;
}
另外,联合体的大小和结构体的不大一样,联合体的size是所包含的所有类型的基本长度的最小公倍数。
union DATA
{
int a[5];
double b;
char c;
}D;
cout << sizeof(D) << endl;//结果:24