一道C语言共用体程序题

来源:百度知道 编辑:UC知道 时间:2024/09/21 06:42:10
main()
{union bt
{int k;
char c[2];
}a;
a.k=-7;
printf("%o,%o,%o\n",a.c[0],a.c[1],a.k);
}
编译运行后输出结果为:177771,177777,177771。a.c[0],a.c[1]长度不是一个字节吗,它们应当分别为k的低8位和高8位,怎么会输出这样的结果,很不明白,还请那位高手给解释一下。
我再补充一下177771是-7的补码8进制输出(16位),我的意思是以前看到类似的题好像a.c[0]输出的是整数k的低八位(如a.k=0x3938,用16进制输出为为38,39,3938),这里怎么a.c[0]会输出16位呢,并且和a.k相同,a.c[1]又是什么?

我来解释解释吧
main()
{union bt
{int k;
char c[2];
}a;
a.k=-7;
//printf("%d,%d,%d\n",a.c[0],a.c[1],a.k);
printf("%d,%d,%d,%d\n",&a.k,&a.c,&a.c[0],&a.c[1]);
}

printf("%d,%d,%d\n",a.c[0],a.c[1],a.k);
当输入-7,则-7,-1,-7
当输入7,则 7,0,7
其实根本问题就是数据在计算机中的存储问题。
首先共用体是共用内存的,即共用体中每个成员都有相同的首地址。
你可以把这句执行看一下:
printf("%d,%d,%d,%d\n",&a.k,&a.c,&a.c[0],&a.c[1]);
共用体的长度是最长一个成员的长度,所以该共用体的长度sizeof(a)=sizeof(a.k)。

7的原码是:00000000|八个0|八个0|00000111,
a.k=-7,内存模式是:11111111|八个1|八个1|11111001,
a.c[0]和其首地址相同,所以a.c[0]在内存中是11111001(一个字节),
当以%d格式输出时要进行符号扩展,扩展到4个字节,所以和-7有相同的内存模式,所以输出-7;
a.c[1]是八个1(一个字节),当以%d格式输出时也要进行符号扩展,扩展后与-1有相同的内存模式,所以输出为-1。

当输入是7时,是同样的道理,你可以自己分析一下。
(符号扩展:当最高位是1时,全部以1填充,当最高位是0时,全部以0填充)

读出的是你给的地址后面的东西,并不是说你给了什么形式的数据就输出什么的。而是你用什么方式来输出,PRINTF就会将后面的对应的32位的内容输出。并不好似你给个八位的字节数据就只读八位。
在我的机器上是:
377777