位元組對齊,還有你不知道的!

2022-05-18 23:54:13 字數 1496 閱讀 2791

位元組對齊的細節和編譯器實現相關,但一般而言,滿足三個準則:

1) 結構體變數的首位址能夠被其最寬基本型別成員的大小所整除;

2) 結構體每個成員相對於結構體首位址的偏移量(offset)都是成員大小的整數倍,

如有需要編譯器會在成員之間加上填充位元組(internal adding);

3) 結構體的總大小為結構體最寬基本型別成員大小的整數倍,如有需要編譯器會在最

末乙個成員之後加上填充位元組(trailing padding)。

一、結構體某個成員相對於結構體首位址的偏移量可以通過巨集offsetof()來獲得,這個巨集也

在stddef.h中定義,如下:

#define offsetof(s,m) (size_t)&(((s *)0)->m)

這個很厲害,很佩服c語言標準小組裡的大牛! 0x00000000指標的妙用!

二、vc6中通過#pragma pack實現,也可以

直接修改/zp編譯開關。#pragma pack的基本用法為:#pragma pack( n ),n為位元組對齊

數,其取值為1、2、4、8、16,預設是8,如果這個值比結構體成員的sizeof值小,那麼

該成員的偏移量應該以此值為準,即是說,結構體成員的偏移量應該取二者的最小值。

#pragma pack(push) // 將當前pack設定壓棧儲存

#pragma pack(2)// 必須在結構體定義之前使用

//定義結構體

#pragma pack(pop) // 恢復先前的pack設定

還有含有位域的結構體,以及聯合體,實在用到的時候再來看看吧。繁瑣。

8. 含位域結構體的sizeof

前面已經說過,位域成員不能單獨被取sizeof值,我們這裡要討論的是含有位域的結構

體的sizeof,只是考慮到其特殊性而將其專門列了出來。

c99規定int、unsigned int和bool可以作為位域型別,但編譯器幾乎都對此作了擴充套件,

允許其它型別型別的存在。

使用位域的主要目的是壓縮儲存,其大致規則為:

1) 如果相鄰位域字段的型別相同,且其位寬之和小於型別的sizeof大小,則後面的字

段將緊鄰前乙個字段儲存,直到不能容納為止;

2) 如果相鄰位域字段的型別相同,但其位寬之和大於型別的sizeof大小,則後面的字

段將從新的儲存單元開始,其偏移量為其型別大小的整數倍;

3) 如果相鄰的位域字段的型別不同,則各編譯器的具體實現有差異,vc6採取不壓縮方

式,dev-c++採取壓縮方式;

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

5) 整個結構體的總大小為最寬基本型別成員大小的整數倍。

9. 聯合體的sizeof

結構體在記憶體組織上是順序式的,聯合體則是重疊式,各成員共享一段記憶體,所以整個

聯合體的sizeof也就是每個成員sizeof的最大值。結構體的成員也可以是復合型別,這

裡,復合型別成員是被作為整體考慮的。

收藏於 2011-01-29

你不知道的 和

開發中,編寫有一定逼格的 是每個程式猿都追求的。經常用來判斷的符號 和 也經常用來定義變數哦,你知道嗎?邏輯與 在有乙個運算元不是布林值的情況下,就不一定返回布林值。比如以下情況 1 第乙個運算元是物件,返回第二個數 var myinfo console.log myinfo 2 輸出22 第二個運...

你不知道的box shadow

我們可以僅使用乙個div利用shadow配合animation實現很多豐富的效果 github 求 必需。水平陰影的位置。允許負值。v shadow 必需。垂直陰影的位置。允許負值。blur 可選。模糊距離。spread 可選。陰影的尺寸。color 可選。陰影的顏色。請參閱 css 顏色值。ins...

你不知道的 gitignore

乙個.gitignore檔案顯式地指定了哪些檔案不應被git追蹤,即被git忽略掉。在被gitignore之前已經被git追蹤的檔案不受gitignore規則的影響。關於gitignore規則的詳情請繼續往下看。gitignore檔案中的每一行都指定了一種匹配模式。通常來說,git會從多個可能的規則...