我很难理解以下程序的输出。
int main(){
char y = 0x02;
y = y-0x03;
printf("0x%x %d",y,sizeof(y));
return 0;
}
我得到的输出是
0xffffffff 1
我知道到目前为止,如果我添加两个十六进制值,则会添加其二进制值。使用借用概念进行减法也是如此(如果我错了,请纠正我)
实例
111 - 001 = 110(二进制) 110 - 001 = 101(使用第一个操作数中第二个LSB的进位)
如果值为overflow char
,则在添加两个十六进制值时,它们基本上是mod 256.即如果我将程序编写为
int main(){
char y = 0x03;
y = y+0xff;
printf("0x%x",y);
return 0;
}
我会得到
的输出0X2
但是在减法的情况下,如果我运行第一个程序,预期的输出应该是
0xff的
所以我的问题是因为上面的减法应该是
00000010 - 00000011
二进制,借款来自哪里? 为什么我得到这个
0xffffffff的
奇怪的输出?
答案 0 :(得分:4)
答案的两个部分:
set iterationTimes=4
for /l %%i in (0,1,%iterationTimes%) do (
call matlab -nodesktop -nosplash -r "loop=%%i%%;"%stitchFile%
call %IJPath% -macro %JythonPath% %%arg%%
)
的参数 - 或任何可变函数的printf()
部分 - 都会进行默认促销。对于类型...
,这意味着该值将转换为char
。
您已在计算机上签名int
,因此该值已进行符号扩展。也就是说,char
中存储的0xFF会转换为y
,这就是您看到的内容。
如果您有一个支持足够现代的printf()
规范的库,您可以使用:
0xFFFFFFFF
printf("%hhx %zu\n", y, sizeof(y));
说'转换为hhx
,然后打印'。 char
长度修饰符z
是打印%zu
值的正确格式之一,例如size_t
返回的值。如果做不到这一点,请使用sizeof()
或y & 0xFF
代替普通(unsigned char)y
作为y
的参数。
答案 1 :(得分:1)
我知道到目前为止,如果我添加两个十六进制值,它们就是 转换为二进制,然后添加。这样做也是如此 使用借用概念减法(如果我是,请纠正我 错)
你错了。十六进制,十进制,八进制等是表示数字的形式。在其下方始终是一系列位。
由于%x
格式规范,您获得了“奇怪”的输出。您的1字节char值将转换为unsigned int。
答案 2 :(得分:0)
今天大多数计算机系统使用two's complement来表示负数。在该系统中,负数表示为比它们absolute value小1的按位反转。以这种方式表示的负数是1 - 1 = 0的按位反转,其所有位都打开。
另外,请注意C中的带符号溢出为undefined behavior,因此除非您使用像gcc' s -fwrapv
这样的编译器选项,否则上面的mod 256示例不会得到保证工作。
答案 3 :(得分:0)
这是因为一个名为整数促销的棘手概念。
基本上,您的单字节字符被转换为4字节整数来处理您的操作。所以:
0x02 - 0x03
变为:
0x00000002 - 0x00000003
碰巧是0xffffffff(因为那是-1如何将-1表示为整数)。