C 結(jié)構(gòu)體對(duì)齊規(guī)則

  1. 描述指針與指針變量的區(qū)別:

    • 指針:指針是一個(gè)變量,它存儲(chǔ)著內(nèi)存中某個(gè)數(shù)據(jù)單元的地址挎袜,即內(nèi)存單元的編號(hào)顽聂。
    • 指針變量:指針變量本質(zhì)上也是一個(gè)變量肥惭,但它存儲(chǔ)的是另一個(gè)變量或者數(shù)據(jù)結(jié)構(gòu)的地址盯仪,而不是實(shí)際的數(shù)據(jù)紊搪。
  2. 描述32位或64位平臺(tái)下指針的大小:

    • 在32位平臺(tái)上全景,任意類型的指針大小為4字節(jié)耀石。
    • 在64位平臺(tái)上,任意類型的指針大小為8字節(jié)爸黄。
  3. 描述指針數(shù)組的概念:

    • 指針數(shù)組是數(shù)組的一種滞伟,其中每個(gè)元素都是指針類型,即存儲(chǔ)的是地址炕贵。這意味著指針數(shù)組中的每個(gè)元素都指向某個(gè)數(shù)據(jù)單元的地址梆奈。
  4. 描述define和typedef的區(qū)別:

    • #define 是 C 預(yù)處理指令,用于創(chuàng)建宏称开。它在編譯之前執(zhí)行文本替換亩钟。
    • typedef 是 C 語言關(guān)鍵字,用于為已有的數(shù)據(jù)類型創(chuàng)建一個(gè)新的名字鳖轰。它在編譯時(shí)期進(jìn)行處理清酥,可以提高代碼的可讀性和可維護(hù)性。
  5. 結(jié)構(gòu)體對(duì)齊規(guī)則:

    • 規(guī)則一: 結(jié)構(gòu)體中的元素按照定義的順序依次置于內(nèi)存中蕴侣,但并不是緊密排列焰轻。每個(gè)元素被放置在其自身對(duì)齊大小的整數(shù)倍地址上。
    • 規(guī)則二: 如果結(jié)構(gòu)體大小不是所有元素中最大對(duì)齊大小的整數(shù)倍昆雀,則結(jié)構(gòu)體對(duì)齊到最大元素對(duì)齊大小的整數(shù)倍辱志,填充空間放置到結(jié)構(gòu)體末尾。
    • 規(guī)則三: 基本數(shù)據(jù)類型的對(duì)齊大小為其自身的大小狞膘,結(jié)構(gòu)體數(shù)據(jù)類型的對(duì)齊大小為其元素中最大對(duì)齊大小元素的對(duì)齊大小荸频。

這些規(guī)則確保了結(jié)構(gòu)體在內(nèi)存中的布局和訪問時(shí)的一致性和效率。


詳細(xì)解釋結(jié)構(gòu)體對(duì)齊規(guī)則:

結(jié)構(gòu)體對(duì)齊規(guī)則是編譯器為了最大化內(nèi)存訪問速度和最小化內(nèi)存使用而采用的一種策略客冈。這些規(guī)則確保了結(jié)構(gòu)體在內(nèi)存中的布局是可預(yù)測(cè)和高效的旭从。

  1. 規(guī)則一:元素對(duì)齊

    • 結(jié)構(gòu)體中的每個(gè)元素按照其自身的對(duì)齊要求被放置在內(nèi)存中。對(duì)齊要求通常與元素的數(shù)據(jù)類型有關(guān)场仲。
    • 基本數(shù)據(jù)類型的對(duì)齊要求通常是其自身大小和悦,例如,int通常對(duì)齊到4字節(jié)邊界渠缕,double通常對(duì)齊到8字節(jié)邊界鸽素。
    • 結(jié)構(gòu)體中的自定義類型(如結(jié)構(gòu)體本身或者其他自定義類型)的對(duì)齊要求通常是其包含的基本數(shù)據(jù)類型中的最大對(duì)齊要求。
  2. 規(guī)則二:填充空間

    • 如果結(jié)構(gòu)體中的元素的大小之和不是某個(gè)值的整數(shù)倍亦鳞,編譯器會(huì)在結(jié)構(gòu)體的末尾插入一些填充空間馍忽,使得結(jié)構(gòu)體的總大小是某個(gè)值的整數(shù)倍棒坏。
    • 這個(gè)值通常是結(jié)構(gòu)體中的元素中的最大對(duì)齊要求。
  3. 結(jié)合示例詳細(xì)解釋: 假設(shè)有以下結(jié)構(gòu)體:

    struct Example {
        char a;    // 1字節(jié)
        int b;     // 4字節(jié)(32位平臺(tái))
        double c;  // 8字節(jié)
    };
    
    • 結(jié)構(gòu)體中的char類型通常對(duì)齊到1字節(jié)邊界遭笋,所以a被放置在結(jié)構(gòu)體的起始位置坝冕。
    • int類型通常對(duì)齊到4字節(jié)邊界,所以b被放置在離結(jié)構(gòu)體起始位置最近的4字節(jié)邊界上瓦呼,可能會(huì)有3個(gè)字節(jié)的填充空間喂窟。
    • double類型通常對(duì)齊到8字節(jié)邊界,所以c被放置在離結(jié)構(gòu)體起始位置最近的8字節(jié)邊界上央串,可能會(huì)有4個(gè)字節(jié)的填充空間磨澡。
    • 結(jié)構(gòu)體的總大小通常是8的整數(shù)倍,所以結(jié)構(gòu)體的總大小可能是24字節(jié)(1字節(jié)的a + 3字節(jié)填充 + 4字節(jié)的b + 4字節(jié)的c)质和。

通過這些對(duì)齊規(guī)則稳摄,編譯器可以確保結(jié)構(gòu)體的訪問速度是高效的,并且在不同的平臺(tái)上饲宿,結(jié)構(gòu)體的大小和布局都是可預(yù)測(cè)的厦酬。


代碼解釋一下這三個(gè)規(guī)則:

??讓我們用一些 C 代碼來演示這三個(gè)結(jié)構(gòu)體對(duì)齊規(guī)則:

#include <stdio.h>

// 定義一個(gè)結(jié)構(gòu)體
struct Example {
    char a;     // 1字節(jié)
    int b;      // 4字節(jié)(32位平臺(tái))
    double c;   // 8字節(jié)
};

int main() {
    printf("Size of struct Example: %zu bytes\n", sizeof(struct Example));
    printf("Offset of member 'a': %zu bytes\n", offsetof(struct Example, a));
    printf("Offset of member 'b': %zu bytes\n", offsetof(struct Example, b));
    printf("Offset of member 'c': %zu bytes\n", offsetof(struct Example, c));

    return 0;
}

運(yùn)行這段代碼,你會(huì)得到類似以下的輸出(具體數(shù)值可能因編譯器和平臺(tái)而異):

Size of struct Example: 16 bytes
Offset of member 'a': 0 bytes
Offset of member 'b': 4 bytes
Offset of member 'c': 8 bytes

現(xiàn)在讓我們解釋這個(gè)輸出以說明結(jié)構(gòu)體對(duì)齊規(guī)則:

  1. Size of struct Example: 16 bytes

    • 結(jié)構(gòu)體Example的大小為16字節(jié)褒傅。這是因?yàn)樵?2位平臺(tái)上弃锐,char占1字節(jié),int占4字節(jié)殿托,double占8字節(jié)霹菊,加上填充字節(jié)。
  2. Offset of member 'a': 0 bytes

    • 成員a位于結(jié)構(gòu)體的起始位置支竹,因此其偏移量為0字節(jié)旋廷。
  3. Offset of member 'b': 4 bytes

    • 成員b被放置在離結(jié)構(gòu)體起始位置最近的4字節(jié)邊界上,因此它的偏移量為4字節(jié)礼搁。
  4. Offset of member 'c': 8 bytes

    • 成員c被放置在離結(jié)構(gòu)體起始位置最近的8字節(jié)邊界上饶碘,因此它的偏移量為8字節(jié)。

這個(gè)示例演示了結(jié)構(gòu)體對(duì)齊規(guī)則馒吴,說明了每個(gè)成員在內(nèi)存中的位置和結(jié)構(gòu)體的總大小扎运。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市饮戳,隨后出現(xiàn)的幾起案子豪治,更是在濱河造成了極大的恐慌,老刑警劉巖扯罐,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件负拟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡歹河,警方通過查閱死者的電腦和手機(jī)掩浙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門花吟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人厨姚,你說我怎么就攤上這事衅澈。” “怎么了遣蚀?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵矾麻,是天一觀的道長(zhǎng)纱耻。 經(jīng)常有香客問我芭梯,道長(zhǎng),這世上最難降的妖魔是什么弄喘? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任玖喘,我火速辦了婚禮,結(jié)果婚禮上蘑志,老公的妹妹穿的比我還像新娘累奈。我一直安慰自己,他們只是感情好急但,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布澎媒。 她就那樣靜靜地躺著,像睡著了一般波桩。 火紅的嫁衣襯著肌膚如雪戒努。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天镐躲,我揣著相機(jī)與錄音储玫,去河邊找鬼。 笑死萤皂,一個(gè)胖子當(dāng)著我的面吹牛撒穷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裆熙,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼端礼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了入录?” 一聲冷哼從身側(cè)響起蛤奥,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纷跛,沒想到半個(gè)月后喻括,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贫奠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年唬血,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了望蜡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拷恨,死狀恐怖脖律,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腕侄,我是刑警寧澤小泉,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站冕杠,受9級(jí)特大地震影響微姊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜分预,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一兢交、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧笼痹,春花似錦配喳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至救赐,卻和暖如春涧团,著一層夾襖步出監(jiān)牢的瞬間净响,已是汗流浹背少欺。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留馋贤,地道東北人赞别。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像配乓,于是被迫代替她去往敵國和親仿滔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容