C语言中联合体union的使用

2024-07-02 15:08
文章标签 语言 使用 union 联合体

本文主要是介绍C语言中联合体union的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文编辑整理自:
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471
一、前言
联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度。应该说明的是, 这里所谓的共享不是指把多个成员同时装入一个联合变量内, 而是指该联合变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则冲去旧值
一个联合体类型必须经过定义之后, 才能使用它,才能把一个变量声明定义为该联合体类型。
关于结构体的更多内容请参考《结构体struct简介
二、联合体的定义
定义一个联合类型的一般形式为: 
union 联合名 
成员表 
};
成员表中含有若干成员,成员的一般形式为: 类型说明符 成员名。成员名的命名应符合标识符的规定。
例如: 
union perdata
{
   int class;
   char office[10];
};
  定义了一个名为perdata的联合类型,它含有两个成员,一个为整型,成员名为class;另一个为字符数组,数组名为office。联合定义之后,即可进行联合变量说明,被说明为perdata类型的变量,可以存放整型量class或存放字符数组office。
三、联合体变量的声明
  联合变量的说明和结构变量的声明方式相同, 也有三种形式。第一种先定义联合体类型,再声明联合体变量;第二种,定义联合体类型的同时声明联合体变量;第三种,直接声明联合体(以匿名的形式定义联合体类型)。
以perdata类型为例,说明如下: 
第一种,先定义联合体类型,再声明联合体变量
union perdata
{
   int class;
   char officae[10];
};
union perdata a,b; /*说明a,b为perdata类型*/
第二种,定义联合体类型的同时声明联合体变量
union perdata
int class;
char office[10]; 
}a,b;
第三种,直接声明联合体(以匿名的形式定义联合体类型)
union
int class;
char office[10]; 
}a,b 
经说明后的a,b变量均为perdata类型。a,b变量的长度应等于 perdata 的成员中最长的长度, 即等于office数组的长度,共10个字节。对a,b变量如赋予整型值时,只使用了2个字节,而赋予字符数组时,可用10个字节。
四、联合体变量的赋值和使用
  对联合体变量的赋值,使用都只能是对变量的成员进行。 
联合变量的成员表示为: 联合变量名.成员名 
例如,a被说明为perdata类型的变量之后,可使用 a.class,a.office 
不允许只用联合变量名作赋值或其它操作。 也不允许对联合变量作初始化赋值,赋值只能在程序中进行。
一个联合体变量, 每次只能赋予一个成员值。一个联合变量的值就是联合变员的某一个成员值。
[例4.1]设有一个教师与学生通用的表格,教师数据有姓名,年龄,职业,教研室四项。学生有姓名,年龄,职业,班级四项。
编程输入人员数据, 再以表格输出。
main()
{
   struct
   {
      char name[10];
      int age;
      char job;
      union
      {
         int class;
         char office[10];
      } depa;
   }body[2];
   int n,i;
   for(i=0;i<2;i++)
   {
      printf("input name,age,job and department\n");
      scanf("%s %d %c",body[i].name,&body[i].age,&body[i].job);
      if(body[i].job=='s')
         scanf("%d",&body[i].depa.class);
      else
         scanf("%s",body[i].depa.office);
   }
   printf("name\tage job class/office\n");
   for(i=0;i<2;i++)
   {
   if(body[i].job=='s')
      printf("%s\t%3d %3c %d\n",body[i].name,body[i].age ,body[i].job,body[i].depa.class);
   else
      printf("%s\t%3d %3c %s\n",body[i].name,body[i].age, body[i].job,body[i].depa.office);
   }
}
  本例程序用一个结构数组body来存放人员数据, 该结构共有四个成员。其中成员项depa是一个联合类型, 这个联合又由两个成员组成,一个为整型量class,一个为字符数组office。在程序的第一个for语句中,输入人员的各项数据,先输入结构的前三个成员name,age和job,然后判别job成员项,如为"s"则对联合depa·class输入(对学生赋班级编号)否则对depa·office输入(对教师赋教研组名)。
  在用scanf语句输入时要注意,凡为数组类型的成员,无论是结构成员还是联合成员,在该项前不能再加"&"运算符。如程序第18行中
body.name是一个数组类型,第22行中的body.depa.office也是数组类型,因此在这两项之间不能加"&"运算符。程序中的第二个for语句用于输出各成员项的值:


这篇关于C语言中联合体union的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1090421

相关文章

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

C语言中%zu的用法解读

《C语言中%zu的用法解读》size_t是无符号整数类型,用于表示对象大小或内存操作结果,%zu是C99标准中专为size_t设计的printf占位符,避免因类型不匹配导致错误,使用%u或%d可能引发... 目录size_t 类型与 %zu 占位符%zu 的用途替代占位符的风险兼容性说明其他相关占位符验证示

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时