大家好,我又来给大家补脑了!上次好像说的是signed 吧? 今天我要说说C++中的另一个关键字——<mark>联合体—union</mark>。

union是数据类型中的<mark>非基本数据类型</mark>。

1、说一说非基本数据类型:

编程中有一个非常重要的话题——数据类型,其中分为<mark>基本数据类型</mark> 和 <mark>非基本数据类型</mark>。这两个我以后会慢慢说。

基本数据类型:

整型 <mark>int / long / long long</mark>
布尔型 <mark>bool</mark>
字符型 <mark>char</mark>
实型
→ 单精度型 / 浮点型 <mark>float</mark>
→ 双精度型 <mark>double</mark>

非基本数据类型:

数组 <mark>[ ]</mark>
指针 <mark>*</mark>
空类型 <mark>void</mark>
结构体 <mark>struct</mark>
联合体 <mark>union</mark> √
枚举 <mark>enum</mark>
类 <mark>class</mark>

2、union简介:

在 C++ 中,union 是一种特殊的数据结构,它允许在相同的内存位置存储不同的数据类型。union 可以帮助节省内存,因为它们使用相同的内存空间来存储不同的数据类型,但是只能同时存储其中一个。

在定义 union 时,所有成员共享同一块内存空间。当为 union 的某个成员赋值时,会覆盖 union 中已有的值。这也是 union 的一个特点:它不会记录哪个成员是当前有效的,因此在使用 union 时,需要确保对应的成员是正确的。

示例:

#include <iostream>
using namespace std;

union MyUnion {
   
    int i;
    double d;
    char c;
};

int main() {
   
    MyUnion u;

    u.i = 42;
    cout << "Value of integer i: " << u.i << endl;

    u.d = 3.14159;
    cout << "Value of double d: " << u.d << endl;

    u.c = 'A';
    cout << "Value of char c: " << u.c << endl;

    return 0;
}

在这个示例中,union MyUnion 可以存储一个整数、一个双精度浮点数或一个字符。在 main 函数中,我们依次给 union 的不同成员赋值,并打印出来。需要注意的是,每次赋值都会影响 union 中的全部成员。

大家是不是觉得它和结构体struct很像呢?

union:
union MyUnion {
   
    int i;
    double d;
    char c;
};
struct:
struct MyStruct {
   
    int i;
    double d;
    char c;
};

接下来我就来解释一下

3、union和struct的区别:

union 和 struct 是 C++ 中用于组织数据的两种不同方式,它们有一些关键的区别:

内存分配方式:
在 struct 中,每个成员都有自己的内存空间,它们按照在结构体中声明的顺序依次排列。
在 union 中,所有成员共享同一块内存空间,union 的大小取决于其最大的成员。
存储方式:
struct 中的成员可以同时存在,每个成员都有自己的地址。
union 中的成员共享相同的内存,同一时刻只能存储一个成员的值。
占用空间:
struct 的大小等于其所有成员大小的总和,每个成员都有独立的内存空间。
union 的大小等于其最大成员的大小。
访问方式:
在 struct 中,可以同时访问所有的成员。
在 union 中,只能访问当前存储的成员,需要确保访问的成员是有效的。
初始化:
struct 中的成员可以独立初始化。
union 的初始化通常是给第一个成员赋值,其他成员会变得不确定。

这个示例说明了 struct 和 union 的不同之处:

#include <iostream>
using namespace std;

struct MyStruct {
   
    int i;
    double d;
    char c;
};

union MyUnion {
   
    int i;
    double d;
    char c;
};

int main() {
   
    cout << "Size of struct: " << sizeof(MyStruct) << " bytes" << endl;
    cout << "Size of union: " << sizeof(MyUnion) << " bytes" << endl;

    MyStruct s;
    s.i = 42;
    s.d = 3.14;
    s.c = 'A';

    cout << "Struct values: " << s.i << ", " << s.d << ", " << s.c << endl;

    MyUnion u;
    u.i = 42;
    cout << "Union value: " << u.i << endl;

    u.d = 3.14;
    cout << "Union value after double assignment: " << u.d << endl;

    return 0;
}

在这个示例中,MyStruct 是一个<mark>包含整数、双精度浮点数和字符的结构体</mark>,而 MyUnion 是一个<mark>包含相同成员的联合</mark>。可以通过 <mark>sizeof () 运算符</mark>查看它们的大小。

使用union的注意事项:

当使用union时,有几个重要的注意事项需要考虑:

<mark>内存重叠</mark>: 因为union的所有成员共享同一块内存,所以修改一个成员可能会影响其他成员的值。这意味着必须小心确保只读取和修改当前活动的成员,否则可能会导致未定义的行为。
<mark>对齐和大小</mark>: union的大小等于其最大成员的大小,而不是所有成员的大小之和。这可能会导致内存浪费。另外,union的对齐方式通常与其最大成员的对齐方式相同。
<mark>类型转换</mark>: 由于union可以存储不同类型的值,因此必须小心处理类型转换。尝试读取一个成员时,必须确保它是最后赋值的那个成员的类型,否则可能会得到意外的结果。
<mark>可移植性</mark>: union的行为在不同的编译器和平台上可能会有所不同。例如,某些编译器可能对union的布局和内存对齐有不同的实现。因此,在编写可移植的代码时,应该尽量避免依赖于union的特定行为。
<mark>使用场景</mark>: union通常用于需要在不同数据类型之间进行临时转换或共享内存的情况。然而,在大多数情况下,使用Union可能不是最佳选择,因为它增加了代码的复杂性并且容易出错。在C++中,可以使用类型安全的联合体variant或any等替代方案来避免union的一些问题。

总之,使用union时需要小心处理内存重叠、类型转换以及可移植性等问题,以确保代码的正确性和可维护性。

完结撒花!!!

对了,我这周要去上学了,但是我会坚持每周一篇的!家人们,你们要等我的!!!