掌握字节对齐有两个要点:
1.32位 与64位 环境下各数据类型的长度:
2.字节对齐基本原则:
(1).结构体的大小为其中最长的数据类型的整数倍。
(2).指定对齐值:#pragma pack(value) //以value为最大值对齐
(3).当有pack指定对齐值时,对齐值为自身对齐值与pack指定值中小的那个.
下面是字节对齐的各种情况:
32位:
1.情况1:
typedef struct
{
char c1;
short s;
char c2;
int i;
}t1;
sizeof(t1) = [1(char)+2(short)+1]+[1(char)+3]+[4(int)] = 12;
2.情况2:
typedef struct
{
char a;
int b;
char c[10];
}te2;
sizeof(t2) = [1(char)+3]+4(int)+[10(char [10])+2] = 20;
3.情况3:
位域:
typedef struct bs
{
int a:8;
int b:2;
int c:6;
}data;
data为bs型变量,共占2个字节,其中a占8位共1个字节,b占2位,c占6位,共2+6=8 一个字节,加起来共两个字节.
其对齐规则大致为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++和GCC采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍,而位域则按照其最宽类型字节数对齐。
3.1
typedef struct t3
{
char a:1;
char b:4;
char c:5;
};
sizeof(t3) =[1(1+4)]+[1(5)] = 2;
3.2
typedef struct t4
{
char a:1;
short b:5;
char c:7;
};
sizeof(t4) = [1(char)+1]+[2(short)]+[1(char)+1] = 6;//vs,vc编译器
sizeof(t4) = [1]+[1] = 2; //gcc编译器
3.3
typedef struct t5
{
char a:1;
char b;
char c:1;
};
sizeof(t5) = [1]+[1]+[1] = 3;
3.4
typedef struct t6
{
int a:1;
int b:5;
int c:29;
int d:4;
char e:1;
char f;
};
sizeof(t6) = [4(1+5)]+[4(29)]+[4(4)]+[1(e)+1(f)+2] = 16;