(原)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 } 

运行结果:

      

 

posted @ 2016-07-25 23:44  来者可追  阅读(185)  评论(0)    收藏  举报