首页 > 试题广场 >

问题:在80X86架构下,输出什么值?

[单选题]
union Test {
    char a[4];
    short b;
 };
 Test test;
 test.a[0] = 256;
 test.a[1] = 255;
 test.a[2] = 254;
 test.a[3] = 253;
 printf("%d\n", test.b);
问题:在80X86架构下,输出什么值?
  • -128
  • -256
  • 128
  • 256
推荐
答案:选B
答案解析:首先要知道大小端模式,80X86下是小端模式;当然可以编写下测试就可以了,short占2个字节,设左高地址,右低地址;
  a[1]           a[0]
1111 1111     0000 0000
short占用的是这a[1]、a[0]两个字节,最高位是1是一个负数,在计算机中采用补码表示,那么二进制表示为:1000 0001 0000 0000,转化为十进制就是-256.
编辑于 2015-02-03 12:09:26 回复(12)
char类型的取值范围是-128~127,unsigned char的取值范围是0~255
这里a[0]=256,出现了正溢出,将其转换到取值范围内就是0,即a[0]=0;
同理,a[1]=-1, a[2]=-2, a[3]=-3,在C语言标准里面,用补码表示有符号数,故其在计算机中的表示形式如下:
a[0]=0,     0000 0000
a[1]=-1,    1111 1111
a[2]=-2,    1111 1110
a[3]=-3,    1111 1101
short是2字节(a[0]和a[1]),由于80X86是小端模式,即数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,在本例中,a[0]中存放的是b的低位,a[1]中存放的是b的高位,即b的二进制表示是:1111 1111 0000 0000,表示-256,故选B。

编辑于 2019-03-24 13:38:59 回复(6)
char为8位,赋值时直接取低8位即可。
a[0] = 0000 0000
a[1] = 1111 1111
a[2] = 1111 1110
a[3] = 1111 1101
short为16位,从a的首地址开始前16位为b。
80X86架构 小端寻址(低位低地址,高位高地址),故 b = 1111 1111 0000 0000 。
符号位为1,因此b为负数。
负数原码 = 取反(补码-1)=~( 111 1111 0000 0000 - 1 )= 000 0001 0000 0000=256。
故b=-256。
发表于 2015-09-07 21:38:40 回复(10)
注意Test是union结构,这种结构里成员a和b地址相同,输出a也是输出b。题目里只初始化了a,所以输出b相当于从a的地址输出16位,所以结果是256.在VS里输出&test.a和&test.b的地址是相同的。
但是如果Test不是union,是struct类型,那么a和b的地址是不同的,大端小端模式也就没什么意义了,输出b的结果是没初始化的随机数。
发表于 2015-11-14 22:52:27 回复(0)
test中
a[0]-->0x002DFB18  00
a[1]-->0x002DFB19  ff
a[2]-->0x002DFB1a  fe
a[3]-->0x002DFB1b  fd

由于80X86是小端模式,即数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,
在本例中,a[0]中存放的是b的低位,a[1]中存放的是b的高位,所以b是ff00,二进制表示是:1111 1111 0000 0000
以上是补码,转化为源码就是
符号位为1,因此b为负数。
负数的补码求原码和负数的原码求补码的方法一样:除符号位外,每位求反,末位加一。
负数原码 = ~1111 1111 0000 0000+1=1000 0000 1111 1111 +1=1000 0001 0000 0000=-256
故b=-256。
发表于 2016-10-25 17:51:46 回复(4)
本题考察点有
1. char所占字节大小和short所占字节, 以及union的内存模型.
2. 大端小端问题
3. 原码补码转换问题
原码 = 最高位(符号位) + 取反(补码去掉最高-1)
a[0] = 256 = (1 0000 0000)补码 = (0000 0000)补码 = +0
a[1] = 255 = (1111 1111)补码 = (1000 0001)原码 = -1
a[2] = 254 = (1111 1110)补码 = (1000 0010)原码 = -2
a[3] = 253 = (1111 1101)补码 = (1000 0011)原码 = -3
小端模式下
b = (1111 1111 0000 0000)补码 = (1000 0001 0000 0000)原码 = -256
发表于 2017-04-30 20:47:42 回复(3)

局部变量存储在栈内,从高位存储到低位;类、结构体、数组是从低位到高位存储;小端口模式是低数据位存在低位,高数据位存在高位;而union只有一个共同的存储内存,所以变量的数据只能刷新式赋值,所以text.b没有重新赋值就只能从共同的内存地址出取值。
发表于 2020-03-01 22:12:24 回复(1)
楼上水牛丙说的正确
给char赋值int采用低位截断 
a[0] = 0000 0000
a[1] = 1111 1111
a[2] = 1111 1110
a[3] = 1111 1101
X86为小端存储
因此short读取到的为1111 1111 0000 0000 对应补码为-256
发表于 2022-03-16 10:13:35 回复(0)
要点分析:
1、联合体union是共用一块内存地址的,
2、char类型的取值范围是 -128~127,unsigned char的取值范围是0~255
2、short占2个字节
3、80x86采用小端存储,即低位存低址,高位存高址
所以b占用a[0]、a[1]即0000 0000 和 1111 1111
二进制即  1111  1111   0000  0000(第一位为符号位)
补码为     1000  0001 0000   0000 即 -256
发表于 2018-09-02 21:07:07 回复(0)

char a[0]=256;
val=-128+(256-128)%256=0            ====>a[0]:00000000
char a[1]=255;
val=-128+(255-128)%256=-1            ====>a[1]:11111111
10000001(-1源码)
11111110(-1反码)
11111111(-1补码)

80X86-->小端模式 数据低位--->内存低地址
test共4字节
            test     XXXXXXXX   XXXXXXXX   XXXXXXXX   XXXXXXXX
低地址 a[0]                                                              00000000
            a[1]                                           11111111
            a[2]                        ........
            a[3]    ........

====>short 11111111 00000000(补码)
                   10000000 11111111( 反码)
                   10000001 00000000(源码-256)
发表于 2017-01-07 13:12:40 回复(0)
大端:高位的数据放在低地址的内存中
0886是小端,高位数据放在高地址的内存
另外,程序中的数字,无论大小在内存中时一个int的长度的,这里是32位
而char是8位,所以,把int的数据的低8位付给char。
还要注意的是,这里的char是有符号的,所以要看看高位是1还是0
发表于 2016-08-22 17:20:14 回复(0)
1.知识点数字在计算机中都是以补码形式存在。 由于256为正数所以补码等于源码及a(0)=1 0000 0000 由于char数据类型8字节所以截断,及a(0)=0000 0000 同理a(1)=1111 1111 ....... 2.知识点nuion公用内存,小端存储 所以b=1111 1111 0000 0000 在去一次补码及得b的源码1000 0001 0000 0000
发表于 2022-12-21 12:18:13 回复(0)
前面给char赋值时,将int做了截断
发表于 2017-02-20 22:09:02 回复(0)
X86是小端模式,

发表于 2016-05-20 20:54:02 回复(0)
a[0]赋值超出范围,采用截断策略,高位丢弃
则,a[0] = 0000 0000;
80X86采用小端模式对应 
     a[1]           a[0]
=> 1111 1111 0000 0000
=>1000 0001 0000 0000
=>-256
编辑于 2023-11-23 17:05:14 回复(0)
union 联合结构 一个值的不同表达 注意小端大端
发表于 2016-07-06 14:58:31 回复(0)
数据越界,按原码存储,所以b在内存中存储的是1111 1111 0000 0000 往外打印数据的时候,最高位为1,所以按补码输出
发表于 2022-09-07 16:08:22 回复(0)
union结构:成员共享内存 x86:小端,低位开始
发表于 2022-03-17 23:21:11 回复(0)
union 为共用结构体 因此它俩开始于相同的地址 共用两个字节空间即16个比特位
char为8位,赋值时直接取低8位即可。
由于正数的原反补相同    且从低地址到高地址取八位
a[0] = 0000 0000
a[1] = 1111 1111
a[2] = 1111 1110
a[3] = 1111 1101
short为16位,从a的首地址开始前16位为b。
80X86架构 小端寻址(低位低地址,高位高地址)
即数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,在本例中,a[0]中存放的是b的低位,a[1]中存放的是b的高位
一般左边为高地址 右边为低地址
故 b = 1111 1111 0000 0000 。
符号位为1,因此b为负数。
补码转化之后
负数原码 =-256。
故b=-256。

发表于 2021-10-09 15:41:15 回复(0)
<p>X86为小端模式,故低位存储于低地址中,short占两个字节,b=a[1]a[0],a[1]为1111 1111,a[0]为0000 0000,计算机中负数以补码形式存储(保留最高位,其余位取反再加1,即1000 0001,故b=a[1]a[0]=1000 0001 0000 0000=–256=B.(最高位为1即为负数)</p>
发表于 2021-03-31 11:02:45 回复(0)
小端格式,且存放的是补码
发表于 2021-03-12 09:38:00 回复(0)