第14章 结构和其他数据形式 14.10 联合简介

联合(union)是一个能在同一个存储空间里(但不同时)存储不同类型数据的数据类型。一个典型的应用是一种表,设计它是用来以某种即没有规律,事先也未知的顺序保存混合类型数据。使用联合类型的数组,可以创建相同大小单元的数组,每个单元都能存储多种类型的数据。

联合是以与结构相同的方式建立的,也是需要一个联合模板和一个联合变量。可以在一步中定义它们也可以使用联合标记在两步中定义。下面是一个带有标记的联合模板的例子:

union hold {

    int digit;

    double bigfl;

    char letter;

};

具有类似声明的结构可以含有一个int类型数值和一个double类型数值以及一个char类型数值,而这个联合可以含有一个int类型数值或一个double类型数值或一个char类型数值。

下面是定义3个hold类型联合变量的例子:

union  hold  fit;    //hold类型的联合变量

union  hold  save[10]    //10个联合变量的数组

union  hold  *pu;    //指向hold类型变量的指针

第一个声明创建一个变量fit。编译器分配足够的空间以保存所描述的可能性的最大需求。在这种情况下,列出的最大可能性是double型数据。在我们的系统里,它需要64位,即8个字节。第二个声明创建了一个save数组,它含有10个元素,每个元素大小为8个字节。第三个声明创建了一个指针,可以存放一个hold联合的地址。

可以初始化一个联合,因为联合只存放一个值 ,所以初始化的规则与结构的初始化不同。具体地,有3种选择:可以把一个联合初始化为同样类型的另一个联合;可以初始化联合的第一个元素;或者按C99标准,可以使用一个指定初始化项目。

union hold valA;
valA.letter='R';
union hold valB = valA;        //把一个联合初始化为另一个联合
union hold valC = {88};        //初始化联合的digit成员(第1个元素)
union hold valD = {.bigfl = 118.2};  //指定初始化项目

下面示例了怎样使用联合:

fit.digit = 23;    //把23存储在fit中,使用2个字节
fit.bigfl = 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.bigfl;  //错误

这个语句序列是错误的,因为存储了一个char类型,而接下来的一行却假定fit的内容是double类型的

但是,使用一个成员来将值保存到一个联合中,然后使用一个不同的成员来查看这些内容,这种做法有时会很有用。下一章的程序清单15.4就给出这样一个例子。

另一个可能会使用联合的地方是在某些结构中,该结构所存储的信息有赖于其中的一个成员。例如,假定有一个表示一辆汽车的结构。如果汽车归属于使用者,就要一个结构成员来描述这个所有者。如果汽车被租赁,需要一个成员来描述租赁它的公司。那么使用下面的语句行,可以做些事情 :

struct owner {
    char socsecurity[12];
    ...
};

struct leasecompany{
    char name[40];
    char headpuarters[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,程序就可以使用fits.ownerinfo.owncar.socsecurity; 如果flits.status是1,程序就可以使用flits.ownerinfo.leasecar.name。

 

总结 :结构和联合运算符

成员运算符:

总体注解:

        运算符和结构或联合名称一起使用,用来指定结构或联合的成员。如果name是一个结构名,member是一个由结构模板指定的成员,下面就表示了该结构的这个成员:

        name.member

        name.member的类型就是member的类型。成员运算符也可以用同样的方式用于联合。

间接成员运算符:

    ->

        总体注解:

        这个运算符与指向结构或联合的指针一起使用,用来指明结构或联合的成员 。假设ptrstr是一个指向结构的指针,member是由该结构模板指定的一个成员。那么:

        ptrstr->member

        这个表达式表示被指向结构的成员。间接运算符也可以用同样的方式用于联合。

例如:

       

struct {
    int code;
    float cost;
} item,*ptrst;

ptrst = &item;
ptrst->code=3451;

 最后一条语句将一个int 值赋给item的成员code。以下三个表达式是等价的:

ptrst->code  item.code    (*ptrst).code

转载于:https://my.oschina.net/idreamo/blog/866620

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值