union-联合体的声明和使用

联合体(或称共用体),是一种数据类型,能够在同一个内存空间中存储不同类型的数据,但不能同时访问.

定义一个联合体,和结构体类似,一个联合内有多个不同类型的成员,但是使用union关键字:

1
2
3
4
5
union num {
char c;
int i;
double d;
};

与结构体类似,这样就定义了一个联合体类型.接下来就可以使用该类型声明若干联合体变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int main() {
union num {
char c;
int i;
double d;
};
union num num1; // num1为联合体类型num的变量
num1.i = 3; // 把int值3存储在num1中
printf("%d\n",num1.i); // 输出
num1.c = 'A'; // 清除原来的3,把char值'A'存储在num1中
printf("%c\n",num1.c); // 输出
num1.d = 3.141592; // 清除原来的'A',把double值3.141592存储在num1中
printf("%.2lf\n",num1.d); // 输出
return 0;
}

同样,也可以声明联合体指针,联合体数组等.

联合体成员的初始化与赋值

有如下几种方法:

1
2
3
4
5
union num1,num2;
num1.i = 3; // 直接赋值其指定成员
num2 = num1; // 用另一个联合体变量来赋值
union num3 = {'A'}; // 初始化联合体的成员c(即第一个成员)
union num4 = {.i = 12}; // C99,使用指定初始化器,本例中指定初始化成员i

访问联合体成员的问题

与结构体不同,联合体的各个成员都共用同一段内存,这意味着当对于一个类型的成员赋值后,其他类型的成员存储的值将不再有效.此时如果直接访问其他成员,结果是未定义的.

联合体的各个成员的类型所占用的内存大小各不相同,联合体只大到足够保存其内最大的成员(例如上例中的double d,其他成员被分配于该最大成员中某一部分相同的字节中.而不是像结构体那样每个成员都有自己的空间.

注:末尾也可能添加额外的填充字符.

总结需要注意的有2点:

  1. 访问联合体的某个特定成员之前,请确保它被正确赋值.

  2. 如果在访问某个特定成员(A)之前,对另一个成员(B)赋值了,那么该特定成员(A)的值应该被认为是被破坏的,它(A)不应被访问.

    换句话说,即使在某个实现中,该内存中原来的(部分)数据仍然未变,也不能认为他们还是有效的,因为他们是共用体的一部分,应该认为其已经损坏.

  3. 对某一成员(A)赋值后,直接访问另个成员(B),结果是未定义的,得到的任何结果都是不可信的(或者说是不可靠的).


联合体比较简单,需要注意不要错误地访问未赋值的成员.

——WAHAHA 2024.2.24 我还在火车上~



上一篇:C语言教程-14_3-使用位域进行位操作

下一篇:C语言教程-14_5-枚举