C——Union是什么?Union和Struct这么像,区别在哪?为什么还要创造出union呢?需要在哪里使用呢?

在 C 语言中,有一种叫做union的变量,是用来在不同的情况下,存放不同类型和大小的对象的变量。这与结构体struct很相似:结构体是一个或多个变量的集合。

union 的声明方式非常简单,也与struct一模一样,如下:

union u_tag {
    
    
    int ival;
    char *sval;
} u;

可以看到,唯一的不同就是结构体中的struct变成了union

使用方法也一模一样:

//一般变量
union_name.val
//指针
union_pointer->val

二者这么像,那么二者的区别在哪里呢?或者说,为什么要弄两个这么像的东西呢?C 又不是 C++,一些功能是由不同的小组开发的,一些功能上会重叠。

首先是表面的不同,structunion在使用目的上完全不一样,union并不像struct会同时存放大括号中列出的每个变量,如果你尝试下面的代码

union u_tag {
    
    
    int a;
    int b;
} u;

int main()
{
    
    
    u.a=1;
    u.b=2;
    printf("u_tag: %d\n", u.a);
    return 0;
}

那么输出的结果为:

u_tag: 2

这里的结果不是出错了,是因为union并不会像结构体一样,去根据前面的u.a=1输出1,由于只能存放一种数据,所以后面的u.b=2覆盖了原本u存放的值。

所以说,union内部声明的变量可以理解成是一种可能,而不是实际的对象或成员变量

并且由于union内部只有一个值,所以一般不会使用相同的数据类型。至于目前包含什么数据类型,这是编程的时候需要程序员注意的。一般是用一个变量u_type,然后再用判断语句来判断当前包含的类型。

但是structunion最核心的不同,也是union诞生的理由是:分配空间的机制。

如果你用sizeof()测量下面两个数据的尺寸

union u_tag {
    
    
    int ival;
    float fval;
    char *sval;
} u;

struct s_tag {
    
    
    int ival;
    float fval;
    char *sval;
} s;

会发现,u_tag的尺寸是 8 个字节,但是s_tag的尺寸是 16 个字节 。这是因为union相当于给内部声明的数据类型留了一个最大空间,而struct是给每个数据类型都留了各自的空间。

在现在的绝大部分机器上,int类型为 4 字节,float类型为 4 字节,cahr *类型为 8 个字节。所以u就占据了最大空间,也就是 8 个字节,而s则每个都留了各自的空间,也就是 4+4+8=16 字节。

那么需要在什么时候使用union呢?
首先根据其存放一种数据的特点,可以用来做一些通用计算,比如说浮点数和整数的切换等。
其次上面的使用目的下,节省空间了。虽然这种情况下也可以使用结构体,但是上面三种数据类型就差一倍大小的情况算好的。因为内存地址分配机制,一些类型的数据的地址是由特殊要求的,比如说在一些机器上,int需要在偶数位的地址。

下面就是一个例子,但是整数的地址限制并不是在偶数,而是 4 的倍数。

struct s_tag {
    
    
    int ival;
    char a;
} s;

这个结构体的大小为 8 个字节,你可以自己试试看是不是这个大小。

并且由于编译器是顺序读取的,所以如果你写成下面这样

struct s_tag {
    
    
    int a;
    char b;
    int c;
    char d;
} s;

那么这个结构体的大小为 16 字节。这种情况下可以将同一类的数据写在一起,可以节约一些空间,如下:

struct s_tag {
    
    
    int a;
    int c;
    char b;
    char d;
} s;

这样这个结构体所占用的空间大小就为 12 字节了。而如果使用union,那么无论什么顺序,大小一直为 4 字节。随着数据类型的可能性越来越多,节约空间的必要性就凸显出来了。

希望能帮到有需要的人~

猜你喜欢

转载自blog.csdn.net/qq_33919450/article/details/130613405