微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C Primer Plus(6) 中文版 第14章 结构和其他数据形式 14.10 联合简介

14.10 联合简介
联合(union)是一种数据类型,它能在同一个内存空间中存储不同的数据类型(不是同时存储)。其典型用法是,设计一种表以存储既无规律、事先也不知道顺序的混合类型。使用联合烈性,其中的联合大小相等,每个联合可以存储各种数据类型。
创建联合和创建结构的方式相同,需要一个联合模板和联合变量。可以用一个步骤定义联合,也可以用联合标记分两步定义。下面是一个标记的联合模板:
union hold{
    int digit;
    double bigf1;
    char letter;
}; 
根据以上形式声明的结构可以存储一个int类型、一个double类型和char类型的值。然而,声明的联合只能存储一个int类型的值或一个double类型的值或char类型的值。
下面定义了3个与hold类型相关的变量:
union hold fit;          //hold类型的联合变量
union hold save[10];     //内含10个联合变量的数组
union hold *pu;         //指向hold类型联合变量的指针
第1个声明创建了一个单独的联合变量fit。编译器分配足够的空间以便它能存储联合声明中占有最大字节的类型。第2个声明创建了一个数组save,内含10个元素,每个元素的类型都是联合声明中占有最大字节的类型。
可以初始化联合。需要注意的是,联合只能存储一个值,这与结构不同。有3种初始化的方法:把一个联合初始化为另一个同类型的联合;初始化联合的第1个元素;或者根据C99标准,使用指定初始化器:
union hold valA;
valA.letter = 'R';
union hold valB = valA; //用另一个联合来初始化
union hold valC = {88}; //初始化联合的digit成员
union hold valD = {.bigfl = 118.2}; //指定初始化器
14.10. 1 使用联合
下面是联合的一些用法
fit.digit = 23; //把23存储在int,占4字节
fit.bigf1 = 2.0; //清除23,存储2.0,占8字节
fit.letter = 'h'; //清除2.0,存储h,占1字节
点运算符表示正在使用哪种数据类型。在联合中,一次只存储一个值。即使有足够的空间,也不能同时存储一个char类型值和一个int类型值。
编写代码时要注意当前在联合中的数据类型。
利用指针访问结构使用->运算符一样,用指针访问联合时也要使用->运算符:
pu = &fit;
x = pu->digit; //相当于x = fit.digit
不要像下面的语句序列这样:
fit.letter = 'A';
flnum = 3.02 * fit.bigf1; //错误
以上语句序列是错误的,因为存储在fit中的是char类型,但是下一行却假定fit中的内容是double类型。
不过,用一个成员把值存储在一个联合中,然后用另一个成员查看内容,这种做法有时很有用。程序清单15.4就给出了一个这样的例子。
联合的另一种用法是,在结构中存储与其成员有从属关系的信息。例如,假设用一个结构表示一辆汽车,如果汽车属于驾驶者,就要用一个结构成员来描述这个所有者。如果汽车被租赁,那么需要一个成员来描述其租赁公司。可以用下面的代码来完成:
struct owner{
    char socsecurity[12];
    ...
}; 
struct leasecompany{
    char name[40];
    char headquarters[40];
    ...
};
union data{
    struct owner owncar;
    struct leasecompany leasecar;
};
struct car_data {
    char make[15];
    int status; /*私有为0,租赁为1*/
    union data ownerinfo;
    ... 
};
假设flits是car_data类型的结构变量,如果flits.status为0,程序将使用flits.ownerinfo.owncar.socsecurity,如果flits.status为1,程序则使用flits.ownerinfo.leasecompany.name。
14.10.2 匿名联合(C11)
匿名联合和匿名结构的工作原理相同,即匿名联合是一个结构或联合的无名联合成员。例如,我们重新定义car_data结构如下:
struct owner{
    char socsecurity[12];
    ...
}; 
struct leasecompany{
    char name[40];
    char headquarters[40];
    ...
};
struct car_data {
    char make[15];
    int status; /*私有为0,租赁为1*/
    union {
        struct owner owncar 
    };
    ... 
};
现在,如果flits是car_data类型的结构变量,可以用flits.owncar.socsecurity代替flits.ownerinfo.owncar.socsecurity
总结:结构和联合运算符
成员运算符:.
一般注释:
name.member
name.member的类型就是member的类型。联合使用成员运算符的方式与结构相同。
间接访问运算符:->
一般注释:
假设ptrstr是指向结构的指针,member是该结构模板指定的一个成员,那么:
ptrstr->member
标识了指向结构的成员。联合使用间接成员运算符的方式与结构相同。 

原文地址:https://www.jb51.cc/wenti/3280315.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐