引子
C语言共用体同结构体类似,都是一种自定义类型,可以通过他们来定义变量。
但又有着很大的区别,下面我们来了解一下共用体
探讨
所谓共用体,顾名思义,多个变量共用一个空间。这便是共用体同结构体最大的区别,公用体在初始化时,分配的内存大小是其中所占内存最大的变量的大小,这个内存空间则属于多个变量使用,一个变量的变化,会对其它共用体成员有影响,下面我们通过一个例子来深入了解下:
#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下面通过图示来了解其中的内存机制:
成员 n、ch、m 在内存中“对齐”到一头,对 ch 赋值修改的是前一个字节,对 m 赋值修改的是前两个字节,对 n 赋值修改的是全部字节。也就是说,ch、m 会影响到 n 的一部分数据,而 n 会影响到 ch、m 的全部数据。
我们了解了共用体的机制,那么为什么要使用共用体呢?
应用
共用体作用
节省内存,有两个很长的数据结构,不会同时使用,比如一个表示老师,一个表示学生,如果要统计教师和学生的情况用结构体的话就有点浪费了!用共用体的话,只占用最长的那个数据结构所占用的空间,就足够了!
共用体应用场景
通信中的数据包会用到共用体:因为不知道对方会发一个什么包过来,用共用体的话就很简单了,定义几种格式的包,收到包之后就可以直接根据包的格式取出数据。
我们通过一个例子来了解一下:
在这个例子中包含学生和教师两种身份,现在要将获取并输出,如果把每个人的信息都看作一个结构体变量的话,那么教师和学生的前 4 个成员变量是一样的,第 5 个成员变量可能是 score 或者 course。当第 4 个成员变量的值是 s 的时候,第 5 个成员变量就是 score;当第 4 个成员变量的值是 t 的时候,第 5 个成员变量就是 course。
这时就可以使用共用体了,因为对于第4、5个成员变量,均只有一种可能,且为已知选项,就像是开关一样,只有0和1两种选择。
下面实现其代码:
#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
欢迎关注公众号 树语星球
关注公众号 树语星球 有好礼相送哦