有时需要使几种不同类型的变量存放到同一段内存单元中。例如可以一个整形变量,一个字符型变量,一个实型变量放在同一地址开始的内存单元中。以上3个变量在内存单元中占的字节数不同,但是都从同一地址开始存放。也就是使用覆盖技术,几个变量互相覆盖。
共用体也是一种构造数据类型,它是将不同类型的变量存放在同一内存区域内。共用体也称为联合(union)。共用体的类型定义、变量定义及引用方式与结构相似,但它们有着本质的区别:结构变量的各成员占用连续的不同存储空间,而共用体变量的各成员占用同一个存储区域。 1.共用体变量的定义共用体变量的定义与结构变量定义相似,首先,必须构造一个共用体数据类型,再定义具有这种类型的变量。 共用体类型定义的一般方法: union 共用体名 { 共用体成员表 } ; 其中,共用体成员表是对各成员的定义,形式为:类型说明符 成员名; 与定义结构变量一样,定义共用体变量的方法有以下三种: (1)先定义共用体类型,再定义该类型数据 例如: union data { char n[10]; int a; double f;}; union data x,y[10]; (2)在定义共用体类型的同时定义该类型变量 例如: union data { char n[10]; int a; double f; }x,y[10]; (3)不定义共用体类型名,直接定义共用体变量 例如: union { char n[10]; int a; double f; }x,y[10]; 定义了共用体变量后,系统就给它分配内存空间。因共用体变量中的各成员占用同一存储空间,所以,系统给共用体变量所分配的内存空间为其成员中所占用内存空间最多的成员的单元数。共用体变量中各成员从第一个单元开始分配存储空间,所以各成员的内存地址是相同的。例如上述共用体data的变量x的内存分配如图9.14所示,它占用10个字节的内存单元。
定义了共用体变量后,即可使用它。若需对共用体变量初始化,只能对它的第一个成员赋初始值。 例如:union data x={"zhangsan"};是正确的,而union data x={"zhangsan",12,40000, 78,5};是错误的。 虽然共用体数据可以在同一内存空间中存放多个不同类型的成员,但在某一时刻只能存放其中的一个成员,起作用的是最后存放的成员数据,其他成员不起作用,如引用其他成员,则数据无意义。 例如,对data类型共用体变量,有以下语句: x.a=100; strcpy(x.n,"zhangsan"); x.f=90.5; 则只有x.f是有效的,x.a与x.n目前数据是无意义的,因后面的赋值语句将前面共用体数据覆盖了。 例9.10 分析下列程序的输出结果,用共用体数据的特性给以正确的解释。 /* 例9-10源程序,分析程序的输出结果。 */ #include <stdio.h> #include <string.h> void main() { union bt { int k; char c[3];} a;
a.k=0; strcpy(a.c,"AB"); //第8行 printf("%o , %o\n",a.c[0],a.c[1]); printf("%d\n",a.k); a.k=2; // 第11行 printf("%o , %o, %o \n",a.c[0],a.c[1],a.c[2]); printf("%d\n",a.k); } 程序执行: 101 , 102 16961 2 , 0, 0 Press any key to continue 程序说明:共用体变量a共占用4个字节的存储空间,执行第8行语句后,a所对应的存储区域中的数据如图9.15(a)所示。
这时a的成员数组3字节被赋值为字符串“AB”,对应的各字符的ASCII码值分别存放在a的对应空间中,因a的成员k与成员c所占用的内存单元是重叠的,所以将前3字节作为a.c。同样,执行程序的第11行后,a所对应的存储区域中的数据如图 9.15(b)所示,a的成员k被赋值为2,将刚才a中的数据覆盖了,执行下一语句后输出的是2的内存存放形式的八进制数据,整型数据在内存中的存放原则是低位字节在前,高位字节在后。 |