如何使用联合
声明联合变量后,有很多方法设置它的值。
C89 方式
如果联合要保存第一个字段的值,就可以用 C89 表示法,只要用花括号把值括起来,就可以把值赋给联合中第一个字段。
指定初始化器
指定初始化器(designated initializer)按名设置联合字段的值:
“点”表示法
第三种设置联合值的方法是在第一行创建变量,然后在第二行设置字段的值。
quantity q;q.volume = 3.7;
切记,无论用哪种方法设置联合的值,都只会保存一条数据。联合只是提供了一种让你创建支持不同数据类型的变量的方法。这里没有蠢问题问:为什么联合的大小取决于最长的字段?答:计算机需要保证联合的大小固定。唯一的办法就是让它足够大,任何一个字段都能装得下。问:为什么 C89 表示法只能设置第一个字段?如果我传给联合 float 值,为什么不把它设为第一个 float 字段?答:这么做是为了避免歧义。假设你有一个 float 字段和一个 double 字段,那么计算机应该把{2.1} 保存成 float 还是 double 呢?每次都把值保存在第一个字段中,你就知道数据是怎么初始化的。
C 标准礼貌指南
可以用“指定初始化器”按名设置结构和联合字段,它属于 C99 标准。绝大多数现代编译器都支持“指定初始化器”,但如果你用的是 C 语言的变种,就要小心了,比如 ObjectiveC 支持“指定初始化器”,但 C++不支持。
是的,“指定初始化器”也可以用来设置结构字段的初值。
如果结构有很多字段,但你只想为其中某些字段设初值,“指定初始化器”就非常有用。同时它还能够提高代码的可读性:
联合常和结构一起用
创建联合相当于创建新的数据类型,也就是说可以在任何地方使用它的值,就像使用整型或结构那样的数据类型。例如,可以把联合和结构结合起来:typedef struct { const char *name; const char *country; quantity amount;} fruit_order;
可以用之前使用过的“点”表示法或“-> ”表示法访问“结构/联合”组合中的值:
晕头转向的调酒师
Head First 酒吧的“玛格丽特之夜”,一群人喝得酩酊大醉以后把配方弄乱了,你能否为每种玛格丽特酒找到相应的代码?基本原料如下:typedef union { float lemon; int lime_pieces;} lemon_lime; typedef struct { float tequila; float cointreau; lemon_lime citrus;} margarita;
下面是几种不同的玛格丽特酒:最后,这里有一些不同的调法和他们制作的配方。为了生成正确的配方,应该把哪些玛格丽特酒加入代码?
变身编译器
有的代码能编译,有的不能。你的任务是扮演编译器,说出哪段代码能编译,如果不能请说明理由。
晕头转向的调酒师解答
Head First 酒吧的“玛格丽特之夜”,一群人喝得酩酊大醉以后把配方弄乱了,你将为每种玛格丽特酒找到相应的代码。基本原料如下:typedef union { float lemon; int lime_pieces;} lemon_lime; typedef struct { float tequila; float cointreau; lemon_lime citrus;} margarita;
下面是几种不同的玛格丽特酒:最后,这里有一些不同的调法和他们制作的配方。为了生成正确的配方,应该把哪些玛格丽特酒加入代码?
变身编译器
有的代码能编译,有的不能。你的任务是扮演编译器,说出哪段代码能编译,如果不能请说明理由。
好问题:可以在联合中保存各种可能的值,但保存以后,就无法知道它的类型。
编译器不会记录你在联合中设置或读取过哪些字段。我们完全可以设置一个字段,读取另一个字段,但有时这会造成很严重的后果。
你需要某种方法记录我们在联合中保存了什么值。C 程序员常用的一种技巧是创建枚举。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论