(原)C/C++字节对齐漫谈
一.为什么要进行字节对齐?
如果在数据存放时不进行字节对齐,会在存取效率上带来损失,比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。
二.字节对齐对程序的影响:
1 #include <unistd.h> 2 #include <stdio.h> 3 4 struct A 5 { 6 int a; 7 char b; 8 short c; 9 }; 10 11 struct B 12 { 13 char b; 14 int a; 15 short c; 16 }; 17 18 #pragma pack (2) /*指定按2字节对齐*/ 19 struct C 20 { 21 char b; 22 int a; 23 short c; 24 }; 25 26 #pragma pack (1) /*指定按1字节对齐*/ 27 struct D 28 { 29 char b; 30 int a; 31 short c; 32 }; 33 34 int main() 35 { 36 printf("sizeof(A)=%d\n", sizeof(struct A)); 37 printf("sizeof(B)=%d\n", sizeof(struct B)); 38 printf("sizeof(C)=%d\n", sizeof(struct C)); 39 printf("sizeof(D)=%d\n", sizeof(struct D)); 40 41 return 0; 42 }
运行结果:

三.编译器是按照什么样的原则进行对齐的?
先让我们看四个重要的基本概念:
1.数据类型自身的对齐值:
对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。
2.结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
3.指定对齐值:#pragma pack (value)时的指定对齐值value。
4.数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。
如下面程序:
1 #include <unistd.h> 2 #include <stdio.h> 3 4 struct S0{ }; 5 struct S1 6 { 7 char a; 8 long b; 9 }; 10 11 struct S2 12 { 13 long b; 14 char a; 15 }; 16 17 struct S3 18 { 19 char c; 20 struct S1 d;//结构体 21 long e; 22 23 }; 24 25 26 struct S5 27 { 28 char a; 29 long b; 30 char name[5]; //数组 31 32 }; 33 34 //含有一个数组 35 struct S6 36 { 37 char a; 38 long b; 39 int name[5]; //数组 40 }; 41 42 struct student0 43 { 44 char name[5]; 45 int num; 46 short score; 47 }; 48 49 struct student1 50 { 51 int num; 52 char name[5]; 53 short score; 54 }; 55 56 struct student2 57 { 58 int num; 59 short score; 60 char name[5]; 61 }; 62 63 union union1 64 { 65 long a; 66 double b; 67 char name[9]; 68 }; 69 70 union union2 71 { 72 char a; 73 int b[5]; 74 double c; 75 int d[3]; 76 }; 77 78 int main(int argc, char* argv[]) 79 { 80 printf("sizeof(char) = %d\n", sizeof(char)); 81 printf("sizeof(short) = %d\n", sizeof(short)); 82 printf("sizeof(int) = %d\n", sizeof(int)); 83 printf("sizeof(long) = %d\n", sizeof(long)); 84 printf("sizeof(long long) = %d\n\n", sizeof(long long)); 85 86 printf("sizeof(S0) = %d\n", sizeof(struct S0)); 87 printf("sizeof(S1) = %d\n", sizeof(struct S1)); 88 printf("sizeof(S2) = %d\n", sizeof(struct S2)); 89 printf("sizeof(S3) = %d\n", sizeof(struct S3)); 90 printf("sizeof(S5) = %d\n", sizeof(struct S5)); 91 printf("sizeof(S6) = %d\n\n", sizeof(struct S6)); 92 93 printf("sizeof(student0) = %d\n", sizeof(struct student0)); 94 printf("sizeof(student1) = %d\n", sizeof(struct student1)); 95 printf("sizeof(student2) = %d\n\n", sizeof(struct student2)); 96 97 printf("sizeof(union1) = %d\n", sizeof(union union1)); 98 printf("sizeof(union2) = %d\n", sizeof(union union2)); 99 100 return 0; 101 }
运行结果:


浙公网安备 33010602011771号