我想知道有关以下代码如何工作的详细信息
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 或像我一样在调试器中执行此操作。
但问题仍然存在:这是为了什么?这只是一个需要解决的神秘程序吗?如果不是,它可能会被简化以使其更易于理解——但为此我们必须知道它的含义。
我得到了输出 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 或像我一样在调试器中执行此操作。
但问题仍然存在:这是为了什么?这只是一个需要解决的神秘程序吗?如果不是,它可能会被简化以使其更易于理解——但为此我们必须知道它的含义。