C语言联合体union用法详细解读

2021年4月5日16:03:07 发表评论 1,235 次浏览

喜欢结构体, union是用户定义的数据类型。在联合体中, 所有成员共享相同的内存位置。

C语言联合体

例如, 在下面的C程序中, x和y共享相同的位置。如果更改x, 我们可以看到更改反映在y中。

#include <stdio.h>
  
// Declaration of union is same as structures
union test {
     int x, y;
};
  
int main()
{
     // A union variable t
     union test t;
  
     t.x = 2; // t.y also gets value 2
     printf ( "After making x = 2:\n x = %d, y = %d\n\n" , t.x, t.y);
  
     t.y = 10; // t.x is also updated to 10
     printf ( "After making y = 10:\n x = %d, y = %d\n\n" , t.x, t.y);
     return 0;
}

输出如下:

After making x = 2:
 x = 2, y = 2

After making y = 10:
 x = 10, y = 10

联合体的大小如何由编译器决定?

联合体的大小是根据联合体中最大成员的大小得出的。

#include <stdio.h>
  
union test1 {
     int x;
     int y;
} Test1;
  
union test2 {
     int x;
     char y;
} Test2;
  
union test3 {
     int arr[10];
     char y;
} Test3;
  
int main()
{
     printf ( "sizeof(test1) = %lu, sizeof(test2) = %lu, "
            "sizeof(test3) = %lu" , sizeof (Test1), sizeof (Test2), sizeof (Test3));
     return 0;
}

输出如下:

sizeof(test1) = 4, sizeof(test2) = 4, sizeof(test3) = 40

联合体的指针

像结构一样, 我们可以具有指向联合的指针, 并且可以使用箭头运算符(->)访问成员。下面的示例演示了相同的内容。

#include <stdio.h>
  
union test {
     int x;
     char y;
};
  
int main()
{
     union test p1;
     p1.x = 65;
  
     // p2 is a pointer to union p1
     union test* p2 = &p1;
  
     // Accessing union members using pointer
     printf ( "%d %c" , p2->x, p2->y);
     return 0;
}

输出如下:

65 A

联合体有什么用途

在许多情况下, 如果我们要为两个或更多成员使用相同的内存, 则联合体会很有用。例如, 假设我们要实现一个二叉树数据结构, 其中每个叶节点都有一个双精度数据值, 而每个内部节点都有指向两个孩子的指针, 但没有数据。如果我们声明为:

struct NODE {
     struct NODE* left;
     struct NODE* right;
     double data;
};

那么每个节点都需要16个字节, 每种类型的节点浪费了一半的字节。另一方面, 如果我们声明一个节点如下, 则可以节省空间。

struct NODE {
     bool is_leaf;
     union {
         struct
         {
             struct NODE* left;
             struct NODE* right;
         } internal;
         double data;
     } info;
};

上面的例子取自计算机系统:程序员的观点(英语)第二版书。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: