在C中运行Unreached代码

时间:2012-10-29 17:01:52

标签: 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。输出似乎不自然。我在互联网上搜索了一些关于堆栈的东西。有人能详细说明为什么会这样吗?

3 个答案:

答案 0 :(得分:3)

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

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

第二次注意n*2的输出介于<{1}}(n)的第一行和第二行之间,因为你制作了两个n < 50之间的递归调用。那么,同意你的输出。

这是预期的。

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

这种堆叠对于递归至关重要。

因此,当你调用printf程序记录它在第5行时,然后跳转到第8行的newfunc(2)的开头。堆栈看起来(在概念上)如:

newfunc

当它到达第13行时,它再次调用新函数,使堆栈

line 5, n=2

这会持续几次,直到堆栈看起来像

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

当if失败并且line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16; line 13, n=32; line 13, n=64 返回弹出堆栈并在第13行之后继续执行(因为这是我们从堆栈中得到的)制作堆栈

newfunc

当我们运行line 5, n=2; line 13, n=4; line 13, n=8; line 13, n=16; line 13, n=32 并弹出堆栈时我们返回到第13行(我们弹出时得到的内容,右边&gt;)以便堆栈

printf

等等,它解除了整个调用堆栈。

最后几个细节:堆栈在概念上“增长”,因此我们经常将其写为

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

并且堆栈内容的确切格式取决于芯片的体系结构以及OS程序员做出的一些决定。


BTW - 交流程序通常不使用行号来表示“它在哪里”,因为行不是c中的好措施(如果我足够傻,我可以将整个程序写成一行),而不是使用芯片上寄存器的值,但这并没有真正影响这里的解释。

答案 1 :(得分:0)

实际发生的是,当您在第13行调用该函数时,该函数之后的代码无法执行,因此它们存储在称为堆栈的内存中的特殊位置,并且它们从底部填充,因此更新的代码填充在堆栈的顶部。因此,在第一个函数调用时,printf("\n%d",2)被添加到底部printf("\n%d",4);的堆栈中,即 2 * n = 2 * 2 = 4 被添加到上一个堆栈的顶部以及递归执行停止时。执行从顶部开始的堆栈程序,产生上述复杂类型的输出,这对于简单分析是不可预测的。

答案 2 :(得分:0)

让我们把它当作小值说10

1st call from main         ////returned from newfunc(2)
newfunc(2)             
//inside newfunc(2)
print 2
2<10 (correct)
newfunc(4)  --> on stack print 2  //returned from newfunc(4)
-------------------------------
//inside newfunc(4)
print 4 
4<10
newfunc(8)  --> on stack print 4 //returned from newfunc(8)
---------------------------------
//inside newfunc(8)
print 8
8<10
newfunc(16) --> on stack print 8 //returned from newfunc(16)
---------------------------
//inside newfunc(16)
print 16
16<10 failed

所以它会return到它之前的函数,无论哪个函数都调用它,所以它将继续-->符号,这个符号在这个例子中是堆栈的顶部,print用于显示屏幕上显示result

功能序列从上到下......我试图在图表中显示。希望你明白。

此处-->语句将从下到上执行,因此结果将为

2
4
8
16
8
4
2