1
0
wiki/docs/开发/C/Union 结构.md

109 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: Union 结构
title: Union 结构
sidebar_position: 14
data: 2022年3月30日
---
有时需要一种数据结构不同的场合表示不同的数据类型。比如如果只用一种数据结构表示水果的“量”这种结构就需要有时是整数6个苹果有时是浮点数1.5公斤草莓)。
C 语言提供了 Union 结构,用来自定义可以灵活变更的数据结构。它内部可以包含各种属性,但同一时间只能有一个属性,因为所有属性都保存在同一个内存地址,后面写入的属性会覆盖前面的属性。这样做的最大好处是节省空间。
```c
union quantity {
short count;
float weight;
float volume;
};
```
上面示例中,`union`命令定义了一个包含三个属性的数据类型`quantity`。虽然包含三个属性,但是同一时间只能取到一个属性。最后赋值的属性,就是可以取到值的那个属性。
使用时,声明一个该类型的变量。
```c
// 写法一
union quantity q;
q.count = 4;
// 写法二
union quantity q = {.count=4};
// 写法三
union quantity q = {4};
```
上面代码展示了为 Union 结构赋值的三种写法。最后一种写法不指定属性名,就会赋值给第一个属性。
执行完上面的代码以后,`q.count`可以取到值,另外两个属性取不到值。
```c
printf("count is %i\n", q.count); // count is 4
printf("weight is %f\n", q.weight); // 未定义行为
```
如果要让`q.weight`属性可以取到值,就要先为它赋值。
```c
q.weight = 0.5;
printf("weight is %f\n", q.weight); // weight is 0.5
```
一旦为其他属性赋值,原先可以取到值的`q.count`属性就不再有效了。除了这一点Union 结构的其他用法与 Struct 结构,基本上是一致的。
Union 结构也支持指针运算符`->`。
```c
union quantity {
short count;
float weight;
float volume;
};
union quantity q;
q.count = 4;
union quantity* ptr;
ptr = &q;
printf("%d\n", ptr->count); // 4
```
上面示例中,`ptr`是`q`的指针,那么`ptr->count`等同于`q.count`。
Union 结构指针与它的属性有关,当前哪个属性能够取到值,它的指针就是对应的数据类型。
```c
union foo {
int a;
float b;
} x;
int* foo_int_p = (int *)&x;
float* foo_float_p = (float *)&x;
x.a = 12;
printf("%d\n", x.a); // 12
printf("%d\n", *foo_int_p); // 12
x.b = 3.141592;
printf("%f\n", x.b); // 3.141592
printf("%f\n", *foo_float_p); // 3.141592
```
上面示例中,`&x`是 foo 结构的指针,它的数据类型完全由当前赋值的属性决定。
typedef 命令可以为 Union 数据类型起别名。
```c
typedef union {
short count;
float weight;
float volume;
} quantity;
```
上面示例中,`union`命令定义了一个包含三个属性的数据类型,`typedef`命令为它起别名为`quantity`。
Union 结构的好处,主要是节省空间。它将一段内存空间,重用于不同类型的数据。定义了三个属性,但同一时间只用到一个,使用 Union 结构就可以节省另外两个属性的空间。Union 结构占用的内存长度,等于它内部最长属性的长度。