[英]Can't understand C program output
我正在编写一些基本程序,并且我编写了该程序
#include<stdio.>
int main()
{
printf("%d\n",-1>>4);
return 0;
}
输出= -1
我不明白这是怎么回事?
是-1是2的补数,然后进行移位运算。然后再进行2的补数以产生结果。
我也想知道这个输出是怎么来的
int main()
{
unsigned int a=4;
printf("%d\n",-a>>4);
return 0;
}
结果= 268435455
首先,您要做的是不可移植的。
ISO C11规定,在6.5.7 Bitwise shift operators
:
E1 >> E2的结果是E1右移E2位位置。 如果E1具有无符号类型或E1具有符号类型和非负值,则结果的值是E1 / 2 ^ E2的商的整数部分。 如果E1具有带符号的类型和负值,则结果值是实现定义的。
因此,这样做是不明智的。
可能发生的情况是,您有一个在负值上保留符号的实现。 >>
通常可能会在左侧移零位(并且对于无符号或带负号的负数, 必须这样做),但是您的实现可能会检测到负数并将一位移入从左数第二个位置,剩下的部分保持不变。
这意味着-1
(例如:二进制1111 1111 1111 1111
)在右移后仍将具有该位模式。
您必须检查特定实现的文档以确保(标准的附录J要求实现记录实现定义的行为的选择)。
您还可以使用一些更好的样本值(例如二进制1100 0000 0000 0000
右移一位)对其进行测试,然后看看会得出什么结果(尽管当然,实现说明应该是确定的来源)。
举例来说, gcc
文档在此处提供了此信息。 由于您提到使用的是4.6.3,因此4.6.4手册可能是最接近的。
该页面上的GCC 4.6.4 Manual (also in PDF or PostScript or an HTML tarball)
链接包含标题为C implementation-defined behaviour
部分,该部分部分指出:
对有符号整数(C90 6.3,C99 6.5)进行一些按位运算的结果。
按位运算符作用于包括符号位和值位的值的表示形式,其中符号位被认为紧邻最高值位。 带符号的“ >>”通过符号扩展作用于负数。
这意味着它的作用如我所解释,左位保持不变并影响到第二个最左位:
您之所以看到不同的值的原因是:
unsigned int a=4;
printf("%d\n",-a>>4);
因为-a
由于某种原因我不确定,所以将-a
视为-4的无符号表示。 您可以通过以下方式看到它:
#include <stdio.h>
int main()
{
unsigned int a=4;
printf("%09x\n",((unsigned int)(-a))>>1);
printf("%09x\n",(-a)>>1);
printf("%09x\n",(-((int)a))>>1);
return 0;
}
输出(带注释):
07ffffffe # explicit unsigned int
07ffffffe # seemingly treated as unsigned int
0fffffffe # explicit int
我怀疑这与整数提升和ISO C11 6.5 Expressions
详细介绍的通常的算术转换有关,但我认为这已经超出了原始问题的范围。
-1具有二进制表示形式(假定2的补码):
11111111111111111111111111111111 // All ones, 32 of them if we assume 32 bit ints
右移带符号的数字时,如果符号位为1,则编译器似乎将移入1。
11111111111111111111111111111111 // All ones, 32 of them if we assume 32 bit ints
^^^^ These 4 are new
如您所见,数字保持不变,-1。
-1是FFFFFFFF,按位,因此当您右移任何位时,它仍将是FFFFFFFF,即-1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.