一、共用体变量
今天我们来一起学习一种与结构体很像的类型:共用体。共用体与结构体一样可以定义其内部成员属性,例如:
typedef union
{
int len;
float flen;
} u_len;
这样我们就定义了一个共用体,它有两个属性,len和flen,但是与结构体不同的是这两个属性共用同一块内存区域,它们一共占用4个字节的内存空间。这一点有点不太好懂,我们可以这样理解,我们定义了一个具有4个字节的变量,而这个变量有两个别名,分别是整型变量int len和浮点型变量float flen。在使用共用体变量时就相当于使用同一个变量。例如:
u_len u;
u.len = 3;
printf("%d\n", u.len);
u.flen = 3.2;
printf("%f\n", u.flen);
值得注意的是,当使用共用体的一个属性时,这个共用体其它属性也发生了变化,因为它们占用的是同一个内存区域。所以共用体不像结构体那样,每一个属性都可以独立保存其数值,共用体只保留一个数值,我们使用哪一个属性,编译器就会为我们按哪一个属性的类型为我们提供属性的数值。所以在使用共用体我们建议要按需要对其成员进行赋值与取值,不建议用某一属性对其赋值,而用另外属性读取其值。例如:
u_len u;
u.flen = 12.3;
printf("%d\n", u.len);
1095027917
结果很奇怪,为什么给flen赋值成12.3,而使用len读取其值时变成了1095027917了呢?因为int len与float flen共用一个内存,赋值时编译器按float型为其赋值,而取值时按int型取值,由于这两种数据类型的赋值与取值方式完全不同,所以读取的结果就完全不同。所以使用共用体时要格外小心。
关于上面这个例子我们将在下一节详细讲述浮点型变量的存取方式与位移运算。
二、多层嵌套
接下来我们来看看共用体与结构体的多层嵌套问题。先来看看共用体嵌套:
typedef union
{
long int len;
float flen;
union
{
double dlen;
short slen;
};
} u_len;
其实我们分析程序可以看到这样只有共用体的设计无论嵌套多少层,都是共用同一个内存,总的内存大小就是其属性中占用内存最大的大小。上面例子中这个共用体的大小为8个字节,因为long int和double都占用8个字节。在实际编程过程我们很少这样定义共用体,有时这样定义只为了节省内存空间。
下面我们来看看共用体与结构体的嵌套
struct s_point
{
union
{
struct
{
int x;
int y;
};
struct
{
float fx;
float fy;
};
};
};
我们定了一个共用体,其中嵌套了两个结构体,一个是整型的点x和y,另一个是浮点型的点fx和fy。我们需要注意的是,在共用内部两个结构体分别作为共用体的成员属性,对于共用体来说,这两个结构体共用一块内存区域,共用8个字节的内存空间,而在结构体内部x和y彼此独立,而在另外结构体中的fx与fy彼此独立。我们可以这样理解,共用体中有8个字节的内存空间,前4个字节有两个别名叫x和fx。而后4个字节也有两个别名y和fy。而从大的角度去看就是这两个结构体共用一块8字节内存。我们再来看一个例子:
struct s_point
{
double lat;
double lon;
union
{
double sea_alt;
double rel_alt;
};
};
在这里我们有一个位置结构体position它有3个属性纬度lat、经度lon和高度,而高度则是一个共用体,它有两个成员海拔高度sea_alt和相对高度rel_alt,这两个高度共用同一块内存区域,一共占4个字节。
另外,结构体与共用体可以多层嵌套,关于这方面我们不在一一举例,请读者自己动手定义多层嵌套的例子,并思考其实际的用途。
Copyright © 2015-2023 问渠网 辽ICP备15013245号