联合
1.概念
联合也叫做共用体,是C语言中一种高级的数据结构,在编码过程中,合理的使用联合可以节省内存空间,简化多种复杂数据的处理。联合有点类似于结构体。
两者的区别在于结构体定义了 由多个数据成员组成的 占用多块内存的特殊类型,而联合定义了 只有一块 由所有数据成员共享的内存 的数据类型。
联合(union)是一种数据类型,它能在同一个内存空间中存储不同的数据类型(不是同时存储)。联合的声明和结构体类似,行为方式却和结构体完全不同。
联合的所有成员引用的是内存中相同的位置。联合在某一时刻,只能有一个值。联合可以将几种不同类型的变量存放到同一段内存单元中,因此联合的大小等于在其中最大成员所占用内存的大小。
2.定义:
union 联合名
{
成员列表;
} 变量列表;
举例:
①
union hold
{
int data;
double bigfl;
char letter;
};
union hold fit; hold类型的联合变量。
union hold fitarray[10]; 内含10个联合变量的数组
union hold* p_fit; 指向hold类型联合变量的指针
②
union hold
{
int data;
double bigfl;
char letter;
} fit, fitarray[10], *p_fit;
① 和 ② 是等价的,一个是先定义联合模板,然后定义联合变量;
一个是在定义联合模板的时候同时定义联合变量。
③
与结构体对比
struct hold
{
int data;
double bigfl;
char letter;
};
结构体③可以存储一个int型数据、一个double型数据 和 一个char型数据。而①②只能存储一个int型数据
或者 一个double型数据
或者 一个char型数据。
根据以上形式声明可知,结构体可以存储一个int类型、一个double类型和char类型的值。然而,声明的联合只能存储一个int类型的值或一个double类型的值或char类型的值。
需要注意的是,联合只能存储一个值,这与结构不同。
3.联合初始化
联合变量可以被初始化,但是被赋予的初始值必须和联合模板的第一个成员的类型相同,而且该值必须放在一对花括号里。
初始化有三种方法:
①初始化联合的第一个元素;
②把一个联合初始化为另一个联合;
③如果编译器支持C99标准,可以使用指定初始化器。
举例:
union hold fit = {10}; ①
fit. letter = ‘H’;
union hold pua = fit; ②
union hold yichen = { . bigfl = 99.99}; ③
对于①不能把 hold 这个联合变量初始化为浮点数或字符值,如果初始值是其他的类型,编译器会进行转换(如果可以),并将转换后的整数赋值给fit. data。
4.联合的引用
联合也要先定义再引用,引用的形式如下:
联合变量.成员名
fit. letter
注意:不能引用联合变量,只能引用联合变量的成员
5.内存占用
在①②中,如果是32位系统机,hold联合中的成员占用空间最大的为double类型,占64位,共8个字节。
而struct占用24个字节。(见博客 《边界对齐》)
6.应用场景
联合可以在不同的时刻把不同的东西存在同一个位置。
它可以存储既无规律,事先也不知道类型的数据表。
fit.data = 66; 把66存储在fit,占用2个字节
fit. bigfl = 99.99; 把99.99存储在fit,占用8个字节
fit. letter = ‘H’; 把H存储在fit,占用1个字节
使用指针访问结构体是需要使用 -> 运算符,使用指针访问联合时,也是如此。
举例:
p_fit = &fit;
x = p_fit -> data;
用一个成员把值存储在联合中,然后用另一个成员查看内容,这种方法有时可以提高编程效率。
union fi_ctrl
{
float f;
int i;
}fi_data;
fi_data.f = 3.1415;
n = fi_data.i;
n可以用作其他的功能处理。在后面《联合进阶》博客中会详细讲述。
7.总结
①同一段内存位置可以用来存放几种不同类型的成员,但是每一次只能存放其中的一种类型,不能同时存放所有类型的数据!也就是说,在某个时刻,联合只有一个成员起作用,其他成员不起作用。
②联合变量所占用的内存空间 等于它最大成员所占的内存空间。
③联合变量使用时,起作用的是最后一次存放的成员,在存入一个新的成员后,原来的成员就会失去作用。因此,在使用联合时应该注意,当前在联合变量中存放的究竟是哪个成员。
④联合变量的地址和其各个成员的地址是同一个地址。
⑤不能对联合变量名赋值,也不能企图引用联合变量名来得到一个值。
⑥不能用联合变量作为函数的参数或者是返回值,当需要在函数间传递联合变量时,可以使用指向联合变量的指针来实现!