首页 > 试题广场 >

有如下程序段,则输出?

[单选题]
有如下程序段:
#include <stdio.h>

int main() {
    char ch = -1;
    printf(" %02x, %02x", ch, (unsigned char)ch);
    return 0;
}

则输出:
  • -1,-1
  • ff,ff
  • ffffffff,ff
  • ff,ffffffff
推荐
C
%02x表示输出最少2位,不足补0.
第一个ch=-1,负数拓展到32位需要补1,所以是ffffffff
第二个先转换为无符号数ff(255), 正数拓展补0,由于最少输出2位,所以是ff
编辑于 2015-12-10 13:32:39 回复(3)
关于为什么-1输出是FFFF,如果是负数,补码等于反码+1,如果是正数,补码等于原码
发表于 2017-09-13 11:07:11 回复(0)
感觉上面的都没回答到点上;
%x默认输出unsigned int;
所以char会被自动扩展至unsigned int;
因此会扩展符号位;
而unsigned char扩展至unsigned int;
会直接用0填充;

发表于 2017-12-22 20:01:11 回复(2)
这是一道关于符号扩展的问题。
短数据类型扩展为长数据类型:①要扩展的数据类型为有符号类型,用短数据的符号位填充长数据多出来的高字节 ,-1 (11111111)扩展为int(方便转换为十六进制)即(符号位是1)11111111 11111111 11111111 11111111(ffffffff)②要扩展的数据类型为无符号的(unsigned char) ,用0来填充长数据类型的高字节,此时-1在内存的二进制存储(11111111 )扩展为int即00000000 00000000 00000000 11111111(ff)。
编辑于 2016-06-07 14:44:29 回复(9)
%x以十六进制无符号形式输出,-1转成二进制全是1,所以第一个输出8个f,第二个转换成unsigned char发生截断只有8位,所以输出ff
发表于 2015-06-23 17:40:46 回复(2)
       %x表示十六进制整数输出,所以char要扩展成四字节的int。
       负数在计算机中是以补码形式存在的,正整数的补码是本身,负数的补码是除符号位以外各位都取反加一,也就是如果一个32位的负数原来是1(符号位)00 ... ... 01, 取反后是 1(符号位)11 ... ... 10,然后再加1,就是1(符号位)11 ... ... 11,就是32个1。所以第一个是ffff。
        要扩展的数据类型为无符号的 (unsigned char)   ,用0来填充长数据类型的高字节,此时-1在内存的二进制存储(11111111  )扩展为int即00000000 00000000 00000000 11111111(ff)。
        %02x表示输出 最少 2位,不足补0.
        第一个ch=-1,负数拓展到32位需要补1,所以是ffffffff
        第二个先转换为无符号数ff(255), 正数拓展补0,由于最少输出2位,所以是ff
发表于 2017-05-10 15:18:47 回复(1)
1:压栈时int以内的整形变量都以int型压栈,常数当int型。
2:float和double都以double压栈(float自动扩展)
3:printf按照指定类型(大小)去解释栈上的数值。

                                                                  -------------月半(知乎)
发表于 2017-05-07 10:22:03 回复(0)
爬楼看了大佬们的评论,总结学到的几点: 1.%x是以十六进制输出整数(int),短数据类型则转换为int;%02x意思是至少输出两位,不足两位的左边补0。 2.短数据类型扩展为长数据类型时,先看短数据类型是有符号类型还是无符号类型,如果是有符号,则以符号位在短数据类型前填充,如果是无符号,则 在短数据类型前填充0 综上,则第一个数会被扩展为 11111111111111111111111111111111,故第一个输出ffffffff, 第二个会被扩展为 00000000000000000000000011111111,则输出为ff
发表于 2023-02-24 11:15:27 回复(0)
//科普1:
//1Byte=8bit ,即8位!
//unsigned char 为 8 bit,所以发生-1的二进制1111111111...(32个只保留后8位)

//----------------------------------------------------------------------------
//科普2:%02XX 表示以十六进制形式输出
//02 表示不足两位,前面补0输出;出过两位,不影响
//举例:
printf("%02X", 0x123);  //打印出:123
printf("%02X", 0x1); //打印出:01

编辑于 2017-08-02 16:42:29 回复(0)
#借用一下@MasterchiefCC,自己方便看
%x默认输出unsigned int;
所以char会被自动扩展至unsigned int;
因此会扩展符号位;
而unsigned char扩展至unsigned int;
会直接用0填充;
发表于 2020-05-20 22:13:26 回复(0)
计算机里面存的是补码,第一个输出是把-1强制转换成了无符号int,此时-1的补码就是ffffffff,第二个输出-1经历两次强制转换,先是无符号char,再是无符号int,变成无符号char就是ff,转成无符号int就是ff
发表于 2019-07-07 23:20:31 回复(0)
%x是十六进制整数输出,所以会发生char到int的隐式转换,插char=ff。
对于有符号性,因为是-1,所以会转换成ffffffff。对于无符号型,相当于char的值成了255,隐式转换后000000ff。
发表于 2017-08-06 16:05:56 回复(0)
C
输出格式%x,接受的参数是无符号整数,第二个参数ch字符型转化变成32为无符号int型,输出为ffffffff

编辑于 2015-12-10 13:32:39 回复(0)
对应的反汇编代码如下:
        char ch = -1;
003113DE  mov         byte ptr [ch],0FFh  
	printf("%02x, %02x", ch, (unsigned char)ch);   ;参数从右向左入栈
003113E2  movzx       eax,byte ptr [ch]                ;movzx是指“0”扩展,对应(unsigned char)ch
003113E6  mov         esi,esp  
003113E8  push        eax  
003113E9  movsx       ecx,byte ptr [ch]                ;movsx是指“符号扩展”,对应ch
003113ED  push        ecx  
003113EE  push        3158B8h  
003113F3  call        dword ptr ds:[319118h]  
003113F9  add         esp,0Ch  
003113FC  cmp         esi,esp  
003113FE  call        __RTC_CheckEsp (031113Bh)  

发表于 2017-02-13 10:07:40 回复(0)

%02x输出至少两位,以int输出

发表于 2020-02-05 15:38:58 回复(0)
%02表示至少输出两位,%x也就是输出16进制数(无符号整数4字节32位),不足的话自动补齐,正数或无符号数补0,负数补1(符号位)。
发表于 2023-10-28 14:32:24 回复(0)
一个是绝对值取反加1,一个是绝对值取反补0
发表于 2023-09-20 18:18:51 回复(0)
int型-1的存储方式为补码(32位,4字节),1111 1111 1111 1111 1111 1111 1111 1111 转换为unsigned char(8位,1字节)发生字节截断,取最后八位为1111 1111 再转换为int后为0000 0000 0000 0000 0000 0000 1111 1111 即为ff
发表于 2022-06-24 22:41:19 回复(0)
有符号提升符号位,没符提升0,搞饭了。。。。
发表于 2021-10-13 09:32:56 回复(0)
02x表示打印16进制,2位,不足两位用0补足
发表于 2019-02-16 21:10:53 回复(0)
1.printf(&ldquo;%x&rdquo;,a);a的数据类型是int,如果不是int,要强制转换成int。int为4字节,根据计算机类型不同而不同。 2.引用。 负数在计算机中是以补码形式存在的,正整数的补码是本身,负数的补码是除符号位以外各位都取反加一,也就是如果一个32位的负数原来是1(符号位)00 ... ... 01, 取反后是 1(符号位)11 ... ... 10,然后再加1,就是1(符号位)11 ... ... 11,就是32个1。所以第一个是ffff。         要扩展的数据类型为无符号的 (unsigned char)   ,用0来填充长数据类型的高字节,此时-1在内存的二进制存储(11111111  )扩展为int即00000000 00000000 00000000 11111111(ff)。         %02x表示输出 最少 2位,不足补0.         第一个ch=-1,负数拓展到32位需要补1,所以是ffffffff         第二个先转换为无符号数ff(255), 正数拓展补0,由于最少输出2位,所以是ff
编辑于 2018-10-28 18:40:39 回复(0)