The C Programming Language(第 2 版) 笔记 / 6 结构 / 6.8 联合

本文深入介绍了C语言中的联合(Union)特性,它允许在一个变量中存储不同类型的对象。联合体用于节省存储空间,程序员负责跟踪当前存储的数据类型。文中通过示例展示了如何声明和使用联合,以及在结构体和数组中的应用。此外,还讨论了联合在编译器符号表管理和存储分配中的作用。
摘要由CSDN通过智能技术生成

目录、参考文献


6.8 联合

联合是可以(在不同时刻)保存不同类型和长度的对象的变量,编译器负责跟踪对象的长度和对齐要求
联合提供了一种方式,以在单块存储区中管理不同类型的数据,而不需要在程序中嵌入任何同机器有关的信息
它类似于 Pascal 语言中的变体记录

类比 TypeScript 中声明多种类型的情况
如:let a: string | number | Person = ‘test’;

我们来看一个例子(可以在编译器的符号表管理程序中找到该例子)
假设一个常量可能是 intf1oat 或字符指针
特定类型的常量值必须保存在合适类型的变量中
然而,如果该常量的不同类型占据相同大小的存储空间,且保存在同一个地方的话,表管理将最方便
这就是联合的目的 —— 一个变量可以合法地保存多种数据类型中任何一种类型的对象
其语法基于结构:

union u_tag {
    int ival;
    float fval;
    char *sval;
} u;

变量 u 必须足够大,以保存这 3 种类型中最大的一种,具体长度同具体的实现有关
这些类型中的任何一种类型的对象都可赋值给 u,且可使用在随后的表达式中,但必须保证是一致的:读取的类型必须是最近一次存入的类型
程序员负责跟踪当前保存在联合中的类型
如果保存的类型与读取的类型不一致,其结果取决于具体的实现

可以通过下列语法访问联合中的成员:

联合名.成员联合指针->成员

它与访问结构的方式相同
如果用变量 utype 跟踪保存在 u 中的当前数据类型,则可以像下面这样使用联合:

if (utype == INT) 
    printf("%d\n", u.ival); 
if (utype == FLOAT) 
    printf("%f\n", u.fval); 
if (utype == STRING) 
    printf("%s\n", u.sval); 
else 
    printf("bad type %d in utype\n", utype);

联合可以使用在结构和数组中,反之亦然
访问结构中的联合(或反之)的某一成员的表示法与嵌套结构相同
例如,假定有下列的结构数组定义:

struct { 
    char *name; 
    int flags; 
    int utype; 
    union { 
        int ival; 
        float fval; 
        char *sval; 
    } u; 
} symtab[NSYM];

可以通过语句 symtab[i].u.ival 引用其成员 ival

也可以通过下列语句之一引用字符串 sval 的第一个字符:

*symtab[i].u.sval
symtab[i].u.sval[0]

实际上,联合就是一个结构,它的所有成员相对于基地址的偏移量都为 0
此结构空间要大到足够容纳最 “ 宽 ” 的成员,并且,其对齐方式要适合于联合中所有类型的成员
对联合允许的操作与对结构允许的操作相同:作为一个整体单元进行赋值、复制、取地址及访问其中一个成员

联合只能用其第一个成员类型的值进行初始化,因此,上述联合 u 只能用整数值进行初始化

第 8 章的存储分配程序将说明如何使用联合来强制一个变量在特定类型的存储边界上对齐


目录、参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值