最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言熱門考點結構體與內(nèi)存對齊詳解

 更新時間:2021年10月22日 15:54:41   作者:高郵吳少  
在掌握基本的結構體使用后,我們在面試和大型比賽中常常會遇到一個熱門考點:結構體內(nèi)存對齊,也就是計算結構體大小。接下來請跟著筆者一起來學習這塊知識點吧

一、引例

到底什么是結構體內(nèi)存對齊,我們用一段代碼來介紹一下

struct S1
{
	char c1;//1字節(jié)
	int a;//4字節(jié)
	char c2;//1字節(jié)
};
int main()
{
	printf("%d\n", sizeof(struct S1));
	//這里打印12
}

先來解釋S1,結構體S1中有2個char類型,1個int類型。那按道理應該是占2*1+4=6個字節(jié)啊,為什么打印的是12呢?到這里,我們必須要來了解一下結構體內(nèi)存對齊的規(guī)則:

1.結構體的第一個成員永遠放在結構體起始位置偏移量為0的位置

對于偏移量你可以這樣理解:數(shù)組下標為0的相對它自己偏移量為0,下標為1的相對下標為0的偏移量為1…
舉例說明:

在這里插入圖片描述

S1第一個成員是c1,它會被放在結構體起始位置偏移量為0的位置,如下圖紅色部分

在這里插入圖片描述

2.從第二個成員開始,總是放在偏移量為一個對齊數(shù)的整數(shù)處,對齊數(shù)=編譯器默認的對齊數(shù)和變量自身大小的較小值

對齊數(shù)=min(編譯器默認的對齊數(shù),變量自身大小)
Linux-沒有對齊數(shù),VS下對齊數(shù)默認為8

我們?nèi)砸許1這個結構體進行舉例,結構體第二個成員是int類型的a,占4個字節(jié),筆者VS環(huán)境下默認對齊數(shù)是8,取兩者較小值是4,那a應該放到偏移量為4的倍數(shù)上

在這里插入圖片描述

放到4的倍數(shù)上也就說可以放在偏移量為4這里,偏移量為1,2,3的這3個空間就白白被浪費了。而a是int型占4個字節(jié),所以會一直占用到偏移量為7的位置。

接下來是結構體的第三個成員,char類型的c2,c2占1個字節(jié),VS環(huán)境下默認對齊數(shù)是8,取較小值為1,也就是說只要是1的倍數(shù)的偏移量都可以放,我們緊接著放在a后面,也就是偏移量8的位置

在這里插入圖片描述

那到這里結構體3個成員都用完了啊,只有8個啊,為什么打印是12呢?這里就要涉及結構體內(nèi)存對齊的第3個規(guī)則

3.結構體的總大小必須是各個成員的對齊數(shù)中最大的那個對齊數(shù)的整數(shù)倍

我們由前面講解知道結構體三個成員c1,a,c2對齊數(shù)分別為1,4,1這三個中最大對齊數(shù)是4,總大小要為4的整數(shù)倍,那這時候肯定有小伙伴會問:我們現(xiàn)在不是對齊到8了嘛,8不是4的倍數(shù)嗎?注意!這里說的是空間總大小,而8是所謂的偏移量,偏移量是從0開始算的,到8已經(jīng)有9個空間了,所以我們這里空間要到12,也就是偏移量到11

在這里插入圖片描述

(后面加上的三個空間用不到,但是由于規(guī)定還是算在結構體總空間內(nèi))

二、小試牛刀

我們再來看一道類似的題目

代碼如下(示例):

struct S2
{
	char c1;//1字節(jié)
	char c2;//1字節(jié)
	int a;//4字節(jié)
};
int main()
{
	printf("%d\n", sizeof(struct S2));
	//這里打印8
}

首先第一個結構體成員是char類型的c1,由規(guī)則1,它會直接被放在偏移量為0的位置
(圖示灰色部分)

在這里插入圖片描述

第二個成員是char類型的c2,占1字節(jié),VS下默認對齊數(shù)是8,取較小值是1,只要放在偏移量為1的倍數(shù)上即可(任意位置),緊跟著0,放在偏移量為1處(圖示紅色部分)

在這里插入圖片描述

最后一個成員int類型的a,占4個字節(jié),VS環(huán)境下默認對齊數(shù)是8,取較小者4,放在偏移量為4的整數(shù)倍處,也就是4這里,然后由于int占4個字節(jié)所以一直占用到偏移量7處

在這里插入圖片描述

再來看看規(guī)則3,結構體的總大小必須是各個成員的對齊數(shù)中最大的那個對齊數(shù)的整數(shù)倍,也就是4的倍數(shù),我們現(xiàn)在正好是占8個空間,8正好是4的倍數(shù),所以就不用再往下浪費空間了,打印出8

三、嵌套結構體的特殊情況

代碼如下(示例):

struct S3
{
	double d;//double占8字節(jié),默認對齊數(shù)8,取較小值,對齊數(shù)8
	char c;//對齊數(shù)1
	int i;//對齊數(shù)4
};
struct S4
{
	char c1;
	struct S3 s3;
	double d;
};
int main()
{
	printf("%d\n", sizeof(struct S4));
}

關于結構體S3我們可以采用和前面S1、S2一樣的方法計算出來是占16個字節(jié)空間,我們這里重點討論S4,對S3有興趣的小伙伴可自行求解。

S4中的第一個成員c1,按規(guī)則1直接放在偏移量為0處,第二個成員s3怎么辦呢?這里涉及結構體內(nèi)存對齊的第四個規(guī)則:

如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數(shù)的整數(shù)倍數(shù)處,結構體的整體大小就是所有最大對齊數(shù)(含嵌套結構體的對齊數(shù))的整數(shù)倍

s3這個結構體三個成員最大對齊數(shù)是8,也就是要對齊到偏移量為8的倍數(shù)處,然后s3是占16個字節(jié),所以一直占到偏移量23處(s3結構體對齊數(shù)是本身s3結構體三個成員中最大對齊數(shù))

ps:在VS環(huán)境中,嵌套結構體的最大對齊數(shù)超過8,仍然用8做最大對齊數(shù)(比默認對齊數(shù)大了,取較小值就取默認對齊數(shù)了)

在這里插入圖片描述

S4最后一個成員double類型的d占8字節(jié),默認對齊數(shù)8,對齊數(shù)取8,然后放在偏移量為對齊數(shù)的整數(shù)倍處,正好往下放在24處,本身占8字節(jié)所以占到31

在這里插入圖片描述

偏移量0-31共占32字節(jié),S4中的成員c1,s3,d對齊數(shù)分別為1,8,8所以最大對齊數(shù)是8,32恰是8的倍數(shù),所以這里不用再浪費空間來滿足 “結構體的總大小必須是各個成員的對齊數(shù)中最大的那個對齊數(shù)的整數(shù)倍”這個規(guī)則,結構體總大小就是32

四、關于為什么存在內(nèi)存對齊

1.平臺原因(移植原因):

不是所有的硬件平臺都能訪問任意地址上的任意數(shù)據(jù)的;某些硬件平臺只能在某些地址處取某些特定的類型的數(shù)據(jù),否則拋出硬件異常

2.性能原因:

數(shù)據(jù)結構(尤其是棧),應盡可能地在自然邊界上對齊。原因在于,為了訪問未對齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問;而對齊的內(nèi)存訪問僅僅需要1次
總體來說:結構體的內(nèi)存對齊是用空間換時間

總結

本文介紹了結構體內(nèi)存對齊的四大規(guī)則,并舉例說明了如何進行方法的操作,對于其中特殊的嵌套結構體內(nèi)存對齊也進行了相應講解,希望讀者在學習完本文后能對結構體內(nèi)存對齊有一個系統(tǒng)的認識。祝讀者學業(yè)有成!

更多關于C語言結構體與內(nèi)存對齊的資料請關注腳本之家其它相關文章!

相關文章

  • OpenCV圖像旋轉Rotate的詳細介紹

    OpenCV圖像旋轉Rotate的詳細介紹

    這篇文章主要介紹了OpenCV圖像旋轉Rotate,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • c++中string類型和int類型相互轉換的幾種常用方法

    c++中string類型和int類型相互轉換的幾種常用方法

    我們在編寫程序時,經(jīng)常涉及到int與string之間的類型轉換,本文主要介紹了c++中string類型和int類型相互轉換的幾種常用方法,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • C++實現(xiàn)井字棋游戲

    C++實現(xiàn)井字棋游戲

    這篇文章主要為大家詳細介紹了C++實現(xiàn)井字棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Qt編寫地圖綜合應用之繪制雨量分布

    Qt編寫地圖綜合應用之繪制雨量分布

    雨量分布圖是在區(qū)域地圖基礎上,針對區(qū)域中的每個最小單位區(qū)域比如縣城點位不同顏色顯示。本文將詳細為大家介紹如何通過QT編寫繪制雨量分布,感興趣的小伙伴可以了解一下
    2021-12-12
  • 雙向鏈表插入刪除基本應用介紹

    雙向鏈表插入刪除基本應用介紹

    本文將詳細介紹建立雙向鏈表,實現(xiàn)對雙向鏈表的插入,刪除操作,需要了解的朋友可以參考下
    2012-11-11
  • C++在vscode中的多文件編程問題解讀

    C++在vscode中的多文件編程問題解讀

    這篇文章主要介紹了C++在vscode中的多文件編程問題解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 深入解析C++ Data Member內(nèi)存布局

    深入解析C++ Data Member內(nèi)存布局

    本篇文章是對C++中的Data Member內(nèi)存布局進行了詳細的分析介紹,需要的朋友參考下
    2013-07-07
  • VC++中HTControl的CHTButton按鈕控件類用法實例解析

    VC++中HTControl的CHTButton按鈕控件類用法實例解析

    這篇文章主要介紹了VC++中HTControl的CHTButton按鈕控件類用法,對于大家進行VC++項目開發(fā)有一定的幫助作用,需要的朋友可以參考下
    2014-08-08
  • MFC繪制不規(guī)則窗體的方法

    MFC繪制不規(guī)則窗體的方法

    這篇文章主要介紹了MFC繪制不規(guī)則窗體的方法,涉及MFC窗體操作的相關技巧,需要的朋友可以參考下
    2015-05-05
  • C++類模板以及保存數(shù)據(jù)到文件方式

    C++類模板以及保存數(shù)據(jù)到文件方式

    這篇文章主要介紹了C++類模板以及保存數(shù)據(jù)到文件方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評論

收藏| 浦江县| 柘荣县| 南阳市| 四会市| 揭西县| 醴陵市| 读书| 蛟河市| 临武县| 且末县| 嘉祥县| 类乌齐县| 大田县| 米易县| 宜君县| 彝良县| 彭阳县| 高清| 宁武县| 江都市| 化隆| 马鞍山市| 柳林县| 蚌埠市| 鹤壁市| 凯里市| 榆中县| 宝清县| 和顺县| 赤水市| 逊克县| 梧州市| 潼关县| 惠水县| 清远市| 辽中县| 成都市| 永济市| 西充县| 长宁区|