C

C 知识量:16 - 74 - 317

14.5 联合><

联合简介- 14.5.1 -

联合(union)是一种数据类型,它能在同一个内存空间中储存不同的数据类型,但是不能同时储存这些不同的数据类型。联合常用于设计一种表以储存既无规律、事先也不知道顺序的混合类型。下面是定义联合及变量的示例:

union box {
    int a;
    double b;
    char c;
};

union box fit;      // box类型的联合变量
union box save[10]; // 内含10个联合变量的数组
union box * p;      // 指向box类型联合变量的指针

以上形式声明的代码可以储存一个int类型或一个double类型或一个char类型的值,但是,声明的联合实际使用时只能存储以上3类数据中的其中1类数据。在创建联合变量时,编译器会分配足够的空间以便它能储存联合声明中占用最大字节的类型。以上示例中,占用空间最大的是double类型的数据,占64位,即8字节。第2个声明创建了一个数组save,内含10个元素,每个元素都是8字节。第3个声明创建了一个指针,该指针变量储存box类型联合变量的地址。

初始化联合时需要注意的是,联合只能储存一个值,这与结构不同。有3种初始化的方法:

  • 把一个联合初始化为另一个同类型的联合。

  • 初始化联合的第1个元素。

  • 使用指定初始化器。

union box valA;
valA.c = 'P';
union box valB = valA;         // 用另一个联合来初始化
union box valC = {88};         // 初始化联合的a成员
union box valD = {.b = 118.2}; // 指定初始化器

使用联合- 14.5.2 -

下面是联合的用法示例:

union box {
    int a;
    double b;
    char c;
};    
union box fit;
fit.a = 5;   //把5储存在fit,占2字节
fit.b = 3.0; //清除5,储存3.0,占8字节
fit.c = 'p'; //清除3.0,储存字符p,占1字节

点运算符表示正在使用哪种数据类型。在联合中,一次只储存一个值。即使有足够的空间,也不能同时储存一个char类型值和一个int类型值。

联合的另一种用法是,在结构中储存与其成员有从属关系的信息,例如用一个结构表示一台电脑。如果电脑属于个人,就用一个结构成员来描述个人的信息。如果电脑属于公司,那么就用一个成员来描述公司的信息:

struct person {
    char name[20];
    int age;
};

struct company {
    char name[50];
    char address[50];
    char Email[50];
};

union data {
    struct person p_computer;
    struct company c_computer;
};

struct computer_data {
    int id;
    int status; /* 个人为0,公司为1 */
    union data ownerinfo;
};

假设dell是computer_data类型的结构变量,如果dell.status为0,程序将使用dell.ownerinfo. p_computer类型的结构信息;如果dell.status为1,程序则使用dell.ownerinfo.c_computer类型的结构信息。

匿名联合- 14.5.3 -

匿名联合和匿名结构的工作原理相同,即匿名联合是一个结构或联合的无名联合成员。例如,我们重新定义computer_data结构如下:

struct person {
    char name[20];
    int age;
};

struct company {
    char name[50];
    char address[50];
    char Email[50];
};

struct computer_data {
    int id;
    int status; /* 个人为0,公司为1 */
    union {
        struct person p_computer;
        struct company c_computer;
    };
};

修改之后,如果dell是computer_data类型的结构变量,当dell.status为0时,就可以用dell.p_computer代替dell.ownerinfo.p_computer了。