为什么这个递归在一些非零值之后打印0

  • 本文关键字:非零值 之后 打印 递归 c
  • 更新时间 :
  • 英文 :


这是无限递归,我很困惑为什么要打印0。

#include <stdio.h>
void go(int x)
{
printf("%d",x);
go(x+x);
}
int main()
{
go(2);
return 0;
}

程序有未定义的行为,因为它最终会导致x+x中的有符号溢出。

当您重复向自身添加整数时,最终会达到整数数据类型太小而无法容纳乘法结果的程度。这将最终导致一个零(或未定义,见下文(值。

将一个整数加到自身上,与乘以2相同如果您的数据类型是符号,则产生溢出的行为是未定义的。如果数据类型为无符号,则最终将达到零值。

由于最终的整数溢出,程序具有未定义的行为(UB(。因此,没有任何形式的输出或行为的保证。

为什么它打印零作为溢出UB的一个可能结果的一种解释是,在32位系统上,它将在1073741824 + 1073741824点溢出。这等于2^31,但INT_MAX将是2^31-1,因此溢出。当发生溢出时,一种常见的行为是切换到数字2^31的二进制表示,在2的补码中,它将是-2147483648

然后在下一个步骤中,CCD_ 5最终为零。这不是特别合乎逻辑(它是UB(,我想你可以把它想象成-2147483648 + -2147483648=-4294967296,这相当于二进制表示0xFFFFFFFF00000000。将其截断到4个字节,则得到零。

我之所以不断提到二进制表示,是因为整数溢出很可能是实际CPU中定义良好的行为。它将像无符号数字一样换行,丢弃任何不适合的数字,并设置溢出标志。

从那时起,您将拥有无尽的0 + 0,除非递归没有得到优化,而是在堆栈溢出中崩溃。

最新更新