共用体(union 关键字)

概念

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

创建,定义,赋值,用法

与结构体相似,请参考上一讲

结构体和共同体的区别

只要是空间区别

结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;
而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙
共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。

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

#include<stdio.h>

union data{
    
    
	 int n;
	 char ch;
	 short m;
};

void 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);
 }

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

共同体应用

共用体在一般的编程中应用较少,在单片机中应用较多。对于 PC 机,经常使用到的一个实例是: 现有一张关于
学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、分数,教师的信息包括姓名、编号、性别、
职业、教学科目。请看下面的表格:
在这里插入图片描述
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;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45830608/article/details/113027322
今日推荐