union pw {int i;char ch[2]; }a; main () {a.ch[0]=10; a.ch[1]=0; printf ("%d\n",a.i); } 为什么不是0

来源:学生作业帮助网 编辑:作业帮 时间:2024/05/13 23:54:16
union pw {int i;char ch[2]; }a; main () {a.ch[0]=10; a.ch[1]=0; printf (

union pw {int i;char ch[2]; }a; main () {a.ch[0]=10; a.ch[1]=0; printf ("%d\n",a.i); } 为什么不是0
union pw {int i;char ch[2]; }a; main () {a.ch[0]=10; a.ch[1]=0; printf ("%d\n",a.i); } 为什么不是0

union pw {int i;char ch[2]; }a; main () {a.ch[0]=10; a.ch[1]=0; printf ("%d\n",a.i); } 为什么不是0
要想弄清这个问题 必须要 弄清楚 什么是联合?
联合是一种可构造的数据类型,就像定义的那样
{int i;char ch[2];} 首先,你要弄清楚他占多大内存,就像 INT 占四字节,SHORT 占两字节,
它占多大呢? 测试一下 发现结果 是 4字节, 也就是它用这 四个字节 来存储 其对应的值,我们想,你一个 INT 就要占四字节 ,那CH 数组的数据放在哪里呢? 其实 这就是联合的特性,他不管那么多,他只负责对内存里的值进行 读写, 比如 这四字节的数据 是 10 05 6A 01 ,当 你用a.i 的时候 ,它的值 是 016A0510 这个补码对应的 整数值,当你用 ch时,它 的值是 10 05 这两个值,当你 修改 a.ch[1]=65; 那这四字节 产生变化 ,10 65 6A 01,这个时候 再输出 a.i 其值就发生了变化,就变成了 016A6510 这个补码对应的值, 如果 你将 a.i=1,则这四个字节的数据变成 01 00 00 00,同理,你访问 a.ch[0] 得到的是 01,a.ch[1] 得到的 00.
所以你上面 的例子 是怎么回事呢?
首先a.ch[0]=10,其值 变为 0A CC CC CC .注意没有初始化的值 为CC
然后a.ch[1]=0,其值变为 0A 00 CC CC,然后你输出,a.i 其值 应该是 CC CC 00 0A 这个补码对应的 整数值,
CCCC000A的 二进制:用计算器求 :11001100110011000000000000001010
要想求其真值 ,先减一,再取反吧,首先判断 这个数是负数,因为第一位为 1
减一后 其值:11001100110011000000000000001001
各位取反: 00110011001100111111111111110110
将上面的数 拿到计算器 里转换成 10进制,得859045878 ,又因它是 负数,所以最终结果 :
-859045878. 不知道 对不对.我没进行测试.
上面有点小问题,由于你 的a 是全局的,数据被初始化为 00 00 00 00 而非 CC CC CC CC
所以上面的计算 有点小问题,如果 你将其改成 如下 格式 :
#include
union pw
{
int i;
char ch[2];
};
void main ()
{
pw a;
a.ch[0]=10;
a.ch[1]=0;
printf ("%d\n",a.i);
}
则上面的解释 正常通过. VC6.0 经过测试