3 回答

TA貢獻(xiàn)883條經(jīng)驗(yàn) 獲得超454個(gè)贊
每種類型都有一個(gè)叫做“對(duì)齊值”的屬性。這個(gè)屬性相當(dāng)于描述“在內(nèi)存中其能夠分配的起始地址和前一一個(gè)此類型能夠分配的起始地址的間距”。
啊,好吧,我的文字表達(dá)能力比較差,上述說(shuō)法我自己看著都覺(jué)得累,其實(shí)通俗地說(shuō)就是限制了“能在內(nèi)存中哪些位置放這個(gè)類型的對(duì)象”。
我還是舉些例子吧,我們?cè)诩傧氲囊恍《蝺?nèi)存中進(jìn)行描述,這段內(nèi)存的起始地址被當(dāng)作 0 地址:
假定 int 類型本身占 4 字節(jié),對(duì)齊值也是 4。那么如果想在這段內(nèi)存中放一個(gè) int 變量,能放在哪里呢?
起始的 0 字節(jié)處當(dāng)然可以放。但如果我不從這段內(nèi)存起始處放,能不能從第 2 字節(jié)處放一個(gè) int 呢?? 答案是不可以!
因?yàn)?int 的對(duì)齊值是 4。內(nèi)存 0 字節(jié)之后,只能間隔 4 字節(jié)再放一個(gè) int 對(duì)象,所以只能在這段內(nèi)存的 4 字節(jié)處放一個(gè) int。注意:這并不是因?yàn)?0 到 3 字節(jié)被前一個(gè) int 占用了!即便這段內(nèi)存中只放一個(gè) int,前面 0 到 3 字節(jié)都是空的,也不能在 1、2、3 字節(jié)處放置 int ——兩個(gè)合法的放置 int 的起始地址必須間隔 4。
也就是只能在這段內(nèi)存的 0、4、8、12 ....字節(jié)處分配 int 對(duì)象。
char 類型本身占用 1 字節(jié)(這點(diǎn)不用假設(shè)了,C標(biāo)準(zhǔn)規(guī)定如此),對(duì)齊值也是 1 。那么你可以知道,這段內(nèi)存的任何一個(gè)字節(jié)處都可以合法地放置一個(gè) char 對(duì)象。
我希望你看懂了我的這些羅嗦解釋。
還有,就像你知道 C 語(yǔ)言是很靈活的,其實(shí) C 標(biāo)準(zhǔn)并沒(méi)有規(guī)定每種類型具體占用內(nèi)存的大小和其對(duì)齊值,不同平臺(tái)可能有自己的規(guī)定。C 標(biāo)準(zhǔn)只是規(guī)定了對(duì)齊值必須是 2 的整數(shù)次冪(從 C11 標(biāo)準(zhǔn)開(kāi)始,你可以用 _Alignof 運(yùn)算符來(lái)獲得類型的對(duì)齊值)
union 的所有成員的起始地址都一樣,所以基本上不用考慮對(duì)齊的問(wèn)題。
struct 的不同成員是依次放置于內(nèi)存中的,每個(gè)成員在內(nèi)存中的位置都必須滿足其類型對(duì)齊值的要求!? 而整個(gè) struct 的對(duì)齊值一般是其成員對(duì)齊值中最大的一個(gè)(不過(guò)此題不涉及這點(diǎn))。
正如我前面提到 C 標(biāo)準(zhǔn)沒(méi)有具體規(guī)定類型的對(duì)齊值。那么嚴(yán)格地說(shuō),這道題出得也不嚴(yán)謹(jǐn),它應(yīng)該說(shuō)明這些類型的對(duì)齊值再讓學(xué)生做計(jì)算的。既然它沒(méi)說(shuō),我就用常見(jiàn)的對(duì)齊值來(lái)解釋下題目中的 struct:
int 占 4 字節(jié),對(duì)齊值為 4。所以 struct 中前 4 個(gè)字節(jié)就是這個(gè) num,這是很顯然的。
char 占 1 字節(jié),對(duì)齊值為 1。數(shù)組中元素是緊挨著放置的,所以 name 數(shù)組占 10 字節(jié)。
這樣 struct 前 14 個(gè)字節(jié)就是 num 和 name 占用的。
float 占 4 字節(jié),對(duì)齊值為 4。那第三個(gè)成員 score 就不能從第 15 字節(jié)起了。它必須放在 4 的倍數(shù)的位置上,所以第 15、16 字節(jié)要被空出來(lái),從第 17 字節(jié)處放置 score。score 占用第 17、18、19、20 字節(jié)。
那么整個(gè) struct 就占用 20 字節(jié)。??
- 3 回答
- 2 關(guān)注
- 1929 瀏覽
添加回答
舉報(bào)