#include <stdio.h>
void count(int );
void count(int n)
{
int d = 1;
printf("%d ", n);
printf("%d ", d);
d++;
if(n > 1) count(n-1);
printf("%d ", d);
}
int main(void) {
count(3);
return 0;
}
输出: 3 1 2 1 1 1 2 2 2
#include <stdio.h>
void count(int );
void count(int n)
{
static int d = 1;
printf("%d ", n);
printf("%d ", d);
d++;
if(n > 1) count(n-1);
printf("%d ", d);
}
int main(void) {
count(3);
return 0;
}
输出: 3 1 2 2 1 3 4 4 4
在两个输出中,我无法得出输出中最后3位数之间的差异,即 444 和 222 。
我知道静态声明在编译时有静态分配,所以它的值在整个程序中保留,并且一旦函数调用结束就会销毁local / auto变量。
但是,即使我在最后3位数字中感到困惑,因为我无法根据上述信息解释它们?
答案 0 :(得分:3)
您的函数末尾的printf()
将首先针对count(n=1)
案例运行。返回后,printf()
将针对count(n=2)
运行,然后针对count(n=3)
运行。
在非静态情况下,局部变量d
在函数末尾始终为2。在静态情况下,all共享相同的变量,因此在最后count()
递增后它将为4。
尝试这样的事情,以便更好地了解会发生什么:
void count(int n)
{
static int d = 1;
d++;
printf("%d: pre recursion (d = %d)\n", n, d);
if(n > 1) count(n-1);
printf("%d: post recursion (d = %d)\n", n, d);
}
答案 1 :(得分:3)
进行递归调用时,调用后的语句不会执行,直到递归结束。这包括所有嵌套的递归调用。以下是使用自动变量调用版本时发生的情况:
main()
来电count(3)
d = 1
n
,其中包含3
d
,其中包含1
d
,现在包含2
count(n-1)
d = 1
n
,其中包含2
d
,其中包含1
d
,现在包含2
count(n-1)
d = 1
n
,其中包含1
d
,其中包含1
d
,现在包含2
if (n > 1)
失败,所以它没有递归d
,其中包含2
d
,其中包含2
d
,其中包含2
如果您找到上面的所有print
行,则会打印3 1 2 1 1 1 2 2 2
以下是使用带有静态变量的版本时会发生什么:
main()
来电count(3)
d = 1
,因为这是对函数的第一次调用n
,其中包含3
d
,其中包含1
d
,现在包含2
count(n-1)
n
,其中包含2
d
,其中包含2
d
,现在包含3
count(n-1)
n
,其中包含1
d
,其中包含3
d
,现在包含4
if (n > 1)
失败,所以它没有递归d
,其中包含4
d
,其中包含4
d
,其中包含4
提取所有print
行,然后打印3 1 2 2 1 3 4 4 4
。
不同之处在于每次调用函数时d
都会持续变高,因为它会保留前一次调用的值,然后会增加。
答案 2 :(得分:2)
在d
的任何和所有递归调用完成后,最后三位数字是count
的值,可见。
在第一个程序中,d
的范围限定为对count
的每个单独调用,并且它在每个堆栈帧中仅增加1
。 1 + 1 = 2
,函数在退出前打印2
。
在第二个程序中,d
是静态到程序中,并在每次调用count
之间共享。如前所述,最终的打印语句仅在所有count
调用开始后才会发生,并且将不再有count
的调用,因此d
将始终处于其最大值 - 无论对count
的哪个电话正在结束。
答案 3 :(得分:0)
在此功能中
void count(int n)
{
static int d = 1;
^^^^^^^^^^^^^^^^^
printf("%d ", n);
printf("%d ", d);
d++;
if(n > 1) count(n-1);
printf("%d ", d);
}
局部变量d
具有静态存储持续时间,它在函数调用之间保持其值。它在程序启动前只初始化一次。
所以在这段代码中
if(n > 1) count(n-1);
printf("%d ", d);
在最内层调用中执行最后一个语句,变量d
已经获得其值4.
你可以通过以下方式想象它
d++;
d++;
d++;
//...
printf("%d ", d);
printf("%d ", d);
printf("%d ", d);
答案 4 :(得分:0)
在第一个程序d
中是auto
变量,因此,每次执行函数时都会保留d
的内存,并且在完成函数后它是未保留的。
在第二个程序中,d
是static
变量,因此,第一次保留函数d
变量内存的执行但是在编译函数之后它不是未保留的。仅当整个程序完成时,static
变量内存才会被保留。