可以将递归命名为简单的函数调用吗?

时间:2013-11-08 17:54:39

标签: c recursion function-calls

请考虑递归函数:

 1)   int calc(int num)
       {

 2)    sum=sum+num;//sum is a global variable

 3)    num--;

 4)    if(num==0)
 5)    return sum;

 6)    calc(num);

       }

它计算整数的总和。 我的老师告诉我这不是递归,而是一个简单的函数调用,因为你需要通过 num--作为参数并返回calc(num--)

我很震惊,因为当一个函数调用它自己时,我只知道一件事,它的递归。

她也给出了原因,那行没有。 23被额外存储在堆栈内存中。 我不知道她指的是什么。所以经过堆栈存储后,事情:

enter image description here

在这里,我注意到传递的函数参数是以递归的方式,如n--中的function。 这样他们就可以链接到下一个function call

为此,我们可以将其称为简单function call而不是recursion吗?

3 个答案:

答案 0 :(得分:3)

即使你提出的内容在技术上是递归的,老师也会有一些非常具体的东西。另一种不依赖全局的形式看起来像这样:

int calc(int num)  // Assume this is valid for non-negative numbers
                   // In that case, type "unsigned int" would be more appropriate
{
    if ( num < 0 )
        return -1;  // Consider this an error; won't happen in recursive case

    if ( num == 0 )
        return 0;

    return num + calc(num-1);
}

答案 1 :(得分:2)

你是对的,递归是一个自我调用的函数。期。还有其他一些值得单独讨论全局变量和其他良好的编程实践,但是无论是在递归调用函数的代码行中实现递减运算符,还是在该点之前,您仍在进行递归调用。 / p>

答案 2 :(得分:2)

对于给定的num,您似乎正在尝试计算0num的总和。 calc函数实际上只需要一个参数num,然后可以调用辅助函数calc_num,该函数获取当前数字和运行总和:

int calc( int num ) {
  return calc_help( num, 0 );
}

然后,calc_help,给定当前数字,以及到目前为止的总和,检查num是否小于或等于零。如果是,则当前运行总和是最终总和并且可以返回。否则,将对calc_help进行递归调用。它的当前数字将比num少一个(这样我们就可以使用连续较小的第一个参数调用calc_help,越来越接近num <= 0)的情况,以及当前总和将是总和加上当前数字:

int calc_help ( int num, int sum ) {
  return num <= 0 ? sum : calc_help( num-1, sum+num );
}

在执行尾调用优化的语言(如Scheme)中,这实际上是以下循环。一些C / C ++编译器执行尾调用优化(例如,根据Tail recursion in gcc/g++,GCC将在指定-O2时优化尾调用,所以这不完全是没有意义。

int calc( int num ) {
  int sum = 0;
  while ( num > 0 ) {
    sum = sum+num;
    num = num-1;
  }
  return sum;
}

或(如果你想更加模糊一点):

int calc( int num ) {
  int sum = 0;
  for ( ; num <= 0; sum+=num, num-- );
  return sum;
}

在递归调用之后执行添加的更天真的递归实现,即

int calc( int num ) {
  return num <= 0 ? num : num + calc( num-1 );
}

无法以这种方式进行优化。