递归和静态变量 [英] Recursion and static variables

查看:77
本文介绍了递归和静态变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在印度准备入学考试时,我遇到了这段 C 代码

So I was preparing for an entrance exam here in India when I came across this piece of C code

#include <stdio.h>
int main(void) {
    static int i = 4;
    if (--i) {
        main();
        printf("%d", i);
    }
}

我认为 printf 语句永远不会被执行,输出将为空白.但我看到答案是 0000,这是由于 static 关键字和 int 导致的.

I thought the printf statement never gets executed and the output will be blank. But I saw the answer to be 0000 and that this happens due to the static keyword with the int.

谁能解释一下 printf 执行的原因还是那个人错了?

Can anyone explain why the printf executes or is that guy wrong?

推荐答案

谁能解释一下 printf 执行的原因还是那个人错了?

Can anyone explain why the printf executes or is that guy wrong?

因为 main 返回.

这个答案写出了逻辑,但我看到你还在评论中问这个.所以我会用不同的方式说同样的事情,希望你能更清楚.

This answer writes out the logic, but I see that you are still asking this in comments. So I'm going to say the same thing in a different way and hope that it is clearer to you.

因为变量是static,所以在第一次调用之前,变量被声明并设置为4.因为它是static,所以每次都会使用相同的变量时间.如果再次调用(甚至可能是第一次调用,因为可以在运行之前分配 static 变量),它只会跳过声明和初始化.

Because the variable is static, prior to the first call, the variable is declared and set to 4. Because it is static, the same variable will be used every time. It just skips over the declaration and initialization if called again (or likely even the first time, as static variables can be allocated before running).

在第一次调用中,变量递减到 3.3 是一个真值,所以我们做了 if 的块.这会递归调用 main.

In the first call, the variable is decremented to 3. 3 is a truthy value, so we do the block of the if. This calls main recursively.

在第二次调用中,变量递减到 2.2 在 C 中仍然是真实的.我们再次递归调用 main.

In this second call, the variable is decremented to 2. 2 is still truthy in C. We call main recursively again.

在第三次调用中,变量递减为 1.1 仍然为真.我们再次递归到 main.

In this third call, the variable is decremented to 1. 1 is still truthy. We recurse to main again.

在第四次调用中,变量递减到 0.0 在 C 中是假的.我们没有进入 if 的块.我们不递归.我们不打印.在这个对 main 的调用中没有什么可做的.它在最后返回.

In this fourth call, the variable is decremented to 0. 0 is falsey in C. We do not enter the block of the if. We do not recurse. We do not print. There's nothing left to do in this call to main. It returns at the end.

现在我们回到第三个电话.我们刚刚从对 main 的调用返回.我们仍然在 if 块中.下一个语句是 printf.变量的值现在是 0.所以我们打印一个 0.没什么可做的,我们最后返回.

Now we're back in the third call. We just returned from the call to main. We are still inside the if block. The next statement is a printf. The value of the variable is now 0. So we print a 0. Nothing left to do, we return at the end.

现在我们回到第二个电话.仍然是 0,所以我们打印另一个 0 并返回.

Now we're back in the second call. Still 0, so we print another 0 and return.

现在我们回到第一个电话.仍然是 0,所以我们打印另一个 0 并返回.

Now we're back in the first call. Still 0, so we print another 0 and return.

我们打印了 3 次 0,所以 000

We printed 0 three times, so 000

正如您所注意到的,在下降的过程中,我们不打印.我们在回来的路上打印.到那时,变量为 0.我们进入 if 的 then 块 3 次.所以我们递归然后打印三遍.

As you note, on the way down, we don't print. We print on the way back up. By that time, the variable is 0. And we enter the then block of the if three times. So we recurse and then print three times.

当你递归调用一个函数时,你不会消除之前的调用.你把它放在堆栈上.完成后,您会回到离开的地方并继续下一个语句.

When you call a function recursively, you don't eliminate the previous call. You put it on the stack. When done, you come back to the place where you left and continue with the next statement.

您可能想考虑以下三段代码的不同反应:

You may want to think about how the following three pieces of code will react differently:

void recurse() {
    static int i = 4;
    if (--i) {
        recurse();
        printf("%d", i);
    }
}

第一次调用时打印 000.之后什么都不做.

Prints 000 when called the first time. Does nothing thereafter.

void recurse(int i) {
    if (--i) {
        recurse(i);
        printf("%d", i);
    }
}

如果作为 recurse(4) 调用,将打印 123.作为参数,我们在每次调用函数时处理不同的 i.

Will print 123 if called as recurse(4). As a parameter, we are dealing with a different i each time the function is called.

void recurse(int i) {
    if (--i) {
        printf("%d", i);
        recurse(i);
    }
}

如果作为 recurse(4) 调用,则打印 321.在下降过程中打印而不是在返回时打印.

Prints 321 if called as recurse(4). Printing on the way down rather than when coming back up.

void recurse(int i) {
    printf("%d", i);
    if (--i) {
        recurse(i);
    }
}

如果作为 recurse(4) 调用,则打印 4321.它在下降的过程中打印,而不是在上升的过程中打印.

Prints 4321 if called as recurse(4). It prints on the way down, rather than the way up.

void recurse() {
    static int i = 4;
    printf("%d", i);
    if (--i) {
        recurse();
    }
}

将打印 4321.我们正在向下打印,而不是向上打印.请注意参数和 static 变量如何以这种方式给出相同的结果.但是,如果第二次调用它,它将什么也不做.该参数将再次打印相同的内容.

Will print 4321. We're printing on the way down, not the way up. Note how the parameter and the static variable give the same result this way. However, if this is called a second time, it will do nothing. The parameter would print the same thing again.

void recurse() {
    int i = 4;
    if (--i) {
        recurse();
        printf("%d", i);
    }
}

永远循环.如果没有 static,我们每次都会创建一个新的 i.这将一直运行,直到它使堆栈过载并崩溃.没有输出,因为它永远不会到达 printf.

Loops forever. Without the static we make a new i each time. This will run until it overloads the stack and crashes. No output because it never makes it to the printf.

检查这一点的最简单方法是访问 ideone.com 之类的地方并运行代码.询问为什么它会打印某些内容对于该站点来说是合理的.但是问它打印什么是你应该自己回答的问题.

The easiest way to check this is to go somewhere like ideone.com and run the code. Asking why it prints something is reasonable for this site. But asking what it prints is something that you should answer yourself.

这篇关于递归和静态变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆