共用体(Union)
前言:看一个实际需求:
传统方式解决:
//定义结构体,根据人员的职业,使用对应的成员变量
struct Person{
char name[20];
int num;
char sex;
char profession;
float score; //学生使用score
char course[20];//老师使用course
};
**传统方式的问题分析:**会造成空间的浪费,比如学生只使用score,但是也占用了course成员20个字节
解决方案:
(1)做struct Stu 和 struct Teacher[但是如果职业很多,就会对应多个结构体类型,不利于管理]
(2)这里因此提出了共用体
1.共用体基本介绍
(1)共用体属于构造类型,它可以包含多个类型不同的成员。和结构体类似,但是也有不同的地方
(2)共用体有时也被称为联合或联合体,定义格式为
union 共用体名{
成员列表
}
(3)结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响,而共用体的的所有成员占用一段内存,修改一个成员会影响其余所有成员
2.快速入门
(1)定义共用体类型和共用体变量的三种方式(和结构体一样)
为什么上述的运行结果和我们想象的不同?
3.说明代码的内存布局:
4.共用体内存布局分析
5.最终实践
分析:
f 和 m 分别表示女性和男性,s 表示学生,t 表示教师。可以看出,学生和教师所包含的数据是不同的(score/course)。现在要求把这些信息放在同一个表格中,并设计程序输入人员信息然后输出。
如果把每个人的信息都看作一个结构体变量的话,那么教师和学生的前 4 个成员变量是一样的,第 5 个成员变量可能是 score 或者 course。当第 4 个成员变量的值是 s 的时候,第 5 个成员变量就是 score;当第 4 个成员变量的值是 t 的时候,第 5 个成员变量就是 course。
代码:
#include <stdio.h>
#include <stdlib.h>
#define TOTAL 2 //人员总数
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;
}