无法理解C程序输出

标签 c

我正在制作一些基本程序,并且我制作了这个程序

 #include<stdio.>
 int main()
 {
   printf("%d\n",-1>>4);
   return 0;
 }

输出=-1

我不明白这是怎么发生的?

is -1 是先对 2 求补,然后进行移位运算,然后再对 2 求补得出结果。

我也想知道这个输出是怎么来的

int main()
{
 unsigned int a=4;
 printf("%d\n",-a>>4);
 return 0;   
}

结果 = 268435455

最佳答案

首先,您所做的事情是不可移植的。

ISO C11 在 6.5.7 位移位运算符 中指出:

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^E2 . If E1 has a signed type and a negative value, the resulting value is implementation-defined.

所以这样做并不明智。

可能发生的情况是您有一个保留负值符号的实现。虽然 >> 通常可能会在左侧移入零位(对于无符号或有符号非负值必须),但您的实现可能会检测到负数并将一位移至左起第二个位置,保持左侧位不变。

这意味着-1(例如:二进制1111 1111 1111 1111)在右移后仍然具有该位模式。

您必须检查特定实现的文档才能确定(标准的附录 J 要求实现记录其对实现定义的行为的选择)。

您还可以使用一些更好的示例值(例如右移一位的二进制 1100 0000 0000 0000 )来测试它,然后看看结果如何(当然,实现注释应该是最终来源)。

<小时/>

例如,gcc 文档提供了此信息 here 。既然您提到您正在使用 4.6.3,那么 4.6.4 手册可能是最接近的。

该页面上的 GCC 4.6.4 手册(也采用 PDF 或 PostScript 或 HTML tarball 格式) 链接包含标题为 C 实现定义的行为 的部分,其中指出,部分:

The results of some bitwise operations on signed integers (C90 6.3, C99 6.5).

Bitwise operators act on the representation of the value including both the sign and value bits, where the sign bit is considered immediately above the highest-value value bit. Signed ‘>>’ acts on negative numbers by sign extension.

这意味着它的作用正如我所解释的那样,左边的位保持不变并且影响第二个最左边的位:

enter image description here

<小时/>

您看到不同值的原因是:

unsigned int a=4;
printf("%d\n",-a>>4);

是因为 -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表达式中详细介绍的整数提升和通常的算术转换有关,但我认为这远远超出了原始问题的范围.

关于无法理解C程序输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23214895/

相关文章:

计算文件中括号的数量

c++ - 仅适用于 .NET 的 Windows API W7 JumpList?

c - (*new) 是做什么的?

c - 有没有比 rand() 更好的函数?

c - scanf 终止标准输入

c++ - C/C++ 中最快/最短的方法来计算二进制数字之和/又称二进制中 1 的数量

c - 如何在 python ctypes 中声明图像指针?

C 将结构传递给函数

C:读取二进制并写入编码文本

c++ - 如何使用带有变量名称的字符串获取变量地址?