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

C语言中union(共用体)的成员值是如何发生变化的?

问题分析

你给出的代码如下:

#include <stdio.h>

int main()
{
 typedef union{
     int a ;
     char c;
     float f;
 } myu;
 
 myu sam;
 sam.a = 10;
 sam.f=(float)5.99;
  sam.c= 'H';

 printf("%d\n %c\n %f\n",sam.a,sam.c,sam.f);
 return 0;
}

出现你观察到的输出,核心原因是C语言**共用体(union)**的内存共享特性,具体逻辑如下:

  • 共用体的所有成员共享同一块起始地址的内存空间,整个共用体的大小等于所有成员中占用空间最大的那个的大小。在常见的x86平台下,int、float均占用4字节,char占用1字节,因此这个共用体总大小为4字节,任意时刻只会保留最后一次赋值的成员的有效内容,更早的赋值会被覆盖。
  • 你的赋值顺序为sam.a = 10 → sam.f = (float)5.99 → sam.c = 'H':
    1. 给a赋值10时,4字节内存为int 10对应的二进制值0x0000000A
    2. 给f赋值5.99时,整个4字节被完全覆盖为float 5.99对应的IEEE754单精度编码,此时a的原有值已经完全失效
    3. 最后给c赋值'H'(ASCII码为0x48),因为char只占用1字节,只会修改4字节内存中最低地址的1个字节(x86平台为小端字节序,该位置对应int的最低位字节、float尾数的最低8位),剩余3个字节仍保留float 5.99的编码内容
  • 两个输出现象的具体原因:
    1. int类型a的取值大幅变化:int会把整个4字节内存当成一个整体的整数解析,当前4字节中只有最低1字节是0x48,剩下3字节都是float 5.99的高位编码,组合出来的整数值自然和原有10完全无关,就是你看到的大数1086303816
    2. float类型f的取值几乎和原值一致:单精度float的32位结构为1位符号位、8位阶码、23位尾数,你修改的最低1字节属于尾数的最后8位,只会影响浮点数精度的最低位,带来的误差极小,因此输出结果5.990025和原值5.99几乎一致。

内容的提问来源于stack exchange,提问作者kakarot-757

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:45:07