C++ union
關鍵字可用來定義union型別。
Union與struct用法非常類似,但差別在於union成員共用一個記憶體空間,持有的記憶體空間會以成員中佔最大的為準;而struct成員則擁有各自的記憶體空間。Union的好處就是節省記憶體空間及效能,當資料有多種不同型別表示的樣態時可使用union表示。
宣告union
宣告union型別的語法如下:
union
- 宣告union的關鍵字。TypeName
- Union的名稱,習慣以UpperCamelCase
命名。member_type1-3
- Union的成員型態。成員(member)是union所含的各種資料型態,如int
、double
,或陣列(array)類別(class)string
、struct、另一union。member_name1-3
- Union的成員名稱。
union TypeName {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
...
};
例如下面宣告一個union型別名為ASCII
,有兩個成員short int d
(佔用2 bytes)及char c
(佔用1 byte),則此union佔的記憶體空間為2 bytes。
union ASCII {
short int d; // 2 bytes
char c; // 1 byte
};
Union初始化
由於union成員共用一記憶體空間,因此在初始化時只能設定一個成員的值,否則會出現error: excess elements in union initializer
錯誤。
main.cpp
#include <iostream>
union ASCII {
short int d;
char c;
};
int main() {
// ASCII ascii = {97, 'a'}; // error: excess elements in union initializer
ASCII ascii = {.c = 'a'};
return 0;
}
範例
下面宣告union ASCII
型別變數asicc
,修改成員的值並印出另個成員的值及以bitset表示的二進位。
main.cpp
#include <bitset>
#include <iostream>
using namespace std;
union ASCII {
short int d; // 2 bytes
char c; // 1 byte
};
int main() {
ASCII ascii;
ascii.d = 97;
cout << ascii.d << endl; // 97 (decimal)
cout << ascii.c << endl; // a (char)
cout << bitset<7>(ascii.d) << endl; // 1100001 (binary)
ascii.c = 'b';
cout << ascii.d << endl; // 98 (decimal)
cout << ascii.c << endl; // b (char)
cout << bitset<7>(ascii.d) << endl; // 1100010 (binary)
cout << sizeof(ascii) << endl; // 2
return 0;
}
由於union的成員使用的是同一個記憶體空間,當一個成員被更新時,另一個成員的記憶體內容也被影響。下圖為二進位表示的記憶體空間。
ASCII.d = 97
┌────────────────────────────────┴────────────────────────────────┐
┌───┬───┬───┬───┬───┬───┬───┬───┐ ┌───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ │ 0 │ 1 │ 1 │ 0 │ 0 │ 0 │ 0 │ 1 │
└───┴───┴───┴───┴───┴───┴───┴───┘ └───┴───┴───┴───┴───┴───┴───┴───┘
└────────────────────────────────┬────────────────────────────────┘
ASCII.c = 'a'
ASCII.d = 98
┌────────────────────────────────┴────────────────────────────────┐
┌───┬───┬───┬───┬───┬───┬───┬───┐ ┌───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ │ 0 │ 1 │ 1 │ 0 │ 0 │ 0 │ 1 │ 0 │
└───┴───┴───┴───┴───┴───┴───┴───┘ └───┴───┴───┴───┴───┴───┴───┴───┘
└────────────────────────────────┬────────────────────────────────┘
ASCII.c = 'b'
沒有留言:
張貼留言