共用体
针对占用的内存来说,名字起的很形象,共用内存的一个整体。即将不同的数据项组织成一个整体,它们在内存中占用同一段存储单元。
定义形式为:
union 共用体名
{成员表列};
例:
union data
{
int a;
float b;
double c;
char d;
}obj;
该形式定义了一个共用体数据类型union data ,定义了共用体数据类型变量obj。共用体数据类型与结构体在形式上非常相似,但其表示的含义及存储是完全不同的。再看个例子:
union data /*共用体* /
{
int a;
float b;
double c;
char d;
}mm ;
struct stud /*结构体* /
{
int a;
float b;
double c;
char d;
} ;
main( )
{
struct stud student
printf("%d,%d",sizeof(struct stud),sizeof(union data));
}
运行输出:
15,8
程序的输出说明结构体类型所占的内存空间为其各成员所占存储空间之和。而形同结构体的共用体类型实际占用存储空间为其最长的成员所占的存储空间。
对共用体的成员的引用与结构体成员的引用相同。但由于共用体各成员共用同一段内存空间,使用时,根据需要使用其中的某一个成员。从图中特别说明了共用体的特点,方便程序设计人员在同一内存区对不同数据类型的交替使用,增加灵活性,节省内存。
共用体变量的引用
union data /*共用体* /
{
int a;
float b;
double c;
char d;
}mm ;
其成员引用为:
mm.a , mm.b , mm.c , mm.d
但是要注意的是,不能同时引用四个成员,在某一时刻,只能使用其中之一的成员。
对共用体变量的使用
main ( )
{
union data
{
int a;
float b;
double c;
char d;
}mm;
mm.a = 6 ;
printf("%d\n",mm.a);
mm.c = 67.2;
printf( " %5.11f\ n ",mm.c ) ;
mm.d = 'W';
mm.b = 34.2;
printf( " %5.1f, %c\n ", mm.b, mm.d) ;
}
运行结果:
6
67.2
34.2,=
程序最后一行的输出是我们无法预料的。其原因是连续做mm.d = ' W ';mm.b = 34.2;两个连续的赋值语句最终使共用体变量的成员mm. b所占四字节被写入34.2,而写入的字符被覆盖了,输出的字符变成了符号“=”。事实上,字符的输出是无法得知的,由写入内存的数据决定。
例子虽然很简单,但却说明了共用体变量的正确用法。
例:通过共用体成员显示其在内存的存储情况。
定义一个名为time的结构体,再定义共用体dig:
struct time
{
int year; / *年* /
int month;/ *月* /
int day; / *日* /
} ;
union dig
{
struct time data; /*嵌套的结构体类型* /
char byte[6];
} ;
假定共用体的成员在内存的存储是从地址
1 0 0 0
单元开始存放,整个共用体类型需占存储空间
6
个字节,即共用体
d i g
的成员
d at a
与
b y t e
共用这
6
个字节的存储空间,存储空间分配示意如图
7 -7
所示。
由于共用体成员data包含三个整型的结构体成员,各占2个字节。由图7 - 7所示可见,
data.year是由2个字节组成,用byte字符数组表示为byte[ 0 ]和byte[1]。byte[ 1 ]是高字节,
byte[ 0 ]是低字节。下面用程序实现共用体在内存中的存储。
struct time
{
int year; /*年* /
int month; / *月* /
int day; / *日* /
} ;
union dig
{
struct time data; /*嵌套的结构体类型* /
char byte[6];
} ;
main( )
{
union dig unit;
int i;
printf("enter year:\n");
scanf ( " %d " , &unit.data.year ) ; / *输入年* /
printf("enter month:\n");
scanf( " %d " , &unit.data.month) ;
/ *输入月* / printf("enter day:\n");
scanf( " %d " , &unit.data.day) ; / *输入日* /
printf( " year = %d month=%d day=%d\n",
unit.data.year,unit. data. month, unit.data.day ) ; / *打印输出* /
for( i = 0 ; i < 6 ; i + + )
printf( " % d , " ,unit.byte[ i ] ) ;
/ *按字节以十进制输出* /
printf( " \ n " ) ;
}
从程序的输出结果来看,1976占两个字节,由第0、1字节构成,即7×256 + 184 = 1976。4同样占两个字节,由第2、3字节构成,0×2 56 + 4 = 4,23由第4、5字节构成, 23 = 0×256 + 23