聯(lián)合體與位域

聯(lián)合體

定義

聯(lián)合體也叫共用體,由不同的數(shù)據(jù)類型組成,其變量互斥,存儲(chǔ)方式是所有成員共用一個(gè)段內(nèi)存,共同體同一時(shí)刻只能保存一個(gè)成員的值,如果對(duì)新的成員賦值,就會(huì)將原來(lái)成員的值覆蓋掉。

特性

  1. union中,分配內(nèi)容空間大小,等于占用內(nèi)存最大的數(shù)據(jù)類型字節(jié)大小
  2. 共享一段內(nèi)存,成員變量的賦值操作,其他成員變量原有數(shù)據(jù)將成為臟數(shù)據(jù),不可用。

例子

// 聯(lián)合體的定義
union Teacher {
    char *name; // 8
    int age; // 4
    double height; // 8
};
  1. 驗(yàn)證聯(lián)合體大小
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 聯(lián)合體
        union Teacher teacher;
        teacher.name = "AngaoTu";
        teacher.age = 18;
        teacher.height = 175.0;
        
        NSLog(@"聯(lián)合體大小 size = %lu", sizeof(teacher));
        
    }
    return 0;
}

打印結(jié)果:2022-07-30 15:38:42.149406+0800 聯(lián)合體+位域[9304:21445471] 聯(lián)合體大小 size = 8

可證明聯(lián)合體的大小,是由占用內(nèi)存最大的數(shù)據(jù)類型字節(jié)大小決定

  1. 驗(yàn)證是否共用同一片地址
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 聯(lián)合體
        union Teacher teacher;
        teacher.name = "AngaoTu";
        teacher.age = 18;
        teacher.height = 175.0;
        
        NSLog(@"name 地址 = %p, age 地址 = %p, height 地址 = %p", &teacher.name, &teacher.age, &teacher.height);
    }
    return 0;
}

打印結(jié)果:2022-07-30 15:43:05.950276+0800 聯(lián)合體+位域[10267:21450499] name 地址 = 0x7ffeefbff398, age 地址 = 0x7ffeefbff398, height 地址 = 0x7ffeefbff398

可驗(yàn)證聯(lián)合體中成員變量使用同一個(gè)地址

  1. 驗(yàn)證一個(gè)成員被賦值,其他成員數(shù)據(jù)不可用
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 聯(lián)合體
        union Teacher teacher;
        teacher.name = "AngaoTu";
        teacher.age = 18;
        teacher.height = 175.0;
    }
    return 0;
}

打印結(jié)果:

  1. (Teacher) teacher = (name = "AngaoTu", age = 16176, height = 2.1220037829711594E-314)
  2. (Teacher) teacher = (name = "", age = 18, height = 2.1219957998584539E-314)
  3. (Teacher) teacher = (name = "", age = 0, height = 175)

可驗(yàn)證成員變量的賦值操作,其他成員變量原有數(shù)據(jù)將成為臟數(shù)據(jù),不可用

優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):
    • 內(nèi)存使用更為精細(xì)、節(jié)省空間
  • 缺點(diǎn):
    • 不夠包容,成員之間會(huì)互相影響

位域

定義

有些信息在存儲(chǔ)時(shí),并不需要占用一個(gè)完整的字節(jié),而只需占幾個(gè)或一個(gè)二進(jìn)制位。 例如在存放一個(gè)開關(guān)量時(shí),只有 0 和 1 兩種狀態(tài),用一位二進(jìn)位即可。為了節(jié)省存儲(chǔ)空間,并使處理簡(jiǎn)便,C語(yǔ)言又提供了一種數(shù)據(jù)結(jié)構(gòu),稱為“位域”或“位段”。

聲明

  • 位域的定義和結(jié)構(gòu)體的定義相仿
sturct 位域結(jié)構(gòu)名 {
  位域列表 // 格式: [類型 位域名:位域長(zhǎng)度]
};

struct bits {
    int a: 8;
    int b: 2;
    int c: 6;
}

位域的大小

struct bits {
    char a:2; 
};
// size = 1 

struct bits {
    char a:2; 
    char b:2;
};
// size = 1 

struct bits {
    char a:2; 
    char b:2;
    char c:4; 
    char d:4;
};
// size = 2

struct bits {
    int a:4;
};
// size = 4 

struct bits {
    int a:4;
    int b:4;
};
// size = 4

struct bits {
    char a:8; 
    char b:8; 
    char c:8; 
    char d:8; 
    int e:4;
};
// size = 8 
  • 位域的存儲(chǔ)同樣遵循結(jié)構(gòu)體內(nèi)存對(duì)齊規(guī)則
    • 選取該位域結(jié)構(gòu)內(nèi)聲明時(shí)的類型中長(zhǎng)度最大的類型長(zhǎng)度,為對(duì)齊方式
    • 具體可參考結(jié)構(gòu)體內(nèi)存對(duì)齊【TODO】

特性說(shuō)明

  1. 當(dāng)相鄰成員,如果它們的位寬之和小于類型的 sizeof 大小,那么后面的成員緊鄰前一個(gè)成員存儲(chǔ),直到不能容納為止;如果它們的位寬之和大于類型的 sizeof 大小,那么后面的成員將從新的存儲(chǔ)單元開始,其偏移量為類型大小的整數(shù)倍。
  2. 位域的寬度不能超過(guò)它所依附的數(shù)據(jù)類型的長(zhǎng)度,成員變量都是有類型的,這個(gè)類型限制了成員變量的最大長(zhǎng)度,: 后面的數(shù)字不能超過(guò)這個(gè)長(zhǎng)度。
  3. 位域可以是無(wú)名位域,這時(shí)它只用來(lái)作填充或調(diào)整位置。無(wú)名的位域是不能使用的

聯(lián)合體位域

定義

聯(lián)合體位域結(jié)合起來(lái)的數(shù)據(jù)類型,稱為聯(lián)合體位域

聲明

union isa_t {
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
    Class cls;
};
  • 由于isa_t是一個(gè)共用體,所以bitscls共用一塊內(nèi)存空間。
  • bits是一個(gè)位域,里面根據(jù)不同位定義了數(shù)據(jù),節(jié)省空間。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 從 isa 底層結(jié)構(gòu)引入聯(lián)合體、位域 在isa底層結(jié)構(gòu)分析[http://www.itdecent.cn/p/3...
    奉灬孝閱讀 686評(píng)論 0 0
  • 首先我們創(chuàng)建一個(gè)類,里面有三個(gè)BOOL類型屬性 創(chuàng)建一個(gè)對(duì)象,打印內(nèi)存大小 打印出來(lái)占16字節(jié)(isa:8,tal...
    鏡像閱讀 764評(píng)論 0 0
  • union 共用體/聯(lián)合體 結(jié)構(gòu)體和共用體的區(qū)別在于:結(jié)構(gòu)體的各個(gè)成員會(huì)占用不同的內(nèi)存,互相之間沒有影響;而共用體...
    答案不止一個(gè)閱讀 1,112評(píng)論 0 1
  • 聯(lián)合體和位域 在上一篇iOS中關(guān)于內(nèi)存對(duì)齊的探究[http://www.itdecent.cn/p/c913b5...
    Eli_app閱讀 686評(píng)論 0 0
  • 在對(duì) OC 對(duì)象創(chuàng)建的探究過(guò)程中,我們發(fā)現(xiàn)一個(gè)很有趣的實(shí)現(xiàn) isa。isa 是將對(duì)象內(nèi)存空間與 class 之間聯(lián)...
    redye閱讀 900評(píng)論 2 1

友情鏈接更多精彩內(nèi)容