色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

解析C語言結(jié)構(gòu)體字節(jié)如何對齊

電子工程師 ? 來源:編程學(xué)習(xí)總站 ? 作者:寫代碼的牛頓 ? 2021-06-12 17:42 ? 次閱讀

01

默認(rèn)字節(jié)對齊

C語言結(jié)構(gòu)體字節(jié)對齊是老生常談的問題了,也是高頻面試題,現(xiàn)在我們來深入研究這個問題,徹底弄懂到底是怎么回事,給你一個結(jié)構(gòu)體定義和平臺機(jī)器位數(shù)就能手動計算出結(jié)構(gòu)體占用字節(jié)數(shù),現(xiàn)在我們不使用宏#pragma pack,采用默認(rèn)字節(jié)對齊方式。

先拋出結(jié)論:

在一個結(jié)構(gòu)體中第一個成員變量放在偏移為0的位置,以后的變量都存儲在該變量占用字節(jié)數(shù)整數(shù)倍的地址上。

結(jié)構(gòu)體總大小,必須是內(nèi)部最大成員變量的整數(shù)倍,不足的補(bǔ)齊。

好了,現(xiàn)在我們直接寫個小程序驗證并分析是否真是這樣一回事。

struct st{ short a1; short a2; short a3; }; struct st2{ long a1; short a2; };

這里我們定義了兩個很簡單的結(jié)構(gòu)體,short占用2個字節(jié),struct st我們一眼就知道大小了6個字節(jié),但是struct st2呢?筆者電腦是64位,那么long占用8個字節(jié),short占用2個字節(jié)。我們先來按照結(jié)論進(jìn)行分析,在struct st2中成員變量a1在偏移0處存儲且占用8個字節(jié),成員變量a2占用2個字節(jié),由于8是2的倍數(shù),所以a2在偏移8的位置存儲,又因為有結(jié)論2。

我們根據(jù)結(jié)論2可以得出,struct st2必須占用8的倍數(shù)大小,所以struct st2總大小是16個字節(jié),不足的后面補(bǔ)齊。現(xiàn)在我分別打印出struct st1和struct st2占用字節(jié)數(shù)大小和struct st2各個成員變量地址,觀察是否和分析的一樣。

int main() { struct st2 st_val2; printf(“sizeof(long) = %d ”, sizeof(long)); printf(“sizeof(struct st) = %d ”, sizeof(struct st)); printf(“sizeof(struct st2) = %d ”, sizeof(struct st2)); printf(“st_val2 addr = %p ”, &st_val2); printf(“st_val2 a1 addr = %p ”, &st_val2.a1); printf(“st_val2 a2 addr = %p ”, &st_val2.a2); return 0; }

編譯運(yùn)行輸出:

sizeof(long) = 8 sizeof(struct st) = 6 sizeof(struct st2) = 16 st_val2 addr = 0x7ffee107f3b8 st_val2 a1 addr = 0x7ffee107f3b8 st_val2 a2 addr = 0x7ffee107f3c0

現(xiàn)在我們看一下輸出結(jié)果,struct st如我們所愿占用6個字節(jié)大小,struct st2也按照我們分析的一樣占用16個字節(jié)。我們在程序中定義了一個struct st2類型變量st_val2,從輸出中可以看出變量st_val2的a1成員變量和st_val2變量地址一樣,成員變量a2在偏移8處存儲(0x c0 = 0xb8 + 8)。一切如我們所愿,看起來好像挺簡單的,我們知道C語言有豐富的數(shù)據(jù)類型,下面我們再定義一個更復(fù)雜的結(jié)構(gòu)體。

struct st3{ int a1; char a2; short a3; long a4; char a5; };

這個結(jié)構(gòu)體包含了大量數(shù)據(jù)類型成員變量,再復(fù)雜的結(jié)構(gòu)體也能按照我們的結(jié)論分析到底占用了幾個字節(jié)。

在struct st3中int型成員變量a1占用4個字節(jié),在偏移0處存儲,char型成員變量a2占用2個字節(jié)那么應(yīng)該放在2的倍數(shù)地址處存儲,a1已經(jīng)占用了4個字節(jié),所以a2應(yīng)該在偏移4的地址存儲。

short型成員變量a3占用2個字節(jié),也應(yīng)該放在2的倍數(shù)地址處存儲,所以a3在偏移6的地址處存儲,a2后面填充1個字節(jié)。

long型成員變量a4占用8個字節(jié),應(yīng)該放在8的倍數(shù)地址上存儲,前面我們已經(jīng)知道a3在偏移6的地址處存儲,且占用2個字節(jié)8 = 6 + 2,所以a4應(yīng)該在偏移8的地址處存儲。

最后一個char型成員變量a5占用一個字節(jié),那么a5在偏移16地址處存儲。

現(xiàn)在我們計算一下struct st3結(jié)構(gòu)體占用空間大小,從a5偏移出計算16 + 1 = 17。在struct st3中最大成員變量占用8個字節(jié),所以結(jié)構(gòu)體總大小應(yīng)該是8的倍數(shù),最后結(jié)構(gòu)體總大小是17 + 7 = 24,這里的7個字節(jié)在最后補(bǔ)齊。

我們依舊寫一個小程序輸出struct st3類型變量各個成員變量地址和結(jié)構(gòu)體總大小。

int main() { struct st3 st_val3; printf(“sizeof(struct st3) = %d ”, sizeof(struct st3)); printf(“st_val3 addr = %p ”, &st_val3); printf(“st_val3.a1 addr = %p ”, &st_val3.a1); printf(“st_val3.a2 addr = %p ”, &st_val3.a2); printf(“st_val3.a3 addr = %p ”, &st_val3.a3); printf(“st_val3.a4 addr = %p ”, &st_val3.a4); printf(“st_val3.a5 addr = %p ”, &st_val3.a5); return 0; }

編譯運(yùn)行輸出:

sizeof(struct st3) = 24 st_val3 addr = 0x7ffeed0c33b0 st_val3.a1 addr = 0x7ffeed0c33b0 st_val3.a2 addr = 0x7ffeed0c33b4 st_val3.a3 addr = 0x7ffeed0c33b6 st_val3.a4 addr = 0x7ffeed0c33b8 st_val3.a5 addr = 0x7ffeed0c33c0

從輸出我們可以看出,和我們分析的完全一樣。

枚舉類型變量和聯(lián)合體類型變量都可以作為結(jié)構(gòu)體的成員變量,在分析這些結(jié)構(gòu)體占用大小時,分析方法和我們上面的一模一樣,只需要把內(nèi)部任何一種數(shù)據(jù)類型變量當(dāng)做一個普通變量看待即可,但是結(jié)構(gòu)體類型成員變量有點(diǎn)不一樣,它不適用于結(jié)論2,我們舉個例子。

struct st4{ char a1[3]; int a2; long a3; struct st3 a4; };

在struct st4中我們定義了一個struct st3類型成員變量,前面我們已經(jīng)分析過了struct st3占用24個字節(jié)。成員變量a1占用3個字節(jié),成員變量a2占用4個字節(jié),所以a2存儲在偏移4的地址上,在a1后面填充一個字節(jié)。成員變量a3占用8個字節(jié),則a3存儲在偏移8的地址上。那么結(jié)構(gòu)體總共占用字節(jié)數(shù)大小是:8 + 8 + 24 = 40。

最后我們寫一個程序驗證一下是否如此。

int main() { struct st4 st_val4; printf(“sizeof(struct st4) = %d ”, sizeof(struct st4)); printf(“st4 addr = %p ”, &st_val4); printf(“st_val4.a1 addr = %p ”, &st_val4.a1); printf(“st_val4.a2 addr = %p ”, &st_val4.a2); printf(“st_val4.a3 addr = %p ”, &st_val4.a3); printf(“st_val4.a4 addr = %p ”, &st_val4.a4); return 0; }

編譯運(yùn)行輸出:

sizeof(struct st4) = 40 st4 addr = 0x7ffeec1263a0 st_val4.a1 addr = 0x7ffeec1263a0 st_val4.a2 addr = 0x7ffeec1263a4 st_val4.a3 addr = 0x7ffeec1263a8 st_val4.a4 addr = 0x7ffeec1263b0

和我們分析的一模一樣。

02

#pragma pack宏的作用

我們看一下下面這段代碼。

#pagma pack(1)int main() { struct st3 st_val3; printf(“sizeof(struct st3) = %d ”, sizeof(struct st3)); printf(“st_val3 addr = %p ”, &st_val3); printf(“st_val3.a1 addr = %p ”, &st_val3.a1); printf(“st_val3.a2 addr = %p ”, &st_val3.a2); printf(“st_val3.a3 addr = %p ”, &st_val3.a3); printf(“st_val3.a4 addr = %p ”, &st_val3.a4); printf(“st_val3.a5 addr = %p ”, &st_val3.a5); return 0; }

這段代碼里我們使用了#pagma pack宏,表示結(jié)構(gòu)體按1字節(jié)對齊。也就是說結(jié)構(gòu)體變量st_val3總大小是內(nèi)部成員變量占用字節(jié)數(shù)總和,沒有字節(jié)填充。

現(xiàn)在編譯運(yùn)行如下:

sizeof(struct st3) = 16 st_val3 addr = 0x7ffee13a93b8 st_val3.a1 addr = 0x7ffee13a93b8 st_val3.a2 addr = 0x7ffee13a93bc st_val3.a3 addr = 0x7ffee13a93bd st_val3.a4 addr = 0x7ffee13a93bf st_val3.a5 addr = 0x7ffee13a93c7

在struct st3中int型a1占用4字節(jié),char型變量a2占用1個字節(jié),short型變量a3占用2個字節(jié),long型變量a4占用8個字節(jié),char型變量a5占用1個字節(jié),所以總大小是:4 + 1 + 2 + 8 + 1 = 16。如果是#pagma pack(2)呢?相信你可以自己計算了。

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7614

    瀏覽量

    137422
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4823

    瀏覽量

    68894

原文標(biāo)題:C語言結(jié)構(gòu)體字節(jié)對齊

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    結(jié)構(gòu)成員的順序會影響結(jié)構(gòu)的大小嗎

    相同的結(jié)構(gòu)成員,如果把順序調(diào)整一下,會不會影響結(jié)構(gòu)的大小? 答案是會的,這主要跟字節(jié)對齊有關(guān)
    的頭像 發(fā)表于 11-25 16:24 ?253次閱讀

    C語言C++中結(jié)構(gòu)的區(qū)別

    同樣是結(jié)構(gòu),看看在C語言C++中有什么區(qū)別?
    的頭像 發(fā)表于 10-30 15:11 ?333次閱讀

    字節(jié)豆包推出AI智能耳機(jī)

    字節(jié)跳動旗下豆包品牌近日推出了其首款A(yù)I智能耳機(jī)——Ola Friend。這款耳機(jī)采用了開放式設(shè)計,單耳重量僅為6.6克,佩戴舒適輕盈。
    的頭像 發(fā)表于 10-10 16:55 ?597次閱讀

    技術(shù)干貨驛站 ▏深入理解C語言:編程高手必備,全方位解析運(yùn)算符的核心技能!

    C語言的編程領(lǐng)域中,運(yùn)算符是實(shí)現(xiàn)數(shù)據(jù)處理與邏輯操作的關(guān)鍵工具。無論是在處理簡單的數(shù)值計算,還是在構(gòu)建復(fù)雜的邏輯結(jié)構(gòu)時,運(yùn)算符的使用貫穿始終。作為編程語言的基礎(chǔ)組成部分之一,運(yùn)算符不僅
    的頭像 發(fā)表于 09-18 15:56 ?391次閱讀
    技術(shù)干貨驛站 ▏深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:編程高手必備,全方位<b class='flag-5'>解析</b>運(yùn)算符的核心技能!

    技術(shù)干貨驛站 ▏深入理解C語言:掌握程序結(jié)構(gòu)知識

    在計算機(jī)編程的世界中,C語言被廣泛認(rèn)可為一門強(qiáng)大而高效的編程語言,其簡潔的語法和直接的指令使得它成為了許多程序員的首選。了解C語言的程序
    的頭像 發(fā)表于 07-27 08:45 ?1508次閱讀
    技術(shù)干貨驛站 ▏深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:掌握程序<b class='flag-5'>結(jié)構(gòu)</b>知識

    你是否真的了解結(jié)構(gòu)占用了多少字節(jié)

    結(jié)構(gòu)成員所占內(nèi)存空間大小一般情況下,如果想知道結(jié)構(gòu)成員的內(nèi)存占用情況需要:1、先用結(jié)構(gòu)在內(nèi)
    的頭像 發(fā)表于 06-04 08:04 ?552次閱讀
    你是否真的了解<b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>占用了多少<b class='flag-5'>字節(jié)</b>?

    嵌入式中C語言結(jié)構(gòu)基本實(shí)現(xiàn)

    C語言中的數(shù)組只能允許程序員定義存儲相同類型數(shù)據(jù)。但是結(jié)構(gòu)C語言編程中允許您存儲不同數(shù)據(jù)類型的數(shù)據(jù)。
    的頭像 發(fā)表于 05-11 08:49 ?1109次閱讀
    嵌入式中<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>基本實(shí)現(xiàn)

    用FreeRTOS使用隊列怎么發(fā)送一個結(jié)構(gòu)呢?

    怎么使用隊列,發(fā)送一個12個字節(jié)結(jié)構(gòu)呢? osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec
    發(fā)表于 04-17 07:35

    求助,關(guān)于STM32H7的Cache無效化操作32字節(jié)對齊問題求解

    core_cm7.h更新到5.1.1版本后,發(fā)現(xiàn)該函數(shù)對dsize做了32字節(jié)對齊,但是op_addr地址32字節(jié)對齊卻注釋掉了?,圖片的這句話是不是說SCB-&gt
    發(fā)表于 03-29 06:51

    C語言結(jié)構(gòu)史上最詳細(xì)的講解【軟件干貨】

    struct結(jié)構(gòu)數(shù)據(jù)類型 前言 我們知道,在C語言中有一些基本的數(shù)據(jù)類型,如?char?int?float?long?double?string(
    的頭像 發(fā)表于 03-28 17:52 ?829次閱讀

    嵌入式系統(tǒng)中C語言結(jié)構(gòu)的基礎(chǔ)實(shí)現(xiàn)與應(yīng)用

    C語言中的數(shù)組只能允許程序員定義存儲相同類型數(shù)據(jù)。但是結(jié)構(gòu)C語言編程中允許您存儲不同數(shù)據(jù)類型的數(shù)據(jù)。
    發(fā)表于 03-12 14:29 ?543次閱讀
    嵌入式系統(tǒng)中<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>體</b>的基礎(chǔ)實(shí)現(xiàn)與應(yīng)用

    C語言中的typedef的應(yīng)用

    C 語言提供了 typedef 關(guān)鍵字,您可以使用它來為類型取一個新的名字。下面的實(shí)例為單字節(jié)數(shù)字定義了一個術(shù)語 BYTE。
    發(fā)表于 03-06 11:34 ?426次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>中的typedef的應(yīng)用

    ArkTS語言基礎(chǔ)類庫-解析

    被設(shè)計用來傳輸和存儲數(shù)據(jù),是一種可擴(kuò)展標(biāo)記語言語言基礎(chǔ)類庫提供了[XML生成、解析與轉(zhuǎn)換]的能力。 URL、URI構(gòu)造和解析能力:其中[URI]是統(tǒng)一資源標(biāo)識符,可以唯一標(biāo)識一個資源
    發(fā)表于 02-20 16:44

    plc編程語言c語言的聯(lián)系 c語言和PLC有什么區(qū)別

    語言,主要用于開發(fā)各種應(yīng)用程序。盡管PLC編程語言C語言有一些相似之處,但它們之間也存在一些明顯的區(qū)別。 首先,PLC編程語言
    的頭像 發(fā)表于 02-05 14:21 ?4341次閱讀

    c語言,c++,java,python區(qū)別

    C語言C++、Java和Python是四種常見的編程語言,各有優(yōu)點(diǎn)和特點(diǎn)。 C語言
    的頭像 發(fā)表于 02-05 14:11 ?2542次閱讀
    主站蜘蛛池模板: 动漫美女性侵 | 欧美人与善交大片 | 果冻传媒在线播放 | 538prom精品视频我们不只是 | 厕所RXXX | 无码国产成人777爽死在线观看 | 美女pk精子4| 国内精品久久人妻无码HD浪潮 | 欧美自拍亚洲综合图区 | 中文字幕人成人乱码亚洲影视S | 老师湿乎乎两半嫩 | 妙玉被肉干高H潮文 | 欧美丰满熟妇无码XOXOXO | 麻豆精选2021 | 99久久香蕉 | 国产盗摄一区二区 | 妓女嫖客叫床粗话对白 | 诱受H嗯啊巨肉舍友1V1 | 国产高清视频免费在线观看 | 国产亚洲精品免费视频 | 挺进绝色老师的紧窄小肉六 | 亚洲精品天堂无码中文字幕影院 | 被窝伦理电影午夜 | 99视频精品全部免费 在线 | 亚洲国产AV精品卡一卡二 | 精品国内自产拍在线观看视频 | 亚洲视频在线观看地址 | 日日做夜夜欢狠狠免费软件 | GOGOGO高清在线播放免费 | 国产人妻麻豆蜜桃色69 | 动漫成年美女黄漫网站 | 国产AV精品久久久毛片 | 在线观看永久免费网站 | 怡春院院日本一区二区久久 | 国产精品69人妻无码久久 | 国产亚洲精品久久久久久久 | 一级做a爰片久久毛片苍井优 | 超嫩校花被灌醉在线观看 | 外国xxxx| 羞羞答答dc视频 | 单亲妈妈3韩国电影免费观看 |