C语言联合体br成员赋值后状态及516数值成因咨询
关于联合体成员赋值与字节序的问题解答
先贴出你提供的代码:
#include <stdio.h> void f(short num, short* res){ if (num){ *res = *res * 10 + num%10; f(num / 10, res); }} typedef union { short br; struct { char a, b; } str; } un; void main() { short res = 0; un x; x.str.a = 4; x.str.b = 2; f(x.br, &res); x.br = res; printf("%d %d %d\n", x.br, x.str.a, x.str.b); }
1. 给x.str.a和x.str.b赋值后,br会怎么变?
联合体的本质是所有成员共用同一块内存空间。这里br是占2字节的short类型,str是两个各占1字节的char组成的结构体,刚好也是2字节,所以两者完全复用同一段内存。
当你给x.str.a=4、x.str.b=2赋值后,br的具体数值取决于系统的字节序(多字节数据在内存中的存储顺序):
- 如果是小端字节序(现在绝大多数电脑采用的模式):低地址存低字节,高地址存高字节。
str.a会放在内存的低地址位,str.b放在高地址位。此时br的数值为str.b*256 + str.a(高地址字节对应short的高位),计算得2*256+4=516。 - 如果是大端字节序,结果会是
4*256+2=1026。
2. 调用函数f前需要提前设置br的值吗?
完全不需要。因为联合体成员共享内存,你给str.a和str.b赋值时,已经覆盖了br所在的内存区域,此时直接读取x.br就能拿到有效的数值,无需额外设置。
3. 为什么调用函数前br的值是516?
这是因为你使用的模拟器运行在小端字节序环境下:
x.str.a=4对应十六进制0x04,存在内存的低地址位置;x.str.b=2对应十六进制0x02,存在内存的高地址位置;br作为short类型读取这两个字节时,会把高地址的0x02当作数值高位,低地址的0x04当作低位,组合成十六进制0x0204,转换为十进制就是516。
额外补充:函数f的作用是递归反转数字的各位,输入516的话,最终res会变成615。之后x.br=615,此时str.a和str.b对应的数值是615拆分后的字节:615的十六进制是0x267,小端模式下低地址是0x67(十进制103),高地址是0x02(十进制2),所以最终printf会输出615 103 2。
内容的提问来源于stack exchange,提问作者luise
相关产品推荐
相关产品推荐

