繁体   English   中英

无法理解C程序输出

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM