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

詳解C語(yǔ)言結(jié)構(gòu)體,枚舉,聯(lián)合體的使用

 更新時(shí)間:2022年07月15日 10:08:33   作者:蔣靈瑜的流水賬  
這篇文章主要給大家介紹一下關(guān)于C語(yǔ)言中結(jié)構(gòu)體、枚舉、聯(lián)合體的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考一下

一、匿名結(jié)構(gòu)體

struct
{
    char name[20];
    int age;
}s1;

匿名結(jié)構(gòu)體對(duì)象s1過(guò)了這一行即銷(xiāo)毀。

二、結(jié)構(gòu)體的自引用

1、聲明時(shí)不要自己引用自己

struct Node
{
 int data;
 struct Node next;//錯(cuò)誤的,嚴(yán)禁自己引用自己
};
 
 
struct Node
{
 int data;
 struct Node* next;//正確的引用方式
};

2、結(jié)構(gòu)體重命名時(shí)不能使用重命名

typedef struct
{
 int data;
 Node* next;//錯(cuò)誤的,不要再重命名中使用重命名
}Node;
 
typedef struct Node
{
 int data;
 struct Node* next;//正確的
}Node;

博主在學(xué)數(shù)據(jù)結(jié)構(gòu)的時(shí)候踩過(guò)這個(gè)坑,在結(jié)構(gòu)體重命名的時(shí)候成員變量的類型就使用了重命名,導(dǎo)致整個(gè)程序不認(rèn)識(shí)這個(gè)成員變量的類型(但是vs在typedef這里不報(bào)錯(cuò),而是在每個(gè)使用這個(gè)類型的地方報(bào)錯(cuò)?。。。?。后來(lái)把這個(gè)成員變量的類型修改為重命名之前的類型,整個(gè)程序就可以運(yùn)行了。(如上圖的正確寫(xiě)法)

三、結(jié)構(gòu)體內(nèi)存對(duì)齊規(guī)則

第一個(gè)成員在與結(jié)構(gòu)體變量偏移量為0的地址處。

后續(xù)成員變量要放到各自的對(duì)齊數(shù)的倍數(shù)上。對(duì)齊數(shù) = 編譯器默認(rèn)對(duì)齊數(shù)與該成員類型大小的較小值。(vs中默認(rèn)對(duì)齊數(shù)是8,gcc沒(méi)有默認(rèn)對(duì)齊數(shù))

結(jié)構(gòu)體最終大小為最大對(duì)齊數(shù)的整數(shù)倍。

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

1、結(jié)構(gòu)體內(nèi)存計(jì)算

struct S1
{
    char c1;
    int i;
    char c2;
};
int main()
{
    printf("%d\n", sizeof(struct S1));
    return 0;
}

char c1在結(jié)構(gòu)體變量的零偏移量處分配內(nèi)存

int i的對(duì)齊數(shù)為4,所以跳過(guò)3個(gè)字節(jié),在4的整數(shù)倍地址處分配內(nèi)存

char c2的對(duì)齊數(shù)為1,使用下一個(gè)字節(jié)空間即可

目前已使用9字節(jié)

由于該結(jié)構(gòu)體中所有成員變量中最大的成員類型大小為4字節(jié),所以最大內(nèi)存對(duì)齊數(shù)為4字節(jié),結(jié)構(gòu)體總大小為最大對(duì)齊數(shù)的整數(shù)倍。所以該結(jié)構(gòu)體內(nèi)存為12字節(jié)。

可以使用宏offsetof來(lái)觀察結(jié)構(gòu)體成員在內(nèi)存中的偏移量:

2、結(jié)構(gòu)體嵌套

struct S3//16
{
 double d;
 char c;
 int i;
};
struct S4//32
{
 char c1;
 struct S3 s3;
 double d;
};

char c1在結(jié)構(gòu)體變量的零偏移量處分配內(nèi)存

struct S3 s3按照其最大內(nèi)存對(duì)齊數(shù)(此處為8)進(jìn)行對(duì)齊

double d按照其最大內(nèi)存對(duì)齊數(shù)(8)進(jìn)行對(duì)齊

S4的最大內(nèi)存對(duì)齊數(shù)為8,所以結(jié)構(gòu)體的最終大小為32

3、通過(guò)調(diào)整結(jié)構(gòu)體成員順序,壓縮內(nèi)存

通過(guò)上述例子可以發(fā)現(xiàn),結(jié)構(gòu)體成員之間有很大的空間浪費(fèi),哪怕是擁有相同結(jié)構(gòu)體成員的兩個(gè)結(jié)構(gòu)體類型,其在內(nèi)存中所占據(jù)的空間也不相同,所以為了空間的節(jié)省,在不影響數(shù)據(jù)結(jié)構(gòu)的情況下,有目的的把字節(jié)占用小的成員變量放在一起,達(dá)到節(jié)省空間的目的。

四、存在內(nèi)存對(duì)齊的原因

1. 平臺(tái)原因(移植原因)

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

2. 性能原因(空間換時(shí)間)

數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對(duì)齊。 原因在于,為了訪問(wèn)未對(duì)齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問(wèn);而對(duì)齊的內(nèi)存訪問(wèn)僅需要一次訪問(wèn)。

五、修改默認(rèn)對(duì)齊數(shù)

#pragma pack(2)//把默認(rèn)對(duì)齊數(shù)改成2
struct S
{
    char c1;
    int i;
    short c2;
};
#pragma pack()//恢復(fù)默認(rèn)對(duì)齊數(shù)為8
int main()
{
    printf("%d\n", sizeof(struct S));
    return 0;
}
#pragma pack(num)修改默認(rèn)對(duì)齊數(shù),該結(jié)構(gòu)體的內(nèi)存大小由12字節(jié)降低為8字節(jié)。

默認(rèn)對(duì)齊數(shù)盡量為2的次方。

六、結(jié)構(gòu)體傳參

結(jié)構(gòu)體傳參要傳地址。

傳址調(diào)用優(yōu)于傳值調(diào)用的原因是地址占4/8個(gè)字節(jié)。

但是傳值調(diào)用參數(shù)需要壓棧,當(dāng)結(jié)構(gòu)體過(guò)大時(shí),參數(shù)壓棧的系統(tǒng)開(kāi)銷(xiāo)較大。

七、位段

位段是在結(jié)構(gòu)體中實(shí)現(xiàn)的。

位段的成員可以是 int、unsigned int、signed int或者是char類型

位段的空間增長(zhǎng)方式為每次增長(zhǎng)4個(gè)字節(jié)(int)或1個(gè)字節(jié)(char)

位段涉及很多不確定因素,位段是不跨平臺(tái)的,注重可移植的程序應(yīng)該避免使用位段。

1、位段在內(nèi)存中的存儲(chǔ)

1.1位段中char類型的存儲(chǔ)方式(vs中舍棄剩余空間)

struct S//占用3個(gè)字節(jié)
{
    char _a : 3;
    char _b : 4;
    char _c : 5;
    char _d : 4;
};
int main()
{
    printf("%d\n", sizeof(struct S));
    struct S s= { 0 };
    s._a = 10;//1010,截?cái)酁?10
    s._b = 12;//1100
    s._c = 3;//0011
    s._d = 4;//0100
    return 0;
}

通過(guò)調(diào)用內(nèi)存發(fā)現(xiàn),&s中存儲(chǔ)的16進(jìn)制數(shù)字為62 03 04,那么可以發(fā)現(xiàn)s在內(nèi)存中的存儲(chǔ)方式如下圖:

在vs環(huán)境中,char成員變量在單個(gè)字節(jié)中是倒著存儲(chǔ)的(有截?cái)嘞劝l(fā)生截?cái)啵?dāng)該字節(jié)中剩余的比特位不足以存放下一個(gè)完整的成員變量時(shí),會(huì)將剩余的比特位舍棄。

1.2位段中int類型的存儲(chǔ)方式(vs中利用剩余空間)

struct A//占4個(gè)字節(jié)
{
    int a : 2;
    int b : 3;
    int c : 4;
};
int main()
{
    struct A s = { 0 };
    s.a = 12;//1100,截?cái)酁?0
    s.b = 13;//1101,截?cái)酁?01
    s.c = 14;//1110
    return 0;
}

通過(guò)調(diào)用內(nèi)存發(fā)現(xiàn),&s中存儲(chǔ)的16進(jìn)制數(shù)字為d4 01 00 00,那么可以發(fā)現(xiàn)s在內(nèi)存中的存儲(chǔ)方式如下圖:

在vs環(huán)境中,int成員變量在單個(gè)字節(jié)中是倒著存儲(chǔ)的(有截?cái)嘞劝l(fā)生截?cái)啵?,?dāng)該字節(jié)中剩余的比特位不足以存放下一個(gè)完整的成員變量時(shí),會(huì)將繼續(xù)存儲(chǔ),存不下的二進(jìn)制位將存放至下一個(gè)字節(jié)的右側(cè)。

注意:位段冒號(hào)后面的數(shù)字只能小于等于類型大小(例如char a:9是錯(cuò)誤的)

2、位段的跨平臺(tái)問(wèn)題

1.int 位段被當(dāng)成有符號(hào)數(shù)還是無(wú)符號(hào)數(shù)是不確定的。

2. 位段中最大位的數(shù)目不能確定。(16位機(jī)器最大16,32位機(jī)器最大32,寫(xiě)成27,在16位機(jī)器會(huì)出問(wèn)題。

3. 位段中的成員在內(nèi)存中從左向右分配,還是從右向左分配標(biāo)準(zhǔn)尚未定義。

4. 當(dāng)一個(gè)結(jié)構(gòu)包含兩個(gè)位段,第二個(gè)位段成員比較大,無(wú)法容納于第一個(gè)位段剩余的位時(shí),是舍棄剩余的位還是利用,這是不確定的。

八、枚舉

1、枚舉的定義

enum color
{
    RED,//枚舉常量
    BLUE,
    YELLOW
};

不賦值那么默認(rèn)從0開(kāi)始,后續(xù)枚舉成員的值遞增1

enum color
{
    RED=1,
    BLUE,
    YELLOW
};

只需要對(duì)第一個(gè)成員進(jìn)行賦值,后續(xù)枚舉成員的值遞增1

在寫(xiě)枚舉成員的時(shí)候建議全大寫(xiě),博主在寫(xiě)通訊錄枚舉了exit,使用時(shí)vs提示該命名和exit函數(shù)沖突。

2、枚舉的優(yōu)點(diǎn)

增加代碼的可讀性和可維護(hù)性

枚舉使用時(shí)有類型檢查,#define定義的標(biāo)識(shí)符沒(méi)有

防止了命名污染(封裝)

便于調(diào)試(#define定義宏在預(yù)處理時(shí)是直接替換)

使用方便,一次可以定義多個(gè)常量

九、聯(lián)合體(共用體)

聯(lián)合也是一種特殊的自定義類型 這種類型定義的變量也包含一系列的成員,特征是這些成員共用同一塊空間(所以聯(lián)合也叫共用體)。

1、聯(lián)合體大小的計(jì)算

#include <stdio.h>
union un
{
    char arr[5];
    int a;
}u;
int main()
{
    printf("%d", sizeof(u));//8
    return 0;
}

聯(lián)合體的大小至少是最大成員的大小。

最大內(nèi)存對(duì)齊數(shù)的整數(shù)倍要大于等于最大成員的大小。

(這里最大成員是arr,占5個(gè)字節(jié),最大內(nèi)存對(duì)齊數(shù)是4,所以需要為祖國(guó)聯(lián)合體開(kāi)辟8個(gè)字節(jié)空間)

2、使用聯(lián)合體判斷計(jì)算機(jī)的大小端字節(jié)序

#include <stdio.h>
union un
{
    int m;
    char n;
}u;
int check_sys()
{
    u.m = 1;
    return u.n;
}
 
int main()
{
    int a = check_sys();
    if (a == 1)
        printf("小端存儲(chǔ)\n");
    else
        printf("大端存儲(chǔ)\n");
    return 0;
}

以上就是詳解C語(yǔ)言結(jié)構(gòu)體,枚舉,聯(lián)合體的使用的詳細(xì)內(nèi)容,更多關(guān)于C語(yǔ)言 結(jié)構(gòu)體 枚舉 聯(lián)合體的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于統(tǒng)計(jì)數(shù)字問(wèn)題的算法

    關(guān)于統(tǒng)計(jì)數(shù)字問(wèn)題的算法

    本文介紹了統(tǒng)計(jì)數(shù)字問(wèn)題的算法,計(jì)算出書(shū)的全部頁(yè)碼中分別用到多少次數(shù)字0,1,2,3,.....9,并有每一步的解題思路,需要的朋友可以參考下
    2015-08-08
  • 使用C語(yǔ)言實(shí)例描述程序中的內(nèi)聚和耦合問(wèn)題

    使用C語(yǔ)言實(shí)例描述程序中的內(nèi)聚和耦合問(wèn)題

    這篇文章主要介紹了用C語(yǔ)言實(shí)例描述程序中的內(nèi)聚和耦合,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • 基于C語(yǔ)言實(shí)現(xiàn)迷宮游戲的示例代碼

    基于C語(yǔ)言實(shí)現(xiàn)迷宮游戲的示例代碼

    這篇文章主要介紹了基于C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單的迷宮游戲,對(duì)于學(xué)習(xí)游戲開(kāi)發(fā)的朋友相信有一定的借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • C語(yǔ)言結(jié)構(gòu)體指針引用詳解

    C語(yǔ)言結(jié)構(gòu)體指針引用詳解

    C語(yǔ)言中結(jié)構(gòu)體指針,可細(xì)分為指向結(jié)構(gòu)體變量的指針和指向結(jié)構(gòu)體數(shù)組的指針。本文將詳細(xì)為大家介紹一下這兩種結(jié)構(gòu)體指針如何引用,需要的小伙伴可以參考一下
    2021-12-12
  • C++ 智能指針的魅力你都了解嗎

    C++ 智能指針的魅力你都了解嗎

    智能指針使用和普通指針類似。解引用一個(gè)智能指針?lè)祷厮赶虻膶?duì)象。如果在一個(gè)條件判斷中使用智能指針,效果就是檢測(cè)它是否為空,本文給大家介紹C++ 智能指針的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2021-06-06
  • C++實(shí)現(xiàn)xml解析器示例詳解

    C++實(shí)現(xiàn)xml解析器示例詳解

    這篇文章主要為大家介紹了C++實(shí)現(xiàn)xml解析器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 深入分析:C++模板究竟會(huì)使代碼膨脹嗎

    深入分析:C++模板究竟會(huì)使代碼膨脹嗎

    今天和同事說(shuō)到C++模板會(huì)使代碼膨脹, 可同事覺(jué)得不會(huì)。 同事的依據(jù)是: 如果模板會(huì)使代碼膨脹, 那么ATL和WTL里為什么還要大量使用模板? 同樣功能 ,ATL和WTL編譯出的可執(zhí)行文件可比MFC編譯的要小的多
    2013-04-04
  • C++中map和set的使用及示例

    C++中map和set的使用及示例

    map和set是STL容器中的部分,本文主要介紹了C++中map和set的使用小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • C++類模板與函數(shù)模板基礎(chǔ)詳細(xì)講解

    C++類模板與函數(shù)模板基礎(chǔ)詳細(xì)講解

    C++語(yǔ)言的模板技術(shù)包括函數(shù)模板和類模板,模板技術(shù)是一種代碼重用技術(shù),函數(shù)和類是C++語(yǔ)言中兩種主要的重用代碼形式,這篇文章主要介紹了C++函數(shù)模板和類模板,需要的朋友可以參考下
    2022-08-08
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之vector底層實(shí)現(xiàn)機(jī)制解析

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之vector底層實(shí)現(xiàn)機(jī)制解析

    向量(Vector)是一個(gè)封裝了動(dòng)態(tài)大小數(shù)組的順序容器(Sequence?Container)。跟任意其它類型容器一樣,它能夠存放各種類型的對(duì)象??梢院?jiǎn)單的認(rèn)為,向量是一個(gè)能夠存放任意類型的動(dòng)態(tài)數(shù)組
    2021-11-11

最新評(píng)論

油尖旺区| 罗定市| 枣阳市| 莒南县| 冷水江市| 新沂市| 武鸣县| 永济市| 宁阳县| 屏东市| 济源市| 华安县| 府谷县| 巍山| 常州市| 两当县| 紫金县| 许昌县| 翁牛特旗| 勃利县| 安平县| 灵石县| 永年县| 西乌珠穆沁旗| 青州市| 府谷县| 三台县| 资溪县| 塔河县| 广昌县| 怀化市| 紫云| 六安市| 隆昌县| 囊谦县| 牡丹江市| 沙洋县| 黔江区| 青川县| 香格里拉县| 和硕县|