a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C > 正文

實例講解C語言編程中的結構體對齊

2020-01-26 14:38:36
字體:
來源:轉載
供稿:網友

Q:關于結構體的對齊,到底遵循什么原則?
A:首先先不討論結構體按多少字節對齊,先看看只以1字節對齊的情況:

#include <stdio.h>#include <string.h>#define PRINT_D(intValue)   printf(#intValue" is %d/n", (intValue));#define OFFSET(struct,member) ((char *)&((struct *)0)->member - (char *)0)#pragma pack(1)typedef struct{  char  sex;  short  score;  int   age;}student;int main(){  PRINT_D(sizeof(student))  PRINT_D(OFFSET(student,sex))  PRINT_D(OFFSET(student,score))  PRINT_D(OFFSET(student,age))  return 0;}

輸出:

sizeof(student) is 7OFFSET(student,sex) is 0OFFSET(student,score) is 1OFFSET(student,age) is 3

可以看到,如果按1字節對齊,那么結構體內部的成員緊密排列,sizeof(char) == 1, sizeof(short) == 2, sizeof(int) == 4.

修改上面的代碼, 去掉#pragma pack語句,代碼如下:

#include <stdio.h>#include <string.h>#define PRINT_D(intValue)   printf(#intValue" is %d/n", (intValue));#define OFFSET(struct,member) ((char *)&((struct *)0)->member - (char *)0)typedef struct{  char  sex;  short  score;  int   age;}student;int main(){  PRINT_D(sizeof(student))  PRINT_D(OFFSET(student,sex))  PRINT_D(OFFSET(student,score))  PRINT_D(OFFSET(student,age))  return 0;}

運行結果:

sizeof(student) is 8OFFSET(student,sex) is 0OFFSET(student,score) is 2OFFSET(student,age) is 4

此時,各個成員之間就不像之前那樣緊密排列了,而是有一些縫隙。這里需要介紹下對齊原則:

此原則是在沒有#pragma pack語句作用時的原則(不同平臺可能會有不同):

原則A:struct或者union的成員,第一個成員在偏移0的位置,之后的每個成員的起始位置必須是當前成員大小的整數倍;

原則B:如果結構體A含有結構體成員B,那么B的起始位置必須是B中最大元素大小整數倍地址;

原則C:結構體的總大小,必須是內部最大成員的整數倍;

依據上面3個原則,我們來具體分析下: sex在偏移0處,占1字節;score是short類型,占2字節,score必須以2的整數倍為起始位置,所以它的起始位置為2; age為int類型,大小為4字節,它必須以4的整數倍為起始位置,因為前面有sex占1字節,填充的1字節和score占2字節,地址4已經是4的整數倍,所以age的位置為4.最后,總大小為4的倍數,不用繼續填充。

繼續修改上面的代碼,增加#pragma pack語句:

#include <stdio.h>#include <string.h>#define PRINT_D(intValue)   printf(#intValue" is %d/n", (intValue));#define OFFSET(struct, member) ((char *)&((struct *)0)->member - (char *)0)#pragma pack(4)typedef struct{  char  sex;  short  score;  int   age;}student;int main(){  PRINT_D(sizeof(student))  PRINT_D(OFFSET(student,sex))  PRINT_D(OFFSET(student,score))  PRINT_D(OFFSET(student,age))  return 0;}

運行結果:

sizeof(student) is 8OFFSET(student,sex) is 0OFFSET(student,score) is 2OFFSET(student,age) is 4

具體分析下:

有了#pragma pack(4)語句后,之前說的原則A和C就不適用了。實際對齊原則是自身對齊值(成員sizeof大小)和指定對齊值(#pragma pack指定的對齊大小)的較小者。依次原則,sex依然偏移為0, 自身對齊值為1,指定對齊值為4,所以實際對齊為1; score成員自身對齊值為2,指定對齊值為4,實際對齊為2;所以前面的sex后面將填充一個1字節,然后是score的位置,它的偏移為2;age自身對齊值為4,指定對齊為4,所以實際對齊值為4;前面的sex和score正好占用4字節,所以age接著存放;它的偏移為4.

Q:關于位域的問題,空域到底表示什么?
A:它表示之后的位域從新空間開始。

#include <stdio.h>#include <string.h>#define PRINT_D(intValue)   printf(#intValue" is %d/n", (intValue));#define OFFSET(struct, member) ((char *)&((struct *)0)->member - (char *)0)typedef struct {  int a : 1;  int b : 3;  int : 0;  int d : 2;}bit_info;int main(){  PRINT_D(sizeof(bit_info))  return 0;}

運行結果:

sizeof(bit_info) is 8

bit_info中的a, b占用4個字節的前4位,到int:0; 時表示此時將填充余下所有沒有填充的位,即剛剛的4個字節的余下28位;int d:2; 將從第四個字節開始填充,又會占用4個字節,所以總大小為8.

再來看下面幾個小例子
例1:

struct A{         char f1 : 3;         char f2 : 4;         char f3 : 5;     };

                    a      b          c
A的內存布局:111,1111 *,11111 * * *
位域類型為char,第1個字節僅能容納下f1和f2,所以f2被壓縮到第1個字節中,而f3只能從下一個字節開始。因此sizeof(A)的結果為2。
例2:

struct B{         char f1 : 3;         short f2 : 4;         char f3 : 5;     };

由于相鄰位域類型不同,在VC6中其sizeof為6,在Dev-C++中為2。
例3:

struct C{         char f1 : 3;         char f2;         char f3 : 5;     };

非位域字段穿插在其中,不會產生壓縮,在VC6和Dev-C++中得到的大小均為3。
考慮一個問題,為什么要設計內存對齊的處理方式呢?如果體系結構是不對齊的,成員將會一個挨一個存儲,顯然對齊更浪費了空間。那么為什么要使用對齊呢?體系結構的對齊和不對齊,是在時間和空間上的一個權衡。對齊節省了時間。假設一個體系結構的字長為w,那么它同時就假設了在這種體系結構上對寬度為w的數據的處理最頻繁也是最重要的。它的設計也是從優先提高對w位數據操作的效率來考慮的。有興趣的可以google一下,人家就可以跟你解釋的,一大堆的道理。
最后順便提一點,在設計結構體的時候,一般會尊照一個習慣,就是把占用空間小的類型排在前面,占用空間大的類型排在后面,這樣可以相對節約一些對齊空間。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 色一情 | 激情国产 | 欧美freesex交免费视频 | 99爱视频| 日本污视频在线观看 | 久久精精品 | 欧州一区二区三区 | 日韩精品四区 | 99精品久久久久 | 国产精品第一国产精品 | 啪一啪av| 999国产在线视频 | 欧美成人免费 | 91精品中文字幕一区二区三区 | 精品无码久久久久久国产 | 男女网站视频 | 久久亚洲国产视频 | 色婷婷小说| 久久成人免费视频 | 一区二区三区亚洲视频 | 久久之久久 | 男女羞羞视频网站 | 久久久久久亚洲精品 | 亚洲电影一区 | 香蕉一区 | 国产不卡区| 国产成人一区二区三区 | 国产一区久久久 | 青娱乐久久| 91av国产在线视频 | 日本亚洲国产一区二区三区 | 97精品国产 | 国产精品国产三级国产aⅴ无密码 | 欧美日韩视频 | 国产福利电影在线观看 | 中文字幕精品三级久久久 | 亚洲精品影院 | 欧美中文在线 | 在线播放国产一区二区三区 | 亚洲va中文字幕 | 四虎国产成人永久精品免费 |