我想知道有关以下代码如何工作的详细信息

I wanted to know the details on how it's working for the following code

我得到了输出 00246,但我不明白代码,有人可以详细说明一下吗?

int print(int nb)
{
    if (nb < 0) 
    {
        return (0);
    }
    printf("%d", nb + print(nb - 1));
    nb --;
    return (nb);
}

int main(void)
{
    print(4);
    return (0);
}

这是代码。

我建议您在纸上记下出现的 nb 的不同值。

注意这一行的打印函数: 在 print(nb-1) 调用 return 值之前,不会调用 printf("%d", nb + print(nb - 1))。 最终这意味着打印的第一个值将来自最后一级递归。

对代码的更改可以向您展示其工作原理:

    int print(int nb, int level)
    {
        printf("\nEnter level %d nb= %d", level, nb);
        if (nb < 0) 
        {
            printf("\nExit level %d nb =%d return 0", level, nb);
            return (0);
        }
        printf("\nOriginal Output  level %d nb=%d",level, nb + print(nb - 1, level+1));
        nb --;
        printf("\nExit level %d nb=%d", level, nb);
        return (nb);
    }
    
    int main(void)
    {
        int level=0;
        print(4, level);
        return (0);
    }

这给出了输出:

Enter level 0 nb= 4
Enter level 1 nb= 3
Enter level 2 nb= 2
Enter level 3 nb= 1
Enter level 4 nb= 0
Enter level 5 nb= -1
Exit level 5 nb =-1 return 0
Original Output level 4 nb=0
Exit level 4 nb=-1
Original Output level 3 nb=0
Exit level 3 nb=0
Original Output level 2 nb=2
Exit level 2 nb=1
Original Output level 1 nb=4
Exit level 1 nb=2
Original Output level 0 nb=6
Exit level 0 nb=3

在更改后的代码中,我添加了一个变量 level,它为每个递归级别标记了一个数字。

如果您按照代码的输出进行操作,您可以看到在顶层 nb 以值 4 开头。

行中 printf("\nOriginal Output level %d nb=%d",level, nb + print(nb - 1, level+1)); 您调用 print 函数,这会将您带到下一级递归,其中条目 nb 为 3.

此时尚未调用 printf 语句,因为代码需要来自 print 函数的 return 值。

代码 运行 直到我们再次调用 print 代码进入下一级递归。

每次 print 调用该点的所有局部变量值,并将指向函数调用位置的指针放在堆栈上,以便代码流可以 return 到它在完成后被调用。

这个循环一直持续到第 5 级,其中 nb 小于 0,因此代码 return 的值为 0,它不会到达 printf 语句级别,因此 0 的值被 returned 到在级别 4 上调用 print 函数的位置。这是通过使用然后删除放置在堆栈上的数据来完成的。

printf 调用现在可以 运行 因为我们有一个值 return 来自 print 函数调用。此时 nb 的本地值为 0,如输出中的语句 Enter level 4 nb= 0 所示。此本地值被添加到 return 调用 print 的值,即 0、0+0=0,因此您会看到:

Original Output level 4 nb=0

printf 代码完成该级别后 nb 递减 return -1 的值。

Exit level 4 nb=-1

堆栈再次回滚一级,现在在第 3 级,-1 的 return 值添加到 nb 的第 3 级值(Enter level 3 nb= 1),1 -1=0 所以 printf 的输出是:

Original Output level 3 nb=0

循环继续,直到所有堆栈级别都已回滚。 输出显示所有阶段,直到第 5 级被放置到堆栈上,然后从那里回滚直到我们回到第 0 级。

递归调用不会停止,直到我们到达 nb==-1 的调用。这 returns 0.

之前的通话现在可以恢复了。在那个电话中,nb==0。我们通过调用 which nb==-1 将 0 添加到 0 returned 以获得 0,并打印它。然后我们returnnb-1(因为我们说nb--),也就是-1.

之前的通话现在可以恢复了。在那个调用中,nb==1。我们将 1 添加到我们从 nb==0 调用中得到的结果,即 -1。所以我们打印1 + -1,即0。然后我们从当前的nb中减去1,也就是1,得到0,return那个。

之前的通话现在可以恢复了。在那个电话中,nb==2。我们将 2 添加到我们从 nb==1 调用中得到的结果,即 0,并打印结果 2。然后我们从当前 nb 中减去 1,即 2,得到 1,并且 return .

之前的通话现在可以恢复了。在那个调用中,nb==3。我们将 3 添加到我们从 nb==2 调用中得到的结果,即 1,并打印结果 4。然后我们从当前 nb 中减去 1,即 3,得到 2,并且 return .

之前的通话现在可以恢复了。在那个电话中,nb==4。我们将 4 添加到我们从 nb==3 调用中得到的结果,即 2,并打印结果 6。然后我们从当前 nb(即 4)中减去 1 得到 3,并且 return到主线,我们就完成了。

这就是痕迹。您可以按照建议自己使用一堆 printf 或像我一样在调试器中执行此操作。

但问题仍然存在:这是为了什么?这只是一个需要解决的神秘程序吗?如果不是,它可能会被简化以使其更易于理解——但为此我们必须知道它的含义。