日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]什么是字節(jié)對(duì)齊 一個(gè)變量占用 n 個(gè)字節(jié),則該變量的起始地址必須能夠被 n 整除,即: 存放起始地址 % n = 0, 對(duì)于結(jié)構(gòu)體而言,這個(gè) n 取其成員種的數(shù)據(jù)類(lèi)型占空間的值最大的那個(gè)。為什么要字節(jié)對(duì)齊 內(nèi)存空間是按照字

什么是字節(jié)對(duì)齊
一個(gè)變量占用 n 個(gè)字節(jié),則該變量的起始地址必須能夠被 n 整除,即: 存放起始地址 % n = 0, 對(duì)于結(jié)構(gòu)體而言,這個(gè) n 取其成員種的數(shù)據(jù)類(lèi)型占空間的值最大的那個(gè)。
為什么要字節(jié)對(duì)齊
內(nèi)存空間是按照字節(jié)來(lái)劃分的,從理論上說(shuō)對(duì)內(nèi)存空間的訪(fǎng)問(wèn)可以從任何地址開(kāi)始,但是在實(shí)際上不同架構(gòu)的CPU為了提高訪(fǎng)問(wèn)內(nèi)存的速度,就規(guī)定了對(duì)于某些類(lèi)型的數(shù)據(jù)只能從特定的起始位置開(kāi)始訪(fǎng)問(wèn)。這樣就決定了各種數(shù)據(jù)類(lèi)型只能按照相應(yīng)的規(guī)則在內(nèi)存空間中存放,而不能一個(gè)接一個(gè)的順序排列。

舉個(gè)例子,比如有些平臺(tái)訪(fǎng)問(wèn)內(nèi)存地址都從偶數(shù)地址開(kāi)始,對(duì)于一個(gè)int型(假設(shè)32位系統(tǒng)),如果從偶數(shù)地址開(kāi)始的地方存放,這樣一個(gè)讀周期就可以讀出這個(gè)int數(shù)據(jù),但是如果從奇數(shù)地址開(kāi)始的地址存放,就需要兩個(gè)讀周期,并對(duì)兩次讀出的結(jié)果的高低字節(jié)進(jìn)行拼湊才能得到這個(gè)int數(shù)據(jù),這樣明顯降低了讀取的效率。

如何進(jìn)行字節(jié)對(duì)齊

每個(gè)成員按其類(lèi)型的對(duì)齊參數(shù)(通常是這個(gè)類(lèi)型的大小)和指定對(duì)齊參數(shù)(不指定則取默認(rèn)值)中較小的一個(gè)對(duì)齊,并且結(jié)構(gòu)的長(zhǎng)度必須為所用過(guò)的所有對(duì)齊參數(shù)的整數(shù)倍,不夠就補(bǔ)空字節(jié)。

這個(gè)規(guī)則有點(diǎn)苦澀,可以把這個(gè)規(guī)則分解一下,前半句的意思先獲得對(duì)齊值后與指定對(duì)齊值進(jìn)行比較,其中對(duì)齊值獲得方式如下:

1. 數(shù)據(jù)類(lèi)型的自身對(duì)齊值為:對(duì)于char型數(shù)據(jù),其自身對(duì)齊值為1,對(duì)于short型為2,對(duì)于int, long, float類(lèi)型,其自身對(duì)齊值為4,對(duì)于 double 類(lèi)型其自身對(duì)齊值為8,單位為字節(jié)。
2.結(jié)構(gòu)體自身對(duì)齊值:其成員中自身對(duì)齊值最大的那個(gè)值。

其中指定對(duì)齊值獲得方式如下:

#pragma pack (value)時(shí)的指定對(duì)齊值value。

未指定則取默認(rèn)值。

后半句的意思是主要是針對(duì)于結(jié)構(gòu)體的長(zhǎng)度而言,因?yàn)獒槍?duì)數(shù)據(jù)類(lèi)型的成員,它僅有一個(gè)對(duì)齊參數(shù),其本身的長(zhǎng)度、于這個(gè)對(duì)齊參數(shù),即1倍。對(duì)于結(jié)構(gòu)體而言,它可能使用了多種數(shù)據(jù)類(lèi)型,那么這句話(huà)翻譯成對(duì)齊規(guī)則: 每個(gè)成員的起始地址 % 自身對(duì)齊值 = 0,如果不等于 0 則先補(bǔ)空字節(jié)直至這個(gè)表達(dá)式成立。
換句話(huà)說(shuō),對(duì)于結(jié)構(gòu)體而言,結(jié)構(gòu)體在在內(nèi)存的存放順序用如下規(guī)則即可映射出來(lái):
(一)每個(gè)成員的起始地址 % 每個(gè)成員的自身對(duì)齊值 = 0,如果不等于 0 則先補(bǔ)空字節(jié)直至這個(gè)表達(dá)式成立;
(二)結(jié)構(gòu)體的長(zhǎng)度必須為結(jié)構(gòu)體的自身對(duì)齊值的整數(shù)倍,不夠就補(bǔ)空字節(jié)。

#pragma pack(8)
struct A{
char a;
long b;
};

struct B{
char a;
struct A b;
long c;
};

struct C{
char a;
struct A b;
double c;
};

struct D{
char a;
struct A b;
double c;
int d;
};

struct E{
char a;
int b;
struct A c;
double d;
};


對(duì)于 struct A 來(lái)說(shuō),對(duì)于char型數(shù)據(jù),其自身對(duì)齊值為1,對(duì)于long類(lèi)型,其自身對(duì)齊值為4, 結(jié)構(gòu)體的自身對(duì)齊值取其成員最大的對(duì)齊值,即大小4。那么struct A 在內(nèi)存中的順序步驟為:
(1) char a, 地址范圍為0x0000~0x0000,起始地址為0x0000,滿(mǎn)足 0x0000 % 1 = 0,這個(gè)成員字節(jié)對(duì)齊了。
(2) long b, 地址起始位置不能從0x00001開(kāi)始,因?yàn)?0x0001 % 4 != 0, 所以先補(bǔ)空字節(jié),直到0x00003結(jié)束,即補(bǔ)3個(gè)字節(jié)的空字節(jié),從0x00004開(kāi)始存放b,其地址范圍為0x00004~0x0007.
(3)此時(shí)成員都存放結(jié)束,結(jié)構(gòu)體長(zhǎng)度為8,為結(jié)構(gòu)體自身對(duì)齊值的2倍,符合條件(二).
此時(shí)滿(mǎn)足條件(一)和條件(二),struct A 中各成員在內(nèi)存中的位置為:a*** b ,sizeof(struct A) = 8。(每個(gè)星號(hào)代表一位,成員各自代表自己所占的位,比如a占一位,b占四位)

對(duì)于struct B,里面有個(gè)類(lèi)型為struct A的成員b自身對(duì)齊值為4,對(duì)于long類(lèi)型,其自身對(duì)齊值為4. 故struct B的自身對(duì)齊值為4。那么struct B 在內(nèi)存中的順序步驟為:
(1) char a, 地址范圍為0x0000~0x0000,起始地址為0x0000,滿(mǎn)足 0x0000 % 1 = 0,這個(gè)成員字節(jié)對(duì)齊了。
(2) struct A b, 地址起始位置不能從0x00001開(kāi)始,因?yàn)?0x0001 % 4 != 0, 所以先補(bǔ)空字節(jié),直到0x00003結(jié)束,即補(bǔ)3個(gè)字節(jié)的空字節(jié),從0x00004開(kāi)始存放b,其地址范圍為0x00004~0x00011.
(3) long c,地址起始位置從0x000012開(kāi)始, 因?yàn)?0x0012 % 4 = 0,其地址范圍為0x00012~0x0015.
(4)此時(shí)成員都存放結(jié)束,結(jié)構(gòu)體長(zhǎng)度為16,為結(jié)構(gòu)體自身對(duì)齊值的4倍,符合條件(二).
此時(shí)滿(mǎn)足條件(一)和條件(二),struct B 中各成員在內(nèi)存中的位置為:a*** b c ,sizeof(struct C) = 24。(每個(gè)星號(hào)代表一位,成員各自代表自己所占的位,比如a占一位,b占八位,c占四位)
對(duì)于struct C,里面有個(gè)類(lèi)型為struct A的成員b自身對(duì)齊值為4,對(duì)于double 類(lèi)型,其自身對(duì)齊值為8. 故struct C的自身對(duì)齊值為8。那么struct C 在內(nèi)存中的順序步驟為:
(1) char a, 地址范圍為0x0000~0x0000,起始地址為0x0000,滿(mǎn)足 0x0000 % 1 = 0,這個(gè)成員字節(jié)對(duì)齊了。
(2) struct A b, 地址起始位置不能從0x00001開(kāi)始,因?yàn)?0x0001 % 4 != 0, 所以先補(bǔ)空字節(jié),直到0x00003結(jié)束,即補(bǔ)3個(gè)字節(jié)的空字節(jié),從0x00004開(kāi)始存放b,其地址范圍為0x00004~0x00011.
(3) double c,地址起始位置不能從0x000012開(kāi)始, 因?yàn)?0x0012 % 8 != 0,所以先補(bǔ)空字節(jié),直到0x000015結(jié)束,即補(bǔ)4個(gè)字節(jié)的空字節(jié),從0x00016開(kāi)始存放c,其地址范圍為0x00016~0x0023.
(4)此時(shí)成員都存放結(jié)束,結(jié)構(gòu)體長(zhǎng)度為24,為結(jié)構(gòu)體自身對(duì)齊值的3倍,符合條件(二).
此時(shí)滿(mǎn)足條件(一)和條件(二),struct C 中各成員在內(nèi)存中的位置為:a*** b **** c ,sizeof(struct C) = 24。(每個(gè)星號(hào)代表一位,成員各自代表自己所占的位,比如a占一位,b占八位,c占八位)

對(duì)于struct D,自身對(duì)齊值為8。前面三個(gè)成員與 struct C 是一致的。對(duì)于第四成員d,因?yàn)?0x0024 % 4 = 0, 所以可以從0x0024開(kāi)始存放d, 其地址范圍為0x00024~0x00027.此時(shí)成員都存放結(jié)束,結(jié)構(gòu)體長(zhǎng)度為28,28 不是結(jié)構(gòu)體自身對(duì)齊值8的倍數(shù),所以要在后面補(bǔ)四個(gè)空格,即在0x0028~0x0031上補(bǔ)四個(gè)空格。補(bǔ)完了,結(jié)構(gòu)體長(zhǎng)度為32, 為結(jié)構(gòu)體自

身對(duì)齊值的4被,,符合條件(二).
此時(shí)滿(mǎn)足條件(一)和條件(二),struct D 中各成員在內(nèi)存中的位置為:a*** b **** c d **** ,sizeof(struct D) = 32。(每個(gè)星號(hào)代表一位,成員各自代表自己所占的位,比如a占一位,b占八位,c占八位, d占四位)。

對(duì)于struct E 中各成員在內(nèi)存中的位置為:a*** b c d, sizeof(struct E) = 24。(每個(gè)星號(hào)代表一位,成員各自代表自己所占的位,比如a占一位,b占四位,c占八位, d占八位)。
通過(guò)struct D 和 struct E 可以看出,在成員數(shù)量和類(lèi)型一致的情況,后者的所占空間少于前者,因?yàn)楹笳叩奶畛淇兆止?jié)要少。如果我們?cè)诰幊虝r(shí)考慮節(jié)約空間的話(huà),應(yīng)該遵循將變量按照類(lèi)型大小從小到大聲明的原則, 這樣盡量減少填補(bǔ)空間。另外,可以在填充空字節(jié)的地方來(lái)插入reserved成員, 例如
struct A
{
char a;
char reserved[3];
int b;
};
這樣做的目的主要是為了對(duì)程序員起一個(gè)提示作用,如果不加則編譯器會(huì)自動(dòng)補(bǔ)齊。

習(xí)題

typedef struct

{

int a; //ARM(int=4) 51(int=2)

char b; // 1

short c; // 2

}AAA;

typedef struct

{

char b;

int a;

short c;

}BBB;

i = sizeof(AAA);

j = sizeof(BBB);

//注意在51單片機(jī),ARM,PC不同

51 (i=j=5) //好像強(qiáng)制單字節(jié)對(duì)齊

ARM(i=8,j=12) //按規(guī)則默認(rèn)對(duì)齊

PC(i=8,j=12)

AAA對(duì)齊方式如下(ARM)

I I I I

I0 I I

BBB對(duì)齊方式如下(ARM)

I 0 0 0

II I I

I I 0 0

通過(guò)#pragma pack可以調(diào)整對(duì)齊字節(jié)數(shù)

#pragma pack(1) //指定Align為 1字節(jié);

。。。。。。。。。。。。//需要對(duì)齊的結(jié)構(gòu)體

#pragma pack() //恢復(fù)到原先值


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

特朗普集團(tuán)近日取消了其新推出的T1智能手機(jī)“將在美國(guó)制造”的宣傳標(biāo)語(yǔ),此舉源于外界對(duì)這款手機(jī)能否以當(dāng)前定價(jià)在美國(guó)本土生產(chǎn)的質(zhì)疑。

關(guān)鍵字: 特朗普 蘋(píng)果 AI

美國(guó)總統(tǒng)特朗普在公開(kāi)場(chǎng)合表示,他已要求蘋(píng)果公司CEO蒂姆·庫(kù)克停止在印度建廠(chǎng),矛頭直指該公司生產(chǎn)多元化的計(jì)劃。

關(guān)鍵字: 特朗普 蘋(píng)果 AI

4月10日消息,據(jù)媒體報(bào)道,美國(guó)總統(tǒng)特朗普宣布,美國(guó)對(duì)部分貿(mào)易伙伴暫停90天執(zhí)行新關(guān)稅政策,同時(shí)對(duì)中國(guó)的關(guān)稅提高到125%,該消息公布后蘋(píng)果股價(jià)飆升了15%。這次反彈使蘋(píng)果市值增加了4000多億美元,目前蘋(píng)果市值接近3萬(wàn)...

關(guān)鍵字: 特朗普 AI 人工智能 特斯拉

3月25日消息,據(jù)報(bào)道,當(dāng)?shù)貢r(shí)間3月20日,美國(guó)總統(tǒng)特朗普在社交媒體平臺(tái)“真實(shí)社交”上發(fā)文寫(xiě)道:“那些被抓到破壞特斯拉的人,將有很大可能被判入獄長(zhǎng)達(dá)20年,這包括資助(破壞特斯拉汽車(chē))者,我們正在尋找你?!?/p> 關(guān)鍵字: 特朗普 AI 人工智能 特斯拉

1月22日消息,剛剛,新任美國(guó)總統(tǒng)特朗普放出重磅消息,將全力支持美國(guó)AI發(fā)展。

關(guān)鍵字: 特朗普 AI 人工智能

特朗普先生有兩件事一定會(huì)載入史冊(cè),一個(gè)是筑墻,一個(gè)是挖坑。在美墨邊境筑墻的口號(hào)確保邊境安全,降低因非法移民引起的犯罪率過(guò)高問(wèn)題;在中美科技產(chǎn)業(yè)之間挖坑的口號(hào)也是安全,美國(guó)企業(yè)不得使用對(duì)美國(guó)國(guó)家安全構(gòu)成威脅的電信設(shè)備,總統(tǒng)...

關(guān)鍵字: 特朗普 孤立主義 科技產(chǎn)業(yè)

據(jù)路透社1月17日消息顯示,知情人士透露,特朗普已通知英特爾、鎧俠在內(nèi)的幾家華為供應(yīng)商,將要撤銷(xiāo)其對(duì)華為的出貨的部分許可證,同時(shí)將拒絕其他數(shù)十個(gè)向華為供貨的申請(qǐng)。據(jù)透露,共有4家公司的8份許可被撤銷(xiāo)。另外,相關(guān)公司收到撤...

關(guān)鍵字: 華為 芯片 特朗普

曾在2018年時(shí)被美國(guó)總統(tǒng)特朗普稱(chēng)作“世界第八奇跡”的富士康集團(tuán)在美國(guó)威斯康星州投資建設(shè)的LCD顯示屏工廠(chǎng)項(xiàng)目,如今卻因?yàn)楦皇靠祵㈨?xiàng)目大幅縮水并拒絕簽訂新的合同而陷入了僵局。這也導(dǎo)致富士康無(wú)法從當(dāng)?shù)卣抢铽@得約40億美...

關(guān)鍵字: 特朗普 富士康

今年5月,因自己發(fā)布的推文被貼上“無(wú)確鑿依據(jù)”標(biāo)簽而與推特發(fā)生激烈爭(zhēng)執(zhí)后,美國(guó)總統(tǒng)特朗普簽署了一項(xiàng)行政令,下令要求重審《通信規(guī)范法》第230條。

關(guān)鍵字: 谷歌 facebook 特朗普

眾所周知,寄往白宮的所有郵件在到達(dá)白宮之前都會(huì)在他地進(jìn)行分類(lèi)和篩選。9月19日,根據(jù)美國(guó)相關(guān)執(zhí)法官員的通報(bào),本周早些時(shí)候,執(zhí)法人員截獲了一個(gè)寄給特朗普總統(tǒng)的包裹,該包裹內(nèi)包含蓖麻毒蛋白。

關(guān)鍵字: 美國(guó) 白宮 特朗普
關(guān)閉