複合型別
![本页使用了标题或全文手工转换](http://images.weserv.nl/?url=//upload.wikimedia.org/wikipedia/commons/thumb/c/cd/Zh_conversion_icon_m.svg/35px-Zh_conversion_icon_m.svg.png)
在電腦科學中,複合型別是一種資料類型,它可以原始型別和其它的複合型別所構成。構成一個複合型別的動作,又稱作組合。
C/C++
struct
是 C 和 C++ 的複合型別概念,是一個將欄位或成員以一定組合方式所組成的資料型別。因為在宣告時,使用了關鍵字 struct
,所以它簡稱為結構,或者更精確地說使用者定義的資料結構。
在 C++ 裡,struct
與class
的唯一區別是預設的存取等級,class
是私有的,struct
則是公有的。
注意尽管类的概念和關鍵字class
是C++新引入的,C語言也已具備粗糙的 struct
型別。對於所有的意圖和目的, C++ 的struct
是 C struct
的超集:几乎所有合法的 C struct
也是合法的 C++ struct
,並有著相同的語義。
struct
宣告組成一個欄位清單,其中的每一個可以是任意型別。對於 struct
物件所需的儲存區,即為全部欄位的總合,再加上內部的補白。
例如:
struct Account {
int account_number;
char *first_name;
char *last_name;
float balance;
};
定義一個稱為 struct Account
的型別。若要建立此型別的新變數,可以寫為 struct Account myAccount;
,它有一個以 myAccount.account_number
存取的整數組件,且有一個以 myAccount.balance
存取的浮點數組件,以及 first_name
和 last_name
組件。myAccount
包含這四個數值,且這四個欄位可各自改變。由于 struct account
的寫法有些累贅,在 C 代碼中,typedef
語句並不罕見,其為 struct
提供一個更簡便的同義詞。例如:
typedef struct Account_ {
int account_number;
char *first_name;
char *last_name;
float balance;
} Account;
在 C++ 中,並不需要 typedef
,因為使用了 struct
的型別定義,已是命名空間的一部分,所以該型別可稱作 struct Account
或較簡單的 Account
。
其它例子,一個使用了浮點數資料型別的三維向量複合型別,可如此建立:
struct Vector {
float x;
float y;
float z;
};
一個以 Vector
複合型別為型別的變數名 velocity
,可以宣告為 Vector velocity;
,可以用點运算符(.)存取 velocity
的成員。例如,velocity.x = 5;
,會使 velocity
的組件 x
等於 5。
同樣地,一個顏色結構可如此建立:
struct Color {
int red;
int green;
int blue;
};
在三維圖像中,必須經常不斷追蹤每一個頂點的位置和顏色。可以使用之前所建立的 Vector
和 Color
複合型別來建立 Vertex
複合型別:
struct Vertex {
Vector position;
Color color;
};
以同樣的格式建立一個 Vertex
型別的變數:Vertex v;
,並以如下方式指派數值給 v
:
v.position.x = 0.0;
v.position.y = 1.5;
v.position.z = 0.0;
v.color.red = 128;
v.color.green = 0;
v.color.blue = 255;
原始子型別檢查
剛開始使用的 struct
,是用來建構組合資料型別,不過有時它是用來避開標準 C 協定,以建立原始子型別檢查(primitive subtyping)。例如,共同的網路協議依賴於以下事實,C 編譯器以可預料的方法,在結構欄位之間補白;因此代碼
struct ifoo_old_stub {
long x, y;
};
struct ifoo_version_42 {
long x, y, z;
char *name;
long a, b, c;
};
void operate_on_ifoo(struct ifoo_old_stub *);
struct ifoo_version_42 s;
. . .
operate_on_ifoo(&s);
將可正確運作。
參閱
|