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

C++結(jié)構(gòu)體字節(jié)對齊和共用體大小

 更新時間:2021年11月12日 09:53:06   作者:學(xué)渣的C/C++  
這篇文章主要介紹了C++結(jié)構(gòu)體字節(jié)對齊和共用體大小,結(jié)構(gòu)體內(nèi)存對齊在筆試和面試中經(jīng)常被問到,所以這篇文章做個總結(jié),首先通過代碼驗證不同結(jié)構(gòu)體的內(nèi)存大小,需要的朋友可以參考下

1、結(jié)構(gòu)體內(nèi)存對齊

結(jié)構(gòu)體內(nèi)存對齊在筆試和面試中經(jīng)常被問到,所以做個總結(jié)

通過代碼驗證不同結(jié)構(gòu)體的內(nèi)存大小:

#include <stdio.h>
struct Node1{
    char c1;
    int val1;
    char c2;
};
struct Node2{
    char c1;
    char c2;
    int val1;
};
struct Node3{
    char c1;
    char array[10];
};
struct Node4{
    char val1;
    int arrar[10];
};
int main(){
    printf("Node1 size = %d\n",sizeof(struct Node1));
    printf("Node2 size = %d\n",sizeof(struct Node2));
    printf("Node3 size = %d\n",sizeof(struct Node3));
    printf("Node4 size = %d\n",sizeof(struct Node4));

    return 0;
}

代碼運行結(jié)果為:

通過上述代碼運行結(jié)果可以發(fā)現(xiàn)Node1Node2定義了相同個數(shù)的變量,但是Node1的大小為12,Node2的大小為8,這是為什么呢?

這里首先明確兩個概念:對齊數(shù)和最大對齊數(shù),在結(jié)構(gòu)體中對齊數(shù)就是每個成員類型的大小,如Node1中,對齊數(shù)為{1,4,1},在數(shù)組中,對齊數(shù)不是數(shù)組的大小,而是數(shù)組成員的大小,所以Node3的對齊數(shù)為{1,1},Node4的對齊數(shù)為{1,4}。最大對齊數(shù)是對齊數(shù)中的最大值(gcc編譯器),最大對齊數(shù)可能受編譯器的影響,通常編譯器會有編譯器對齊數(shù),最大對齊數(shù)應(yīng)該是編譯器對齊數(shù)和結(jié)構(gòu)體最大對齊數(shù)中較小值,如VS編譯器對齊數(shù)為8,如果結(jié)構(gòu)體的最大對齊數(shù)為16,那么計算結(jié)構(gòu)體的最大對齊數(shù)應(yīng)該為8。我的編譯器為gcc,所以最大對齊數(shù)為結(jié)構(gòu)體對齊數(shù)中的最大值。

知道最大對齊數(shù)后,就可以計算結(jié)構(gòu)體的大小了,需要明確結(jié)構(gòu)體的大小一定是最大對齊數(shù)的整數(shù)倍。那么Node1和Node2的成員類型是一樣的,為什么Node1的大小為12字節(jié),Node2的大小為8字節(jié)呢。這是因為結(jié)構(gòu)體內(nèi)存的連續(xù)性,在存儲容量沒有到最大對齊數(shù)的內(nèi)存大小時,只要能夠保存這個成員,結(jié)構(gòu)體就會將該成員變量保存在一個最大對齊樹的內(nèi)存空間內(nèi)。這樣就避免了內(nèi)存的過度浪費。

所以,上述各結(jié)構(gòu)體的內(nèi)存大小計算方式如下:

  • sizeof(Node1)= 1 + 3(浪費)+ 4 + 1 + 3(浪費) = 12
  • sizeof(Node2)= 1 + 1 + 2(浪費)+ 4 = 8
  • sizeof(Node3) = 1 + 1 * 10 = 11
  • sizeof(Node4) = 1 + 3(浪費)+ 4 * 10 = 44

那么結(jié)構(gòu)體嵌套結(jié)構(gòu)體的大小應(yīng)該怎么計算呢?舉以下例子:

#include <stdio.h>
struct Node1{
    char c1;
    int val1;
    char c2;
};
struct Node2{
    char c1;
    struct Node1 node;
    double val1;
};

int main(){
    printf("Node1 size = %d\n",sizeof(struct Node1));
    printf("Node2 size = %d\n",sizeof(struct Node2));
    return 0;
}

代碼運行的結(jié)果為:

 可以明確,嵌套結(jié)構(gòu)體的對齊數(shù)為所嵌套結(jié)構(gòu)體的最大對齊數(shù),所以Node1的對齊數(shù)為{1,4,1},Node2的對齊數(shù)為{1,4,8},最大對齊數(shù)分別為4和8,則代碼里兩個結(jié)構(gòu)體的大小計算方式為:

  • sizeof(Node1)= 1 + 3(浪費)+ 4 + 1 + 3(浪費) = 12
  • sizeof(Node2)= 1 + 7(浪費)+ 12 + 4(浪費)+ 8 = 24

2、共用體的內(nèi)存大小

對于以下共用體,讀取它大小的代碼如下:

#include <stdio.h>

union un1{
    int val;
    char c;
    double d;
};
union un2{
    int val;
    char array[5];
};

int main(){
    printf("un1 size = %d\n",sizeof(union un1));
    printf("un2 size = %d\n",sizeof(union un2));
    return 0;
}

代碼運行結(jié)果為:

 共用體之所以叫共用體,就是因為它的成員變量共享內(nèi)存,既然共享內(nèi)存,那么共用體占用的內(nèi)存空間一定要可以保存內(nèi)存最大的成員類型,而un1的最大內(nèi)存成員為double型,大小為8字節(jié),所以un1的大小為8字節(jié),那么un2的內(nèi)存大小為什么不是5呢?這是因為要內(nèi)存對齊,共用體也遵循內(nèi)存對齊原則,un2的最大對齊數(shù)是4,因此un2的大小應(yīng)該是4的整數(shù)倍數(shù),所以,sizeof(un2)= 8.

3、枚舉的大小

這里順帶提一下枚舉的內(nèi)存大小,代碼驗證如下:

#include <stdio.h>

enum Colour {
    RED,
    GREEN,
    BLUE
};
enum ProgramLanguage {
    python = 0xffffffffff,
    c = 8,
    java
};

int main()
{
    printf("Colour size = %d\n",sizeof(enum Colour));
    printf("ProgramLanguage size = %d\n",sizeof(enum ProgramLanguage));
    return 0;
}

代碼運行結(jié)果為:

 可見枚舉類型的大小是編譯器根據(jù)定義的值自行給定的,實際使用中很少會超出4字節(jié)大小。

到此這篇關(guān)于C++結(jié)構(gòu)體字節(jié)對齊和共用體大小的文章就介紹到這了,更多相關(guān)結(jié)構(gòu)體字節(jié)對齊和共用體大小內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++簡單實現(xiàn)Dijkstra算法

    C++簡單實現(xiàn)Dijkstra算法

    這篇文章主要為大家詳細介紹了C++簡單實現(xiàn)Dijkstra算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • 詳解C語言數(shù)據(jù)結(jié)構(gòu)之棧

    詳解C語言數(shù)據(jù)結(jié)構(gòu)之棧

    這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)之棧,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • c++回調(diào)之利用函數(shù)指針示例

    c++回調(diào)之利用函數(shù)指針示例

    這篇文章主要介紹了c++利用函數(shù)指針示例,需要的朋友可以參考下
    2014-04-04
  • Pthread?并發(fā)編程線程自底向上深入解析

    Pthread?并發(fā)編程線程自底向上深入解析

    這篇文章主要為大家介紹了Pthread?并發(fā)編程線程自底向上深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • c++ 類中const成員變量的賦值方法

    c++ 類中const成員變量的賦值方法

    下面小編就為大家?guī)硪黄猚++ 類中const成員變量的賦值方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • Qt控件之QToolButton的使用及示例

    Qt控件之QToolButton的使用及示例

    QToolButton類提供了一個快速訪問命令或選項的按鈕,通常在QToolBar內(nèi)部使用,本文主要介紹了Qt控件之QToolButton的使用及示例,感興趣的可以了解一下
    2023-10-10
  • C中的volatile使用方法

    C中的volatile使用方法

    volatile 影響編譯器編譯的結(jié)果,指出,volatile 變量是隨時可能發(fā)生變化的,與volatile變量有關(guān)的運算,不要進行編譯優(yōu)化,以免出錯
    2013-02-02
  • Opencv基于文字檢測去圖片水印的實現(xiàn)示例

    Opencv基于文字檢測去圖片水印的實現(xiàn)示例

    去水印是個麻煩事,本文就來介紹一種方法Opencv基于文字檢測去圖片水印的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • C程序中唯一序列號的生成實例詳解

    C程序中唯一序列號的生成實例詳解

    這篇文章主要介紹了C程序中唯一序列號的生成實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • VScode搭建OpenCV環(huán)境的詳細步驟

    VScode搭建OpenCV環(huán)境的詳細步驟

    用vscode來寫opencv代碼需要自己編譯OpenCV,主要用到MinGW-w64和CMake工具。接下來通過本文給大家介紹VScode搭建OpenCV環(huán)境的相關(guān)知識,需要的朋友可以參考下
    2021-11-11

最新評論

三门县| 扶风县| 宁波市| 京山县| 长岭县| 吉林市| 万州区| 新和县| 扎赉特旗| 宜良县| 庆安县| 武冈市| 宜州市| 湟中县| 精河县| 洛川县| 吴旗县| 钟祥市| 阜新市| 三河市| 黑山县| 松桃| 黄大仙区| 军事| 富川| 华亭县| 马龙县| 连城县| 秦皇岛市| 邢台县| 镇远县| 新乡市| 晋城| 绵竹市| 连城县| 贵阳市| 双鸭山市| 方山县| 郁南县| 长治市| 天峨县|