跳转到内容

英文维基 | 中文维基 | 日文维基 | 草榴社区

复合型别

本页使用了标题或全文手工转换
维基百科,自由的百科全书

电脑科学中,复合型别是一种资料类型,它可以原始型别和其它的复合型别所构成。构成一个复合型别的动作,又称作组合

C/C++

[编辑]

structCC++ 的复合型别概念,是一个将栏位成员以一定组合方式所组成的资料型别。因为在宣告时,使用了关键字 struct,所以它简称为结构,或者更精确地说使用者定义的资料结构

在 C++ 里,structclass的唯一区别是预设的存取等级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_namelast_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;
 };

在三维图像中,必须经常不断追踪每一个顶点的位置和颜色。可以使用之前所建立的 VectorColor 复合型别来建立 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);

将可正确运作。

参阅

[编辑]