cpp的union使用

2023-10-21 11:33:23 浏览数 (2)

union介绍

看一下下面的代码运行结果

代码语言:javascript复制
#include <iostream>
using namespace std;

union u
{
    char c;
    int n;
};

int main()
{
    cout << sizeof(u) << endl;
    return 0;
}

运行结果为4,实际上上面代码定义的union就是两个变量共用同一块内存。union的大小为最大的那一个变量。

它与结构体struct的不同就是struct需要满足内存对齐,例如下面这段代码。

代码语言:javascript复制
#include <iostream>
using namespace std;

struct s
{
    char c;
    int n;
};

int main()
{
    cout << sizeof(s) << endl;
    return 0;
}

运行结果为8,也就是其中的c与n都占据了4个字节。

还可以在union内放结构体,也可以再结构体中放union。下面的示例代码运行结果为16 16 16 8。

代码语言:javascript复制
#include <iostream>
using namespace std;

union U
{
    struct st
    {
        int x;
        long long y;
    } s;
    double z;
};

struct S
{
    union un
    {
        int x;
        long long y;
    } u;
    double z;
};

int main()
{
    cout << sizeof(U) << endl;
    cout << sizeof(U::s) << endl;
    cout << sizeof(S) << endl;
    cout << sizeof(S::u) << endl;
    return 0;
}

union判断端序

查看下面的示例代码,可以查看num的内存分布。运行结果为00001000 00000000 00000000 00000000,从最低位(LSB)开始输出,因此使用的是小端存储。

代码语言:javascript复制
#include <iostream>
 #include <bits/stdc  .h>
 using namespace std;
 ​
 union U
 {
     unsigned char bits[4];
     int num;
 };
 ​
 int main()
 {
     U u;
     u.num = 8;
     for (int i = 0; i < 4; i  )
    {
         cout << bitset<8>(u.bits[i]) << " ";
    }
     return 0;
 }

union比较短字符串

在字符串中,一般情况下比较相等是通过比较哈希值。可以通过下面的示例代码通过union快速获得短字符串的哈希值进行比较。

代码语言:javascript复制
#include <iostream>
 using namespace std;
 ​
 union U
 {
     unsigned long long hs;
     char s[8];
 };
 ​
 int main()
 {
     U u1, u2;
     memcpy(u1.s, "hello", 6);
     memcpy(u2.s, "hello1", 7);
     cout << u1.s << " " << u2.s << endl;
     cout << u1.hs << " " << u2.hs << endl;
     return 0;
 }

union取别名

在一些二维的问题中,一般都是,定义点,然后点构成了线。但是访问具体的数据就要通过line.p1.x这样的语句。

代码语言:javascript复制
struct point
 {
     int x, y;
 };
 struct line
 {
     point p1, p2;
 };

可以通过union来实现内存共享。arr数组与两个点p1、p2共享内存,访问数据更加便捷。

代码语言:javascript复制
#include <iostream>
 using namespace std;
 ​
 struct point
 {
     int x, y;
 };
 ​
 struct line
 {
     union
    {
         struct
        {
             point p1, p2;
        };
         int arr[4];
    };
 };
 int main()
 {
     line L = {0, 0, 6, 9};
     cout << L.p1.x << " " << L.p1.y << endl;
     cout << L.p2.x << " " << L.p2.y << endl;
     cout << sizeof(line) << endl;
     return 0;
 }

union实现动态类型

下面这段代码实现一个简单的动态类型。给var类型变量赋值时,会根据参数类型调用对应的构造函数,然后为union结构赋值。

代码语言:javascript复制
#include <iostream>
 using namespace std;
 ​
 struct var
 {
     union
    {
         int num;
         double dbnum;
         char *str;
    };
     var(const int &n) : num(n){};
     var(const double &dn) : dbnum(dn){};
     var(const char *s)
    {
         str = new char[strlen(s)   1];
         memcpy(str, s, strlen(s)   1);
    };
 };
 ​
 int main()
 {
     var v = 99;
     cout << v.num << endl;
     v = 10.2;
     cout << v.dbnum << endl;
     v = "hello";
     cout << v.str << endl;
     return 0;
 }

这段代码输出的结果如下

99 10.2 hello

0 人点赞