复合型别
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);
将可正确运作。