C 什么是递归,并解释这个程序的输出?

C 什么是递归,并解释这个程序的输出?,c,function,recursion,C,Function,Recursion,我真的不懂这个代码。当函数调用自身时,会发生什么?我知道,这与堆栈的概念有关,但我仍然无法解决这些问题 #include<stdio.h> fun(int); main() { int x=3; fun(x); } fun(int a) { if(a<0) { fun(--a); // what happens when function calls itself printf("%d",a); fun(--a);

我真的不懂这个代码。当函数调用自身时,会发生什么?我知道,这与堆栈的概念有关,但我仍然无法解决这些问题

#include<stdio.h>

fun(int);

main()
{
  int x=3;
  fun(x);
}

fun(int a) 
{
  if(a<0)
   {
     fun(--a);    // what happens when function calls itself
     printf("%d",a);
     fun(--a);
   }
} 
#包括
娱乐(国际);
main()
{
int x=3;
乐趣(x);
}
趣味(INTA)
{

如果(a函数参数由C中的值传递,这意味着每次调用函数时都会创建临时局部变量。当递归调用函数时,每次都会创建一组新的变量。然而,递归并不一定能节省存储空间,因为必须在某个地方维护正在处理的值堆栈函数仅仅是驻留在内存中某个地方的代码。无论何时进行函数调用,编译器都会将其转换为平台的汇编代码命令,用于保存函数调用完成后要执行的下一个命令的地址,并告诉处理器从何处“跳转”在内存中读取下一个要执行的命令

递归之所以有效,是因为您可以轻松地告诉处理器“跳转”返回到内存中函数代码块的开头。从中调用的当前函数与任何其他函数一样具有内存地址,因此处理器跳到内存中当前函数代码块的开头或内存中其他函数代码块的开头没有区别

堆栈之所以发挥作用,是因为我们需要保存返回地址,以便在完成函数调用后执行命令,以及存储当前函数参数和自动变量的位置。因此,在进行连续函数调用时,会创建一个调用堆栈,其中包含参数和ret如果堆栈向下增长,则堆栈上更高的任何以前调用的函数的urn地址。这统称为“堆栈帧”对于函数。当您从函数返回时,当前函数的堆栈帧从堆栈底部弹出,然后读取并执行函数完成后处理器需要跳回的内存地址。在递归的情况下,这意味着我们只需跳回相同的前一版本函数,但在这种情况下,自动堆栈变量和参数在返回后会有所不同,因为我们已返回该函数以前版本的堆栈帧。

在这种情况下,调用fun()就像调用任何其他函数。例如:

int main() {
   int a = 0;
   foo(a);
   printf("main a = %d\n", a);
}

void foo(int a) {
   a = 1;
   bar(a);
   printf("foo a = %d\n", a);
}

void bar(int a) {
   a = 2;
   printf("bar a = %d\n", a);
}
您的通话顺序如下所示:

main();
foo();
bar();
您的输出将是:

bar a = 2
foo a = 1
main a = 0
参数是按值传递的,因此
a
被复制,实际上是每个函数中的一个不同变量。递归也是如此

main();  x = 3
fun(3);  a = 3, so a > 0, nothing happens, return to main()
如果要更改条件,则当a>0(自顶向下读取)时,so fun()会调用自身

您的输出应该是:1213121,它反映了调用的树结构:

        3
       / \
      /   \
     2     2
    / \   / \
   1   1 1   1

目前它似乎什么也不做。如果它被传递一个正值,什么也不会发生,如果它被传递一个负值,它将进入无限递归。此外,你的函数没有返回类型。要理解递归,你必须首先理解递归。因为第一次调用的值grather大于0,如果
条件为eval,
我认为正确的条件应该是:
如果(a>0)
。这是家庭作业吗?你试过自己执行吗?你试过调试吗?试试看。。。
        3
       / \
      /   \
     2     2
    / \   / \
   1   1 1   1