首页 > 试题广场 >

​​ 假设在上下文和头文件正常的情况下,下列代码输出多少?

[单选题]
unsigned short A = 10; 
printf("~A = %u\n", ~A); 
char c = 128; 
printf("c=%d\n", c);


输出多少?
  • 10   128
  • -11 -128
  • 4294967285   -128
  • -11 128
推荐
第一个,~A =0xfffffff5,int值 为-11,但输出的是uint。所以输出4294967285
第二个,c=0x10,输出的是int,最高位为1,是负数,所以它的值就是0x00的补码就是128,所以输出-128。这两道题都是在考察二进制向int或uint转换时的最高位处理。
编辑于 2015-02-02 17:43:01 回复(10)
最终输出的结果~A,c与变量A和变量c的定义无关,只与%u,%d有关,这俩决定最终输出的格式
发表于 2016-02-17 23:25:35 回复(0)
shor和char的无符号和有符号形式都会先转换为int型。
unsigned short A=10转换为int型类0x0000000a,按位取反为0xfffffff5,若按%d形式输出,由于是补码形式存储的,所以0xfffffff5的原码为0x8000000b,也就是-11;此时是按%u无符号形式输出,结果为15*16^7+15^16^6+15*16^5+15*16^4+15*16^3+15*16^2+15*16+5=4294967285;
char c=128先转化为int类型,为0xffffff80,以%d输出,转换为原码为0x80000080,也就是-16*8=-128


发表于 2015-07-28 11:30:09 回复(6)
楼上都说的很好,第一个很好理解,第二个涉及到了短数据转换为长数据时候的符号位扩展问题,具体如下:

关于符号扩展

一、短数据类型扩展为长数据类型

1、要扩展的短数据类型为有符号数的

       进行符号扩展,即短数据类型的符号位填充到长数据类型的高字节位(即比短数据类型多出的那一部分),保证扩展后的数值大小不变

如1:char x=10001001b;   short y=x;   y 的值应为 11111111 10001001b

    2 char x=00001001b;   short y=x;   y 的值应为 00000000 00001001b

2、要扩展的短数据类型为无符号数的

     进行零扩展,即用零来填充长数据类型的高字节位

如1:unsigned char x=10001001b;   short y=x;   y 的值应为 00000000 10001001b

    2 unsigned char x=00001001b;   short y=x;   y 的值应为 00000000 00001001b
参考链接更详细:http://blog.sina.com.cn/s/blog_6adcb3530101cmsd.html
发表于 2015-08-21 14:58:23 回复(3)
  A的16位二进制表示为:                                    0000 0000 0000 1010
  A的32位二进制表示为:0000 0000 0000 0000 0000 0000 0000 1010
~A的32位二进制表示为:1111 1111 1111 1111 1111 1111 1111 0101
因为按%u输出,所以最高位的1表示数值,不表示符号。由于32位全1的值等于(2^32-1),所以~A=(2^32-1)-10=4294967285
     128的二进制表示为:                                 1 0000 0000 0000 0000
  c的  8位二进制表示为:                                    0000 0000 0000 0000
  c的32位二进制表示为:1111 1111 1111 1111 0000 0000 0000 0000
 因为按%d输出,所以最高位的1表示符号。有符号数使用补码表示,所以取反加1后等于-128
 
发表于 2017-03-22 21:53:03 回复(2)
第一个就是把0转化为1,把1转化为0,其实就是32个1减去10,即为4294967285
第二个前面的说的很好,可以用补码的思路一补一补就可以算出来,还可以这样,char的范围是-128到127,而在C语言中是循环的,即最大值加一变为最小值最小值减一变为最大值,故128转化为int即为-128.
发表于 2017-05-16 00:05:55 回复(0)

%d 有符号32位整数

%u 无符号32位整数

发表于 2015-08-29 15:15:38 回复(0)
unsigned short最大为2^16-1,A=10,~A=2^16-1-10,输出说明符为%u,所以按unsigned int输出,~A符号扩展,输出2^32-1-10
char范围-128~+127,所以128保存在c里int值为-128, %d按int输出,为-128
发表于 2016-09-14 09:17:51 回复(7)
类型转换,先转长度,再转符号。本题只涉及长短转换,有符号数位数变多时,用符号位填充高位,无符号数位数变多时,用0填充高位。
编辑于 2019-04-28 09:47:31 回复(0)
这题出的不好,应该声明操作系统是多少位的
发表于 2017-09-06 15:18:20 回复(0)
char c = 128;
先转化为int类型,为

0xffffff80----------------------补码
0x80000080------------------源码 -128
发表于 2016-04-16 18:40:41 回复(0)
  1. 符号扩展:当用更多的内存存储某一个有符号数时,由于符号位位于该数的第一位,扩展之后,符号位仍然需要位于第一位,所以,当扩展一个负数的时候需要将扩展的高位全赋为1.对于正数而言,符号扩展和零扩展是一样的,因为符号位就是0. 
    比如一个用一个8位二进制表示-1,则是10000001 
    如果把这个书用16位二进制表示时,则为11111111 10000001 高位全都是1,这个叫做符号扩展,主要用于对其操作数。 

    零扩展就是全补零。不论其符号位是多少,高8位全都补0.

    能过上面的定义可以看出在C++中,如果把一个char向一个整形转换的时候,就会存在着这个问题

    如果你想得到一个正数,那么如果一个字符的ASCII码值是小于零的,而直接用(int)c进行强制类型转换,结果是通过符号扩展得到的也为一个负数。要得到正数,一定要用(int)(unsigned char)c;因为unsigned char去除了c的符号位,所以,这样的类型转换后,再用(int)进行转换得到的就是一个正数。

A是u short的10,unint原码0000 0000 0000 0000 0000 0000 0000 1010,因为是整数,补码也是这个,电脑里存的就还是0000 0000 0000 0000 0000 0000 0000 1010,按位取反,得到~A为1111 1111 1111 1111 1111 1111 1111 0101,最后%u输出,又变成无符号的int了,2的32次方为4 294 967 296,所以答案就是这串东西。
char c=128,存储为1000 0000,因为有符号字符型的范围是-128~127,这个128溢出了1,就变为-128
发表于 2022-03-18 17:42:32 回复(0)
根据一楼评论,长知识了,%u 时候,short char 会转换int 输出,16位变成了32位
发表于 2018-04-07 10:25:15 回复(0)
c之所以是-128,是因为128在机器中以补码形式存在[1000 0000],然后因扩展成int类型,所以为[1111 1111 1111 1111 1111 1111 1000 0000],此时该数是补码,需-1并取反转换成源码[1000 0000 0000 0000 0000 0000 1000 0000],即-128
编辑于 2024-03-04 11:53:23 回复(0)
这题第一个非常好理解, 主要就是第二个输出. 我从汇编语言的角度来解释一下
0040148C | mov byte ptr ss:[esp+1D],80             |
00401491 | movsx eax,byte ptr ss:[esp+1D]          |
00401496 | mov dword ptr ss:[esp+4],eax            |
0040149A | mov dword ptr ss:[esp],01.40506D        | [esp]:"~A = %u\n", 40506D:"c=%d\n"
004014A1 | call <JMP.&printf>                      |
  • 第一行汇编: 其实就是对应着char c = 128;只不过这里是按照16进制的编码来的
  • 第二行汇编实际上就是把c变量当成一个有符号数, movsx实际上就是把80存到EAX寄存器当中, 并且高维填补符号位, 而0x80最高位是1, 所以当前eax当中的值是FFFFFF80. (这里其实就是C语言char类型的变量强制转换成有符号int类型的变量的过程, 计算机底层就是做了这么一件事)
  • 把eax当中的值放到堆栈当中
  • 把要输出的字符格式放到堆栈当中
  • 调用printf进行打印
总的来说这道题128是故意选的, 如果你选其他的数只要最高位不是1, 即1xxx xxxx这种的数字, 就很难发现这个问题.


发表于 2023-08-12 21:04:32 回复(0)
问题关键:
若为无符号的数据:

char向int转换时,要用‘0’补充高位数据的空缺;
若为有符号的数据:
char向int转换时,正数要用’0’补充高位数据的空缺;
负数要用’1’补充高位数据的空缺。
所以:
128(1000 0000)补码:(1000 0000)拓展为int类型:补码(1111 1111 1000 0000),符号位不变,减1取反 原码(1000 0000 1000 0000)化为十进制数为-128
发表于 2023-04-10 11:22:05 回复(1)
128(1000 0000)补码:(1000 0000)拓展为int类型:(1111 1111 1000 0000),符号位不变,取反加一:(1000 0000 1000 0000)化为十进制数为-128
发表于 2022-07-17 06:40:41 回复(0)
有符号char 是从-128到127的范围  127+1=-128😎
无符号的char 从0 到255 😜
~A是按位取反  %u是无符号的十进制输出
 short 10原来的二进制表达为00001010  要进行整形提升为00000000000000000000000000001010
                                                                    ~按位取反后为1111111111111111111111111111111110101
                                                                     因为%u为无符号计算所以按十进制计算结果为4294967285
初学者(个人拙见)
发表于 2022-04-10 17:48:41 回复(1)
马了原来还有一个~按位取反大意了
发表于 2021-10-07 10:01:08 回复(0)
关于符号扩展 一、短数据类型扩展为长数据类型 1、要扩展的短数据类型为有符号数的 进行符号扩展,即短数据类型的符号位填充到长数据类型的高字节位(即比短数据类型多出的那一部分),保证扩展后的数值大小不变 如1:char x=10001001b; short y=x; 则 y 的值应为 11111111 10001001b ; 2 : char x=00001001b; short y=x; 则 y 的值应为 00000000 00001001b ; 2、要扩展的短数据类型为无符号数的 进行零扩展,即用零来填充长数据类型的高字节位 如1:unsigned char x=10001001b; short y=x; 则 y 的值应为 00000000 10001001b ; 2 : unsigned char x=00001001b; short y=x; 则 y 的值应为 00000000 00001001b ; 参考链接更详细:http://blog.sina.com.cn/s/blog_6adcb3530101cmsd.htm
发表于 2021-07-01 08:26:12 回复(0)
<p>1. unsigned short:2字节,16位</p><p> A=10,二进制为</p><p> 0000 0000 0000 0000 0000 0000 0000 1010</p><p> 取反后为</p><p> 1111 1111 1111 1111 1111 1111 1111 0101</p><p> 即0xFFFFFFF5</p><p> </p>
发表于 2020-04-29 16:55:33 回复(0)