请考虑递归函数:
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--)
。
我很震惊,因为当一个函数调用它自己时,我只知道一件事,它的递归。
她也给出了原因,那行没有。 2
和3
被额外存储在堆栈内存中。
我不知道她指的是什么。所以经过堆栈存储后,事情:
在这里,我注意到传递的函数参数是以递归的方式,如n--
中的function
。
这样他们就可以链接到下一个function call
。
为此,我们可以将其称为简单function call
而不是recursion
吗?
答案 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
,您似乎正在尝试计算0
到num
的总和。 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 );
}
无法以这种方式进行优化。