You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言Union中int与double未相互覆盖的原因咨询

问题

C语言中Union类型的内存是重叠的,同一时间仅应存储一种类型的对象。但实验发现,当Union包含int和double成员时,修改其中一个成员的值后,另一个成员的输出值似乎未被破坏,仿佛内存没有重叠。

实验代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>

union Data
{
  int int_val;
  double d_val;
};

int main()
{
  union Data data = {0};
  data.d_val = 0;
  data.int_val = INT_MAX;
  printf("%f, %d\n", data.d_val, data.int_val);
  data.d_val = __DBL_MAX__;
  data.int_val = 0;
  printf("%f, %d\n", data.d_val, data.int_val);
  return EXIT_SUCCESS;
}

编译命令为gcc -g -o main main.c,运行结果:

0.000000, 2147483647
179769227765543015871544843204898548561652852981845720830741485657701606177416873137818677866537230765451463672297559953407043753842793767107723942762853526789169461948323286682454336232649253620483947928451548544466350813686932742283772637216475668546847194115014476747609904655041063083840261631978879582208.000000, 0

为何修改一个成员后,另一个成员的输出值未出现预期的破坏?

原因分析

Union的内存确实是完全重叠的,出现这种现象是数据存储特性和输出格式掩盖了内存变化,核心原因如下:

1. 数据类型的字节长度与存储格式差异

通常int占4字节,double占8字节,且double遵循IEEE754浮点标准:

  • 高字节存储符号位和指数,低字节存储尾数的低位部分。
  • 当你修改int_val时,仅覆盖了Union内存的前4字节(double的低4字节),对double的核心数值部分(指数和尾数高位)影响极小甚至可忽略。

以第一次操作为例:

  • 先将d_val设为0.0,此时Union的8字节内存全为0。
  • 再将int_val设为INT_MAX(二进制为01111111 11111111 11111111 11111111),仅修改前4字节。
  • 此时8字节的二进制对应一个IEEE754非规格化数,其数值极其接近0,printf用%f格式输出时会将其近似为0.0,导致你误以为d_val未被修改。

2. 大数的低位修改无法被输出感知

第二次操作中:

  • 先将d_val设为__DBL_MAX__,这是一个极大的浮点数,其尾数的低位部分对整体数值的影响微乎其微。
  • 再将int_val设为0,仅覆盖前4字节(double的尾数低位),这种修改带来的数值变化远小于%f格式的显示精度,因此输出时完全看不出差异。

3. Union的访问规则

C标准明确,Union中只有最后被赋值的成员是“活跃”的,访问其他成员属于未定义行为(编译器会直接按内存解析)。你的实验中看似另一个成员未被破坏,本质是内存修改的部分对该类型的数值表现影响极小,被输出格式掩盖,并非内存没有重叠。

验证方法

若要直观看到内存变化,可直接打印Union的所有内存字节:

// 在main函数中添加这段代码,修改成员后打印内存
unsigned char *p = (unsigned char *)&data;
for (int i = 0; i < sizeof(union Data); i++) {
    printf("%02x ", p[i]);
}
printf("\n");

运行后会看到,修改int_val后,Union的内存确实发生了变化,只是double的输出表现不明显。

内容的提问来源于stack exchange,提问作者Arthur Grigoryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:53:19