其他資料型別

定義資料型別 (typedef)

C++ 允許我們基於其他現有的資料型別定義自己的型別。我們可以使用關鍵字typedef來實現,其格式為:

typedef existing_type new_type_name;

,其中existing_type是 C++ 的基本或複合型別,而new_type_name是我們定義的新型別的名稱。例如:

1
2
3
4
typedef char C;
typedef unsigned int WORD;
typedef char * pChar;
typedef char field [50];

在此示例中,我們定義了四個資料型別:C, WORD, pChar欄位char, unsigned int, char*char[50]分別,這些型別可以像任何其他有效型別一樣用於後續的宣告。

1
2
3
4
C mychar, anotherchar, *ptc1;
WORD myword;
pChar ptc2;
field name;

typedef並不會建立不同的型別。它僅僅是建立現有型別的別名。這意味著變數myword的型別可以被認為是WORD或者unsigned int,因為它們實際上是相同的型別。

typedef定義一個程式中頻繁使用的型別的別名會非常有用。當程式後續版本可能需要更改型別時,或者當您想使用的型別名稱太長或令人困惑時,定義型別也很有用。

聯合體 (Unions)

聯合體允許同一塊記憶體區域被訪問為不同的資料型別,因為它們實際上都位於同一記憶體地址。其宣告和使用方式與結構體類似,但功能完全不同。

union union_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;

聯合體聯合體宣告的所有成員都佔據相同的物理記憶體空間。其大小等於宣告中最大成員的大小。例如:

1
2
3
4
5
union mytypes_t {
  char c;
  int i;
  float f;
  } mytypes;

定義了三個成員,

1
2
3
mytypes.c
mytypes.i
mytypes.

每個成員都有不同的資料型別。由於它們都指向同一記憶體位置,修改其中一個成員的值會影響所有成員的值。我們無法獨立地在它們中儲存不同的值。

聯合體的一個用途是將一個基本型別與一個較小元素的陣列或結構體組合起來。例如:

1
2
3
4
5
6
7
8
union mix_t {
  long l;
  struct {
    short hi;
    short lo;
    } s;
  char c[4];
} mix;

定義了三個名稱,允許我們訪問相同的 4 位元組組:mix.l, mix.smix.c根據我們想要訪問這些位元組的方式,可以將其視為一個單獨的long型別資料,或者兩個short元素,或者一個char元素陣列,分別對應。我在聯合體中混合了型別、陣列和結構體,以便您可以看到訪問資料的不同方式。對於一個“小端序”(大多數 PC 平臺)系統,該聯合體可以表示為:


聯合體成員的確切對齊方式和順序是平臺相關的。因此,要注意這種用法可能存在的移植性問題。

匿名聯合體

在 C++ 中,我們可以選擇宣告匿名聯合體。如果我們宣告一個沒有名稱的聯合體,該聯合體將是匿名的,並且我們可以直接透過其成員名稱訪問其成員。例如,看看這兩個結構體宣告之間的區別:

帶有常規聯合體的結構體帶有匿名聯合體的結構體
struct {
char title[50];
char author[50];
union {
float dollars;
int yen;
} price;
} book;
struct {
char title[50];
char author[50];
union {
float dollars;
int yen;
};
} book;

這兩段程式碼之間的唯一區別在於,第一段程式碼中我們給聯合體起了一個名稱(price),而在第二段程式碼中我們沒有。當訪問物件的成員dollarsyen

1
2
book.price.dollars
book.price.

時,區別就顯現出來了。對於第一個型別的物件,訪問方式是:

1
2
book.dollars
book.

而對於第二個型別的物件,訪問方式是:dollars再次提醒您,由於這是一個聯合體而不是結構體,成員price佔據相同的物理記憶體空間,因此它們不能同時用於儲存兩個不同的值。您可以為

設定美元值或日元值,但不能同時設定兩者。

列舉 (enum)

enum enumeration_name {
value1,
value2,
value3,
.
.
} object_names;

列舉建立新的資料型別來包含不同於基本資料型別可能值的特定值。其形式如下:例如,我們可以建立一個名為colors_t

1
enum colors_t {black, blue, green, cyan, red, purple, yellow, white};

的新變數型別來儲存顏色,使用以下宣告:請注意,我們沒有在宣告中包含任何基本資料型別。可以說,我們是從零開始建立了一個全新的資料型別,而沒有基於任何其他現有型別。這種新型別變數可能取的可能值是包含在大括號內的新常量值。例如,在聲明瞭列舉之後,以下表達式將是有效的:例如,我們可以建立一個名為列舉與數值變數是型別相容的,因此其常量在內部總是被賦予一個整數數值。如果未指定,則第一個可能值的整數等價物是

1
2
3
4
colors_t mycolor;
 
mycolor = blue;
if (mycolor == green) mycolor = red;

,後續值按 +1 遞增。因此,在我們上面定義的0資料型別中,例如,我們可以建立一個名為black將等價於blue0, greenblue1, ,依此類推。2我們可以顯式指定列舉型別所能取的任何常量值的整數值。如果其後的常量值未被賦予整數值,則自動假定為前一個值加一。例如:

在這種情況下,列舉型別

1
2
3
enum months_t { january=1, february, march, april,
                may, june, july, august,
                september, october, november, december} y2k;

months_t的變數y2k可以包含 12 個可能值中的任何一個,這些值從januarydecember,它們等價於值介於112(不是介於011,因為我們已經將設定為等於1).
Index
目錄