[英]Explanation regarding output of C program
void count(int n)
{
static int d=1;
printf("%d", n);
printf("%d", d);
d++;
if(n>1)
count(n-1);
printf("%d", d);
}
void main()
{
count(3);
}
我计算的输出是3 1 2 2 1 3 4
本书给出的输出3 1 2 2 1 3 4 4 4
我知道为什么我的答案有所不同。
在书籍解决方案中,他们总是在“ if”循环中执行printf语句。 但是当我在书中学习时,如果不存在括号,则if,for和while循环取决于下一个语句。
在if语句true计数之后,不会执行printf。 但是为什么他们每次都要执行它。
如果您不为if
, for
, while
语句加上括号,它们将仅在下一行执行。 更改后:
if(n>1)
count(n-1);
printf("%d", d);
至:
if(n>1){
count(n-1);
printf("%d", d);
}
您的输出将变得更接近您的预期:
gonczor@wiktor-papu:~/tmp$ gcc main.c -o main
gonczor@wiktor-papu:~/tmp$ ./main 31221344
static d:1
count(n:3)
print(n) // 3
print(d) // 1
++d:2
count(n:2)
print(n) // 2
print(d) // 2
++d:3
count(n:1)
print(n) // 1
print(d) // 3
++d:4
print(d) // 4
print(d) // 4
print(d) // 4
打印前4
是因为if
卫士停止了递归。 当返回count(n:1)
的(递归)函数调用时,将打印第二个4
。 当返回count(n:2)
的(递归)函数调用时,将打印第三个4
。
我认为您的困惑是,您认为进行递归调用会导致调用者终止对其函数主体的任何进一步处理。 但是,情况并非如此,除非有一个return
语句尽早结束该函数。 例如,如果递归调用受到如下保护:
if (n>1) {
count(n-1);
return;
}
print("%d", d);
然后,输出将符合您的期望。 只打印4
,执行该操作if
因为if
评估为false。 所有其他递归调用将在完成后执行return
,因此不会出现其他4
。
另请注意:
if (n>1)
count(n-1);
printf("%d", d);
和
if (n>1) {
count(n-1);
}
printf("%d", d);
是等效的。 该代码的含义是:在if
块完成后打印d
。 有两种方法可以完成它。 一种方法是if
条件为false时。 另一种方法是, if
条件为true,则执行递归调用,然后该调用返回。 当递归调用返回时, if
块完成,然后打印d
。
进一步注意,虽然递归关系非常紧密,并且在计算上等效,但是递归不能视为普通的“循环”。 递归调用意味着多个活动的本地堆栈,而普通的“循环”仅具有当前的本地堆栈和循环执行块。 因此,在普通的“循环”之后的打印语句仅会执行一次,即循环完成之后。 但是,在递归调用返回之后,将执行递归调用之后的代码。 因此,如果执行两次递归调用,则需要完成三个活动的本地堆栈。 在您的代码中,每个本地堆栈都希望在if
块完成后打印d
。
如果书的输出为'3 1 2 2 1 3 4 4 4'
#include <stdio.h>
void count(int n)
{
static int d=1;
printf("\nN IS: %d", n);
printf("\nD IS: %d", d);
d++;
if(n>1) count(n-1);
printf("\nFINAL D IS: %d", d);
}
int main()
{
count(3);
return 0;
}
如果没有改变这个:
if(n>1)
{
count(n-1);
printf("\nFINAL D IS: %d", d);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.