转载重点:共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。图形分析影响过程

通过前面的讲解,我们知道结构体(Struct)是一种构造类型或复杂类型,它可以包含多个类型不同的成员。在C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为:

union 共用体名{成员列表
};

共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。

结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。

结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。

共用体也是一种自定义类型,可以通过它来创建变量,例如:

union data{
int n;
char ch;
double f;
};
union data a, b, c;

上面是先定义共用体,再创建变量,也可以在定义共用体的同时创建变量:

union data{
int n;
char ch;
double f;
} a, b, c;

如果不再定义新的变量,也可以将共用体的名字省略:

union{
int n;
char ch;
double f;
} a, b, c;

共用体 data 中,成员 f 占用的内存最多,为 8 个字节,所以 data 类型的变量(也就是 a、b、c)也占用 8 个字节的内存,请看下面的演示:

#include <stdio.h>union data{
int n;
char ch;
short m;
};int main(){
union data a;
printf("%d, %d\n", sizeof(a), sizeof(union data) );
a.n = 0x40;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.ch = '9';
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.m = 0x2059;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.n = 0x3E25AD54;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);return 0;
}

运行结果:

4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54

这段代码不但验证了共用体的长度,还说明共用体成员之间会相互影响,修改一个成员的值会影响其他成员。

要想理解上面的输出结果,弄清成员之间究竟是如何相互影响的,就得了解各个成员在内存中的分布。以上面的 data 为例,各个成员在内存中的分布如下:

成员 n、ch、m 在内存中“对齐”到一头,对 ch 赋值修改的是前一个字节,对 m 赋值修改的是前两个字节,对 n 赋值修改的是全部字节。也就是说,ch、m 会影响到 n 的一部分数据,而 n 会影响到 ch、m 的全部数据。

上图是在绝大多数 PC 机上的内存分布情况,如果是 51 单片机,情况就会有所不同:

为什么不同的机器会有不同的分布情况呢?这跟机器的存储模式有关,我们将在VIP教程《大端小端以及判别方式》一节中展开探讨。

共用体的应用

共用体在一般的编程中应用较少,在单片机中应用较多。对于 PC 机,经常使用到的一个实例是: 现有一张关于学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、分数,教师的信息包括姓名、编号、性别、职业、教学科目。请看下面的表格:

Name

Num

Sex

Profession

Score / Course

HanXiaoXiao

501

f

s

89.5

YanWeiMin

1011

m

t

math

LiuZhenTao

109

f

t

English

ZhaoFeiYan

982

m

s

95.0

f 和 m 分别表示女性和男性,s 表示学生,t 表示教师。可以看出,学生和教师所包含的数据是不同的。现在要求把这些信息放在同一个表格中,并设计程序输入人员信息然后输出。

如果把每个人的信息都看作一个结构体变量的话,那么教师和学生的前 4 个成员变量是一样的,第 5 个成员变量可能是 score 或者 course。当第 4 个成员变量的值是 s 的时候,第 5 个成员变量就是 score;当第 4 个成员变量的值是 t 的时候,第 5 个成员变量就是 course。

经过上面的分析,我们可以设计一个包含共用体的结构体,请看下面的代码:

#include <stdio.h>
#include <stdlib.h>#define TOTAL 4 //人员总数struct{char name[20];int num;char sex;char profession;union{float score;char course[20];} sc;
} bodys[TOTAL];int main()
{int i;//输入人员信息for(i=0; i<TOTAL; i++){printf("Input info: ");scanf("%s %d %c %c", bodys[i].name, &(bodys[i].num), &(bodys[i].sex)   &(bodys[i].profession));            if(bodys[i].profession == 's'){ //如果是学生scanf("%f", &bodys[i].sc.score);}else{ //如果是老师scanf("%s", bodys[i].sc.course);}fflush(stdin);
}//输出人员信息
printf("\nName\t\tNum\tSex\tProfession\tScore / Course\n");
for(i=0; i<TOTAL; i++)
{if(bodys[i].profession == 's'){ //如果是学生printf("%s\t%d\t%c\t%c\t\t%f\n", bodys[i].name, bodys[i].num, bodys[i].sex,                 bodys[i].profession, bodys[i].sc.score);}else{ //如果是老师printf("%s\t%d\t%c\t%c\t\t%s\n", bodys[i].name, bodys[i].num, bodys[i].sex,     bodys[i].profession, bodys[i].sc.course);}
}return 0;}

运行结果:

Input info: HanXiaoXiao 501 f s 89.5↙
Input info: YanWeiMin 1011 m t math↙
Input info: LiuZhenTao 109 f t English↙
Input info: ZhaoFeiYan 982 m s 95.0↙Name            Num     Sex     Profession      Score / Course
HanXiaoXiao     501     f       s               89.500000
YanWeiMin       1011    m       t               math
LiuZhenTao      109     f       t               English
ZhaoFeiYan      982     m       s               95.000000

C语言共用体(C语言union用法)详解相关推荐

  1. 联合体c语言作用,C语言共用体-C语言union-什么是C语言中的联合体-嗨客网

    C语言共用体教程 在 共用体的各个成员会占用不同的内存,互相之间没有影响,而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员. C语言共用体 语法 union unionName{ fi ...

  2. 【C语言】结构体定义 typedef struct 用法详解和用法小结

    结构体定义 typedef struct 用法详解和用法小结 文章目录 结构体定义 typedef struct 用法详解和用法小结 0. 前言 1. 首先:在C中定义一个结构体类型要用typedef ...

  3. C语言结构体中定义函数指针详解

    C语言结构体中定义函数指针详解 结构体指针函数应用场景之一--驱动程序编写 结构体的一些基本用法 形式1:先定义结构体类型,再定义变量 形式2:在定义类型的同时定义变量 形式3:直接定义变量,用无名结 ...

  4. c语言数据类型int的用法,C语言基本数据类型:整型(int)用法详解|C语言学习

    C语言基本数据类型:整型(int)用法详解 1. 整型 int C 语言提供了很多整数类型(整型),这些整型的区别在于它们的取值范围的大小,以及是否可以为负.int 是整型之一,一般被称为整型.以后, ...

  5. C语言高频率--typedef和const用法详解

    一.typedef用法详解 C语言允许为一个数据类型起一个新的别名,就像给人起"绰号"一样. 起别名的目的不是为了提高程序运行效率,而是为了编码方便.例如有一个结构体的名字是 st ...

  6. 第十章 结构体_C语言共用体(C语言union用法)详解

    通过前面的讲解,我们知道结构体(Struct)是一种构造类型或复杂类型,它可以包含多个类型不同的成员.在C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为:  un ...

  7. c语言结构体定义和使用typedef,结构体定义typedef struct 用法详解

    typedef是类型定义的意思,typedef struct是为了使用这个结构体方便. 在了解typedef之前我们先来了解一下什么是结构体类型: C++提供了许多种基本的数据类型(如int.floa ...

  8. c语言中整形变量,C语言基本数据类型:整型(int)用法详解

    1.整型int C语言提供了很多整数类型(整型),这些整型的区别在于它们的取值范围的大小,以及是否可以为负.int是整型之一,一般被称为整型.以后,在不产生歧义的情况下,我们把整数类型和int都称为整 ...

  9. c语言fseek128字节,C语言rewind和fseek函数的用法详解(随机读写文件)

    前面介绍的文件读写函数都是顺序读写,即读写文件只能从头开始,依次读写各个数据.但在实际开发中经常需要读写文件的中间部分,要解决这个问题,就得先移动文件内部的位置指针,再进行读写.这种读写方式称为随机读 ...

  10. C语言rewind函数返回值为空,C语言rewind和fseek函数的用法详解(随机读写文件)...

    前面介绍的文件读写函数都是顺序读写,即读写文件只能从头开始,依次读写各个数据.但在实际开发中经常需要读写文件的中间部分,要解决这个问题,就得先移动文件内部的位置指针,再进行读写.这种读写方式称为随机读 ...

最新文章

  1. 计算机网络-UDP协议
  2. DIV CSS display (block none inline)属性的用法教程
  3. ios打包报错:User interaction is not allowed
  4. win7 桌面右下角音量图标消失的解决办法 参考
  5. matlab内置函数fitgeotrans与transformPointsForward解析
  6. spark官方文档_这些未在 Spark SQL 文档中说明的优化措施,你知道吗?
  7. sql中有一些保留字,当你的字段名是它的保留字时,这个时候sql语句的字段不加``就会报错...
  8. 机械制图国家标准的绘图模板_如何使用p5js构建绘图应用
  9. 信息学奥赛一本通 提高篇 第一部分 基础算法 第2章 二分与三分
  10. blender 3d打印_如何在Blender中开始3D打印
  11. oracle发生重启动的介绍
  12. H5 活动利用Canvas把用户信息和二维码合并到图片内。
  13. 《社会调查数据管理——基于Stata 14管理CGSS数据》一导读
  14. Qt6.0开发环境搭建
  15. 提取LSV中的高程数据在CAD中进行道路的方案设计流程
  16. 谈谈电子设计中PCB上的ESD防护方法
  17. java实现俄罗斯方块项目
  18. 计算机管理里怎么改ahci,联想电脑模式更改成ahci模式方法
  19. 王峰十问Nervos联合创始人王宁宁:缘何“中国最懂以太坊的人”要走中国公链的自主创新之路?...
  20. Flink janino,跟老铁又学到了

热门文章

  1. 英国首相卡梅隆特制iPad应用,处理政务
  2. 关于自我成长推荐几本书籍
  3. notion自建服务器,秒杀传统型笔记!《Notion》等 5 款工具全方位对比,模块化笔记究竟强在哪?...
  4. echarts map 解决label设置width height无效并附aliyun地图json地址
  5. [日推荐]『涂图艺术滤镜』让你的照片一秒变艺术大片
  6. 芒果iOS开发之利用U盘给Mac重新安装系统
  7. Linux根据关键字或日期查找日志
  8. java中的cascade,详解Hibernate cascade级联属性的CascadeType的用法
  9. Flink Forward Asia 2020 大会精彩总结
  10. 马云给阿里巴巴员工的公开信