在之前的讲解中相信大家都了解到了结构体(Struct)是一种构造类型或复杂类型,它可以包含多个类型不同的成员。其实在C语言中还有另外一种和结构体非常类似的语法--共用体(Union),那么到底它是什么意思呢?它的作用又是什么呢?下面课课家笔者就为大家简单介绍C语言中的共用体概念和作用。
所谓共用体,它表示的是几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在共用体中,所有的成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。当一个共用体被声明时,编译程序自动地产生一个变量,其长度(以字节byte为单位,一个byte是8个二进制位)为联合中最长的数据类型长度的整数倍。共用体的定义格式为:
union共用体名{
成员列表
};
另外共用体有时也被称为联合或者联合体,这也是Union这个单词的本意。
◎结构体和共用体的区别
结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。共用体也是一种自定义类型,可以通过它来创建变量,比如:
uniondata{
intn;
charch;
doublef;
};
uniondataa,b,c;
在上述的代码例子中我们是先定义共用体再创建变量,其实我们也可以在定义共用体的同时创建变量,具体代码如下:
uniondata{
intn;
charch;
doublef;
}a,b,c;
当然如果我们不再定义新的变量,我们也可以将共用体的名字省略,具体代码如下:
uniondata{
intn;
charch;
doublef;
}a,b,c;
在共用体data中,我们可以观察到成员f占用的内存最多,为8个字节,所以data类型的变量(也就是a、b、c)也占用8个字节的内存,具体大家可以观察下面的代码例子:
#include
uniondata{
intn;
charch;
shortm;
};
intmain(){
uniondataa;
printf("%d,%d\\n",sizeof(a),sizeof(uniondata));
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);
return0;
}
输出结果:
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单片机,情况就会有所不同(具体原因在于和机器的存储模式有关):
◎共用体的应用
通常共用体在一般的编程中应用较少,在单片机中应用较多。为了使大家更容易的了解共用体的应用,下面笔者通过PC机给大家举一个具体表格例子:
题目:下面是一张关于学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、分数,教师的信息包括姓名、编号、性别、职业、教学科目。
目标:把信息放在同一个表格中并设计程序输入人员信息然后输出。
分析:在这里f和m分别表示女性和男性,s表示学生,t表示教师。从表格中我们可以看出,学生和教师所包含的数据是不同的。如果我们把每个人的信息都看作一个结构体变量的话,那么教师和学生的前4个成员变量是一样的,第5个成员变量可能是score或者course。当第4个成员变量的值是s的时候,第5个成员变量就是score;当第4个成员变量的值是t的时候,第5个成员变量就是course。
经过上面的简单分析,接下来我们就可以设计一个包含共用体的结构体了,具体大家可以观察下面的代码:
#include
#include
#defiNETOTAL4//人员总数
struct{
charname[20];
intnum;
charsex;
charprofession;
union{
floatscore;
charcourse[20];
}sc;
}bodys[TOTAL];
intmain(){
inti;
//输入人员信息
for(i=0;i
printf("Inputinfo:");
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
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);
}
}
return0;
}
输出结果:
Inputinfo:HanXiaoXiao501fs89.5↙
Inputinfo:YanWeiMin1011mtmath↙
Inputinfo:LiuZhenTao109ftEnglish↙
Inputinfo:ZhaoFeiYan982ms95.0↙
NameNumSexProfessionScore/Course
HanXiaoXiao501fs89.500000
YanWeiMin1011mtmath
LiuZhenTao109ftEnglish
ZhaoFeiYan982ms95.000000
本次解读C语言共用体的讲解到此暂告一段落,如果以后有什么内容继续补充或者修改的话笔者会继续在此进行补充或者修改的工作,同时也欢迎大家对本次的讲解提出自己的建议和补充。最后笔者希望本次的讲解对大家学习C语言能够起到一定的帮助作用!
¥150.00
¥98.00
¥25.00¥49.00
¥100.00