赞
踩
在编程过程中,有时需要使几种不同类型的变量存放到同一段内存单元中。例如,可以把一个整型变量,一个字符型变量,一个实型变量放在同一个地址开始的内存单元中。
这样的话,不同类型的变量在内存中占据的字节数不同,但是都从同一个地址开始。也就是使用覆盖技术,几个变量互相覆盖。这种使几个不同的变量共同占用同一段内存的结构,称为“共用体”类型的结构。
结构体变量占用的内存空间大小是其各个成员所占的字节长度的总和。如果同一时刻只存放其中的一个成员数据,会浪费单片机有限的内存空间.而共用体所占的内存空间的长度是其中最长的成员的字节长度。这样就有效的提高了内存的利用效率。
共用体类型的定义也有三种方式:
1)先定义共用体类型再定义变量名。一般格式如下:
union 共用体名
{undefined
成员列表;
};
定义好一个共用体类型之后,就可以像定义变量一样来定义共用体变量。一般格式为:
union 共用体名 共用体变量名1,共用体变量名2,…共用体变量名n;
2)在定义共用体类型的同时定义共用体变量名。一般格式为:
union 共用体名
{undefined
成员列表;
}共用体变量名1,共用体变量名2,…共用体变量名n;
3)直接定义共用体变量。一般格式为:
union
{undefined
成员列表;
}共用体变量名1,共用体变量名2,…共用体变量名n;
由上可见,共用体类型与结构体类型有很多相似之处,只是将关键字struct改成了union,但是在内存分配上两者却有本质的区别。
3、共用体变量的引用
与结构体变量类似,对共用体变量的引用也是通过对其成员的引用来实现的。
引用共用体变量成员的一般格式为:
共用体变量名.共用体成员
共用体类型数据是需要注意:
1)同一个内存段可以用来存放几种不同类型的成员,但在每一瞬间只能存放其中一种,而不能同时存放几种,也就是说,每一瞬时只有一个成员起作用,其他的成员都不起作用;
2)共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后,原有的成员就失去作用。因此在引用共用体变量是因注意当前存放在共用体变量中的到底是哪个成员。
3)共用体变量的地址和它的各成员的地址都是同一地址;
4)不能对共用体变量名赋值,也不能企图引用共用体变量名来得到一个值,更不能在定义共用体变量时对它初始化。
(也不能在共用内对成员进行的赋值,赋值后的语句就不能作为共用体的成员了,譬如:int a = 3;作为共用体的成员列表中的成员,编译器会把a=3作为一个成员名在内存中开辟空间,这样就出现了空间名是一个“a=3”的名字,是不符号C语言的规定,所以在共用体内出现int a =3;的成员时会报错:error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token
int a= 3;在之后定义的成员char c;编译器也会报错没有成员名:error: ‘union myunion’ has no member named ‘c’
x.c=4;
^
)
5)不能把共用体变量作为函数参数,也不能使函数返回共用体变量,但可以使用指向共用体变量的指针
6)共用体类型可以出现在结构体类型定义中,也可以定义共用体数组,反之亦然。
4、本实例演示共用体类型的定义、共用体变量的定义以及共用体成员的引用。
共用体在一般的编程中应用较少,在单片机中应用较多。
#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
union型数据就是用来节省不必要的内存开销,将不在同一时间使用的各类型数据进行封装。
为了访问共用体的成员,我们使用成员访问运算符(.)。成员访问运算符是共用体变量名称和我们要访问的共用体成员之间的一个句号。您可以使用 union 关键字来定义共用体类型的变量。下面的实例演示了共用体的用法:
#include <stdio.h> #include <string.h> union Data { int i; float f; char str[20]; }; int main( ) { union Data data; data.i = 10; data.f = 220.5; strcpy( data.str, "C Programming"); printf( "data.i : %d\n", data.i); printf( "data.f : %f\n", data.f); printf( "data.str : %s\n", data.str); return 0; }
当上面的代码被编译和执行时,它会产生下列结果:
data.i : 1917853763
data.f : 4122360580327794860452759994368.000000
data.str : C Programming
在这里,我们可以看到共用体的 i 和 f 成员的值有损坏,因为最后赋给变量的值占用了内存位置,这也是 str 成员能够完好输出的原因。现在让我们再来看一个相同的实例,这次我们在同一时间只使用一个变量,这也演示了使用共用体的主要目的:
#include <stdio.h> #include <string.h> union Data { int i; float f; char str[20]; }; int main( ) { union Data data; data.i = 10; printf( "data.i : %d\n", data.i); data.f = 220.5; printf( "data.f : %f\n", data.f); strcpy( data.str, "C Programming"); printf( "data.str : %s\n", data.str); return 0; }
当上面的代码被编译和执行时,它会产生下列结果:
data.i : 10
data.f : 220.500000
data.str : C Programming
所有的成员都能完好输出,因为同一时间只用到一个成员。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。