c - 在 C 中运行 Unreached 代码

标签 c stack

下面是一个示例 C 程序,它提供了程序之后的输出

#include<stdio.h>
void newfunc(int n);
int main(void)
{
    newfunc(2);
    return 0;
}
void newfunc(int n)
{
    printf("\n%d",n);
    if(n<50)
    {
        newfunc(2*n);
        printf("\n%d",n);
    }
}

产生输出

2
4
8
16
32
64
32
16
8
4
2

但是根据代码来看,好像在第13行的函数调用之后,并没有调用下一个printf。而且输出看起来不自然。我在网上搜索了一下,发现了一些关于堆栈的东西。有人可以详细说明为什么会这样吗?

最佳答案

这是一个基本的递归调用。

首先,请注意 n 的值少于 50 你的函数将打印 n两次,对于 n 的其他值它只会打印一次。这与你的输出一致,所以这里唯一要弄清楚的是顺序......

再次注意 n*2 的输出应该在 n 的第一行和第二行输出之间 (对于 n < 50 ),因为您在 两个 printf 之间进行了递归调用秒。嗯,同意你的输出。

这符合预期。

您在互联网上找到的有关堆栈的部分是指调用堆栈。为了从函数返回,程序必须跟踪调用函数时它所在的位置。此信息被写入称为“调用堆栈”或“执行堆栈”的特殊内存部分的“末尾”;并且它被从堆栈中取出(意味着当函数返回时'end'被移动)。调用参数也记录在栈中。

这种堆叠对于递归是必不可少的。

因此,当您调用 newfunc(2)程序记录它在第 5 行,然后跳转到 newfunc 的开头在第 8 行。堆栈看起来(名义上)像:

line 5, n=2

到了第13行,再次调用new函数,入栈

line 5, n=2; line 13, n=4

这会重复几次,直到堆栈看起来像

line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16; line 13, n=32; line 13, n=64

当 if 失败并且 newfunc在第 13 行之后返回弹出堆栈并恢复执行(因为那是我们从堆栈中取出的)制作堆栈

line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16; line 13, n=32

当我们运行 printf并在我们返回到第 13 行时弹出堆栈(弹出时得到的内容,对>),这样堆栈就是

line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16;

等等,同时展开整个调用堆栈。

一些最后的细节:堆栈在概念上会“向上”增长,因此我们通常将其写为

line 13, n=32
line 13, n=16
line 13, n=8 
line 13, n=4 
line 5, n=2 

堆栈内容的确切格式取决于芯片的架构和操作系统程序员做出的一些决定。


顺便说一句——c 程序通常不使用行号来表示它所在的“位置”,因为行数在 c 中不是很好的衡量标准(如果我够傻的话,我可以一行一行地写整个程序),而是它使用芯片上寄存器的值,但这并不真正影响这里的解释。

关于c - 在 C 中运行 Unreached 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13126270/

相关文章:

c - getopt.h : Compiling Linux C-Code in Windows

python - list.pop 的 numpy 等价物?

algorithm - 如何使用两个堆栈实现队列?

c - 通过指针传递对象时成员值丢失

python - 使用 list.pop() 反转列表的问题

带有多个条件语句的 C 代码给出了意外的结果

c - 具有特定功能的for循环

c - 使用ctime的段错误

Java 检查 Stack 是否包含某个类

c - strstr 找不到子字符串,但缓冲区包含该值