HOME ABOUT CONTACT

C/C++教學: 第二十三課 - 共用資料(Union)

Rain October 18, 2024
Outline

1. 簡介

2. 定義共用資料語法

3. 宣告共用資料語法

4. 初始值配置

5. 共用資料與結構占用記憶體比較

簡介top

在介紹結構告一個段落之後,我們接著來看一下一種與結構很像的資料型態 - 共用資料(Union)。

共用資料(Union)和結構(Struct)的最大差異在於,共用資料的成員們彼此佔用的記憶體空間是共享的,也就是說當宣告一個共用資料之後,系統會以占用記憶體空間最大的成員來配置一塊記憶體給這個共用資料(Union),所有成員就共用了這塊記憶體。

這意味著這個共用資料在一同一個時間內,它只代表了一種資料型態,而不是像結構一樣同時含有多種資料型態的集合。因此共用資料(Union)雖然節省了記憶體空間,但必須確保這個資料不會同時被其他不同用途的執行緒(Thread)存取。(多執行緒的程式設計就需要特別注意)

定義共用資料語法top

定義共用資料語法和結構很像,只要把關鍵字改成 union 即可,如下:


union {union name} {
    members ...
}; 
                        

union person{
    char name[16];
    int age;
}; 
                        

宣告共用資料語法top

宣告共用資料語法和結構一模一樣,如下:


union person {
    char name[16];
    int age;
} RainD; 
                        

union person {
    char name[16];
    int age;
}; 

void main() {
    union person RainD;
}
                        

初始值配置top

在初始值配置的環節,有一個地方是與結構不太一樣的,當宣告共用資料是採用上述第一種方式時,你會發現它無法給予整數型態作為初始值給 age 成員,如下:


union person {
    char name[16];
    int age;
} RainD = {18}; 
                        

union 在標準函式庫規定了系統只會將初始值給順位第一位的成員,也就是 name,因此像這樣的例子,初始值只能給字串,如下:


union person {
    char name[16];
    int age;
} RainD = {"RainD"}; 
                        

倘若是採用宣告的第二種方式呢? 就必須記住 union 只能在一個時間代表一個值,若每個成員都給予了值,則 union 只會具有最後一個成員被賦予的值,如下:


union person {
    char name[16];
    int age;
}; 

void main() {
    union person RainD;
    strcpy_s(RainD.name, "RainD"); // 先將 union 的第一個成員賦予字串 "RainD"
    RainD.age = 18; // 再將 union 的第二個成員賦予值 18
    std::cout << "Name = " << RainD.name << ", age = " << RainD.age << std::endl;
}
                        

上例中,你會發現輸出的 name 值已經變成其他數值,這是因為 union 最後附值的是給整數到 age 成員,而已無法使用 name 的記憶體空間已經被刷清並且給 age 成員使用。

共用資料與結構占用記憶體比較top

如前面簡介所述,union 所佔用的總記憶體空間是以成員中佔用最大者來配置的,而 struct 則是全部成員的加總,我們可以打印這兩者的記憶體空間來做實證,如下:


union personA {
    char name[16];
    int age;
}RainA; 

struct personB {
    char name[16];
    int age;
}RainB;

void main() {
    std::cout << "union personA size = " << sizeof(personA) << ", struct personB size = " << sizeof(personB) << std::endl;
}
                        

下一篇: 第二十四課 - 遞迴(Recursive)


Last updated:

Related Artical List

  1. C/C++教學: 第二十一課 - 鏈結串列(Linked List)
  2. C/C++教學: 第二十二課 - 結構陣列(Struct Array)
  3. C/C++教學: 第二十四課 - 遞迴(Recursive)

Article List