union 共用体

本文介绍了C++中的union共用体,包括声明、定义及如何使用。union允许不同类型的成员共享同一块内存,同一时间只能保存其中一个成员的值。通过示例展示了如何在union中使用char、int和double,并指出union的大小等于其最大成员的大小。同时,文章对比了union与struct的区别,强调了在union中赋值会覆盖其他成员,而struct则不会相互影响。
 

1. 共用体声明和共用体变量定义

  共用体(参考“共用体”百科词条)是一种特殊形式的变量,使用关键字union来定义

  共用体(有些人也叫"联合")声明和共用体变量定义与结构体十分相似。其形式为:

  union 共用体名{

  数据类型 成员名;

  数据类型 成员名;

  ...

  } 变量名;

  共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。

  下例表示声明一个共用体foo:

  union foo{

  int i;

  char c;

  double k;

  };

  再用已声明的共用体可定义共用体变量。

  例如用上面说明的共用体定义一个名为bar的共用体变量, 可写成:

  union foo bar;

  在共用体变量bar中, 整型变量i和字符变量c共用同一内存位置。

  当一个共用体被声明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度。以上例而言,最大长度是double数据类型,所以foo的内存空间就是double型的长度。

  由于union的资料成员共用一个内存空间,所以必须存取正确的成员才能正确的读取变量值,可以使用一个额外的变数或列举型态来记录最后一次使用空间的是哪个成员,例如:

  #include <iostream>

  using namespace std;

  union StateMachine {

  public:

  char character;

  int number;

  char *str;

  StateMachine(char c) {

  character = c;

  }

  StateMachine(int n) {

  number = n;

  }

  StateMachine(char* s) {

  str = s;

  }

  };

  enum State {character, number, str};

  int main() {

  State state = character;

  StateMachine machine('J');

  ...

  if(state == character)

  cout << machine.character << endl;

  ...

  return 0;

  }

  另外要注意的是,union的成员不可以为静态、引用,如果是自订型态的话,该自订型态成员不可以有建构函式、解构函式或是复制指定运算子。

2. 共用体和结构体的区别

  共用体和结构体有下列区别:

  1. 共用体和结构体都是由多个不同的数据类型成员组成, 但在任何同一时刻, 共用体只存放了一个被选中的成员, 而结构体的所有成员都存在。

  2. 对于共用体的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构体的不同成员赋值是互不影响的。

### Union共用体在小端字节序下的内存布局规则 Union共用体)是一种特殊的复合数据类型,允许多个不同的数据类型共享同一块内存区域。在C语言中,Union的内存布局遵循以下规则: 1. **内存分配**:所有成员共享同一块内存,Union的总大小等于其最大成员所需的内存大小[^3]。 2. **对齐规则**:Union的大小和对齐方式取决于其成员中要求最严格对齐的那个成员[^2]。 3. **小端字节序**:在小端字节序系统中,数据的最低有效字节存储在最低地址处,而最高有效字节存储在最高地址处[^4]。 #### 示例代码 以下是一个示例程序,展示Union在小端字节序下的内存布局规则: ```c #include <stdio.h> #include <stdint.h> union Example { int32_t n; uint8_t ch; uint16_t m; } __attribute__((packed)); int main(void) { union Example e; e.n = 0x12345678; // 设置整数值为 0x12345678 printf("e.n = %x\n", e.n); // 输出整个Union的值 printf("e.ch = %x\n", e.ch); // 输出第一个字节的值 printf("e.m = %x\n", e.m); // 输出前两个字节的值 return 0; } ``` #### 解释 - 在上述代码中,`union Example` 定义了一个包含 `int32_t`、`uint8_t` 和 `uint16_t` 的共用体。 - 当将 `e.n` 设置为 `0x12345678` 时,在小端字节序下,内存布局如下: - 地址 0: `0x78` - 地址 1: `0x56` - 地址 2: `0x34` - 地址 3: `0x12` - 对于 `e.ch`,它访问的是内存中的第一个字节,因此输出为 `0x78`[^4]。 - 对于 `e.m`,它访问的是内存中的前两个字节,因此输出为 `0x5678`[^4]。 #### 内存对齐的影响 在某些情况下,编译器可能会根据目标平台的对齐规则调整Union的大小。例如,如果Union中包含一个 `double` 类型的成员,则整个Union的大小和对齐方式可能需要满足 `double` 的要求。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值