欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報激活碼778899分享:C語言----字節(jié)對齊

柚子快報激活碼778899分享:C語言----字節(jié)對齊

http://yzkb.51969.com/

一:字節(jié)對齊的概念

? ? ? ? 針對字節(jié)對齊,百度百科的解釋如下:

????????字節(jié)對齊是字節(jié)按照一定規(guī)則在空間上排列,字節(jié)(Byte)是計算機信息技術(shù)用于計量存儲容量和傳輸容量的一種計量單位,一個字節(jié)等于8位二進制數(shù),在UTF-8編碼中,一個英文字符等于一個字節(jié),字節(jié)按照一定規(guī)則在空間上排列就是字節(jié)對齊。

? ? ? ? 上面就提到按照一定規(guī)則,那規(guī)則是什么,按什么規(guī)則去對齊,帶著這個疑問往下走

二:為什么要字節(jié)對齊

? ? ? ? 我們?yōu)槭裁匆M行字節(jié)對齊,不對齊會有什么后果,在計算機中我們?nèi)魏我粋€動作無非就是保證程序的正確性,提高程序的性能和可靠性。

? ? ? ? 1,平臺的硬要求,必須要字節(jié)對齊

????????某些平臺對特定類型的數(shù)據(jù)只能從特定地址開始存取,而不允許其在內(nèi)存中任意存放。例如,Motorola 68000 處理器不允許16位的字存放在奇地址,否則會觸發(fā)異常,因此在這種架構(gòu)下編程必須保證字節(jié)對齊。

? ? ? ? 2,提高程序的性能

? ? ? ? 字節(jié)對齊如何能提高程序的性能?CPU內(nèi)部有幾個重要的部件決定了CPU一次能處理的字節(jié)和可訪問的內(nèi)存大小。寄存器,ALU和數(shù)據(jù)總線的位數(shù),這些共同決定了CPU的字長,常見CPU的字長有4位,8位,16位,32位和64位。字長越多,則CPU內(nèi)部硬件規(guī)模和造價越高。如果CPU字長是16位。它的寄存器和總線也是16位。那么它一次處理的數(shù)據(jù)長度就為2字節(jié)。

? ? ? ? 當(dāng)訪問一個變量時,當(dāng)該變量的地址為偶地址(即字變量的低字節(jié)在偶地址單元,高字節(jié)在奇地址單元),則需要一個總線周期訪問該字變量;如果該字變量的地址為奇地址(即字變量的低字節(jié)在奇地址單元,高字節(jié)在偶地址單元),則需要用兩個連續(xù)的總線周期才能訪問該字變量,每個周期訪問一個字節(jié)。

? ? ? ? 字節(jié)對齊讓CPU讀取數(shù)據(jù)的效果高了,這就解釋了為什么字節(jié)對齊能提高程序的性能。

? ? ? ? 3,節(jié)省程序的內(nèi)存

? ? ? ? 下面我們以一個實際的例子來看看字節(jié)對齊如何節(jié)省內(nèi)存

#include

#include

struct byte1

{

char a;

int b;

short c;

};

struct byte2

{

char a;

short c;

int b;

};

int main()

{

// please write your code here

printf("struct byte1 size:%d\n",sizeof(struct byte1));

printf("struct byte2 size:%d\n",sizeof(struct byte2));

}

?可以看到,同樣是存儲一個char,一個int,一個short,結(jié)構(gòu)體中順序不一樣,結(jié)構(gòu)體的所占的空間也不一樣。之所以出現(xiàn)上述結(jié)果,就是因為編譯器要對數(shù)據(jù)成員在空間上進行對齊

三:字節(jié)對齊規(guī)則

1,基本類型對齊規(guī)則

基本類型包括char、int、float、double、short、long等基本數(shù)據(jù)類型。CPU位數(shù)不同所占的字節(jié)數(shù)也不一樣,如下圖所示

?????????對齊要求:起始地址為其長度的整數(shù)倍即可。如,int類型的變量起始地址要求為4的整數(shù)倍,char類型的變量只占一個字節(jié),那起始地址放哪都行。

2,結(jié)構(gòu)體對齊規(guī)則

1>每個數(shù)據(jù)成員的起始位置必須是自身大小的整數(shù)倍;?

2>結(jié)構(gòu)體總大小必須是結(jié)構(gòu)體成員中最大的對齊模數(shù)的整數(shù)倍;

3>?結(jié)構(gòu)體包含數(shù)組時,按單個類型對齊方式;

4>共用體union取成員的最大內(nèi)存,但包含在結(jié)構(gòu)體內(nèi)時,按union內(nèi)部最大類型字節(jié)數(shù)的整數(shù)倍開始存儲;

struct byte1

{

char a;

int b;

short c;

};

結(jié)構(gòu)體大?。?2 解釋:char占一個字節(jié),int占四個字節(jié),由于int的起始地址要在4的倍數(shù)上,char后邊補齊3個字節(jié),shor占兩個字節(jié),但是整個結(jié)構(gòu)體大小要是最大的對齊模數(shù)的整數(shù)倍,即4的倍數(shù),所以補兩個字節(jié),一共12個字節(jié)

struct byte2

{

char a;

short c;

int b;

};

結(jié)構(gòu)體大?。?

解釋:char占一個字節(jié),short占兩個字節(jié),由于short的起始地址要在2的倍數(shù)上,char后邊補齊1個字節(jié),int占四個字節(jié),剛好在4的倍數(shù)上,所以總共8個字節(jié)

那結(jié)構(gòu)體里嵌套結(jié)構(gòu)體呢?

結(jié)構(gòu)體包含另一個結(jié)構(gòu)體成員,則被包含的結(jié)構(gòu)體成員要從其原始結(jié)構(gòu)體內(nèi)部的最大對齊模數(shù)的整數(shù)倍地址開始存儲(比如struct a里含有struct b,b中有char、double 、int?元素,那么b應(yīng)該從8(double)的整數(shù)倍開始存儲)

結(jié)構(gòu)體嵌套共同體

結(jié)構(gòu)體包含共用體成員,則該共用體成員要從其原始共用體內(nèi)部成員中的最大對齊模數(shù)的整數(shù)倍地址開始存儲

結(jié)構(gòu)體最后包含0數(shù)組

struct byte2

{

char a;

short c;

int b;

double d[0];

};

結(jié)構(gòu)體最后包含0數(shù)組,那0數(shù)組占空間嗎?長度為0的數(shù)組的主要用途是為了滿足需要可變長度的結(jié)構(gòu)體,具體用法是在一個結(jié)構(gòu)體的最后,申明一個長度為0的數(shù)組,就可以使得這個結(jié)構(gòu)體是可變長的。對于編譯器來說,此時長度為0的數(shù)組并不占用空間,因為數(shù)組名本身不占空間,它只是一個偏移量,數(shù)組名這個符號本身代表了一個不可修改的地址常量。

3,共同體對齊規(guī)則

共同體的內(nèi)存除了取最大成員內(nèi)存外,還要保證是所有成員類型size的最小公倍數(shù)。

union byte3

{

char a;

short c[5];

int b;

};

?共同體byte3中最大成員就是short c[5],占10個字節(jié),由于要保證是所有成員類型size的最小公倍數(shù),即4個倍數(shù),所以是12

4,存在#pragma pack宏的對齊規(guī)則

#pragma pack(n)//編譯器將按照n個字節(jié)對齊

#pragma pack()//取消自定義字節(jié)對齊方式

******對齊規(guī)則******

結(jié)構(gòu)體、聯(lián)合、類的結(jié)構(gòu)成員,第一個放在偏移為0的地方,以后每個數(shù)據(jù)成員的對齊,按照#pragma pack指定的數(shù)值和自身對齊模數(shù)中最小的那個。

結(jié)構(gòu)體的大小是#pragma pack指定的數(shù)值的整數(shù)倍。

#pragma pack(4)

typedef struct

{

int age;

char name[0];

double a;

} Person;

#pragma pack();//結(jié)束#pragma pack(4)對齊。 如果沒有結(jié)束,aa也按照#pragma pack(4)對齊

typedef struct

{

double age;

Person k;

} aa;

int m=sizeof(Person); // m=12, 按照4字節(jié)對齊

int n=sizeof(aa); // n=24, 按照8字節(jié)對齊 按照#pragma pack(4)對齊的話,n=20

5,位域字節(jié)對齊規(guī)則

“位域”是把一個字節(jié)中的二進位劃分為幾個不同的區(qū)域,并說明每個區(qū)域的位數(shù)。使用位域的主要目的是壓縮存儲。

位域列表的形式為:?類型說明符 位域名:位域長度(單位:位 bite)

如:struct bs ? ? ? { ? ? ? ? ? ?int a:8; ? ? ? ? ? ?int b:2; ? ? ? ? ? ?int c:6; ? ? ? ?} data; 其中位域a占8位,位域b占2位,位域c占6位。

位域說明:

1.?一個位域必須存儲在同一個字節(jié)中,不能跨兩個字節(jié)。如一個字節(jié)所??臻g不夠存放另一位域時,應(yīng)從下一單元起存放該位域。

2. 由于位域不允許跨兩個字節(jié),因此位域的長度不能大于一個字節(jié)(8位)的長度,也就是說不能超過8位二進位。 3. 位域可以無位域名,這時它只用來作填充或調(diào)整位置。無名的位域是不能使用的。例如:?int :2 ?

位域?qū)R規(guī)則

1) 如果相鄰位域字段的類型相同,且其位寬之和小于類型的sizeof大小,則后面的字段將緊鄰前一個字段存儲,直到不能容納為止;

2) 如果相鄰位域字段的類型相同,但其位寬之和大于類型的sizeof大小,則后面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數(shù)倍;

3) 如果相鄰的位域字段的類型不同,從新的存儲單元開始,偏移量為其類型大小的整數(shù)倍,即不壓縮;(各編譯器的具體實現(xiàn)有差異,VC6采取不壓縮方式,Dev-??

? ? ?C++采取壓縮方式)

4) 如果位域字段之間穿插著非位域字段,則不進行壓縮;

5)?整個結(jié)構(gòu)體的總大小為最寬基本類型成員大小的整數(shù)倍。

例題:

(1)typedef?struct??AA { ???????unsigned?int?b1:5; ???????unsigned?int?b2:5; ???????unsigned?int?b3:5; ???????unsigned?int?b4:5; ???????unsigned?int?b5:5; }AA;

sizeof(AA)= 4?

【解析】參考規(guī)則 1)。由于相鄰成員類型相同,unsigned?int為 4 個字節(jié),b1占5位,b2加上b1的位數(shù)之和為10位,不超過4字節(jié),因此b2接著b1繼續(xù)存儲;

? ? ? 同理b3、b4、b5的類型相同,位數(shù)之和不超過4字節(jié),因此接著b2繼續(xù)存儲,總位數(shù)為25位。

? ? ? 由于結(jié)構(gòu)體的大小是最寬類型成員的整數(shù)倍,因此25位之后的補0,直到補滿4字節(jié)。

(2)typedef?struct??AA { ???????unsigned?int?b1:5; ???????unsigned?int?b2:5; ???????unsigned?int?b3:5; ???????unsigned?int?b4:5; ???????unsigned?int?b5:5; ???????unsigned?int?b6:5; ???????unsigned?int?b7:5; }AA; ? ?sizeof(AA)= 8?

【解析】參考規(guī)則 1) 和規(guī)則 2) 。由于相鄰成員類型相同,unsigned?int為 4 個字節(jié)(32位),當(dāng)存儲到 b7 時,b7和b6之前的位數(shù)相加超過4字節(jié),

因此b7從新的存儲單元開始存儲。

即b1~b6?存儲在 第0~29位,第30、31位補0,b7從下一個 4字節(jié)存儲單元 開始存儲5位,剩下的補0。

?(3)struct test1

{

char a:1;

char :2;

long b:3;

char c:2;

};

?sizeof(test1)= 12

【解析】 

char a:1; //用一個字節(jié)去存儲

char :2;  //空域。因為與前面的a的類型相同,而兩個位域的位寬相加仍然少于8位,所以依然用1個字節(jié)表示

long b:3; //long類型的位寬是4個字節(jié),與前面的char類型不同,所以b與a之間偏移4個字節(jié),它們之間自動補充3個字節(jié) 

char c:2; //因為c與b又不同型,以test1中的最長的long類型的位寬進行偏移,所以雖然char只用1個字節(jié)就夠了,但依然要占4個字節(jié)。

結(jié)構(gòu)體總長以最長的類型位寬做為偏移量,最長的是long型,占4位,所以不同類型之間應(yīng)該是4個字節(jié)的偏移,即test1應(yīng)該是4字節(jié)的整數(shù)倍?!?/p>

總共是12字節(jié)。

柚子快報激活碼778899分享:C語言----字節(jié)對齊

http://yzkb.51969.com/

精彩鏈接

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19269734.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機訪問

文章目錄