递归函数调用中返回语句的原因


14

我只是有一个疑问。以下子例程(例如,在列表中搜索元素)的末尾具有return语句:

list *search_list(list *l, item_type x) {
  if (l == NULL) return(NULL);
  if (l->item == x)
    return(l);
  else
    return( search_list(l->next, x) );
}

我无法在最后获得return语句的意义(即return search_list(l-> next,x))。如果有人可以使用堆栈模型来解释这个概念,那将非常有帮助。


如果列表的第一项不是结果,请搜索列表的其余部分。这是最后一个return所做的。
Giorgio 2013年

@Giorgio,为什么不只有一个函数调用就足够了,为什么在此之前需要返回?
user1369975 2013年

7
因为您需要返回函数返回的值
Esailija 2013年

7
拒绝投票的人:请意识到,根据OP的背景,它的作用一点都不明显return。实际上,在函数式语言(和某些混合语言,例如Scala)return 中并不需要:递归函数的值是其最后一个表达式的值。简单地编写search_list(l->next, x)return不会在Scala中工作!该return语句的含义仅对具有必要背景的程序员而言是显而易见的。
Andres F.

OP:您的代码段是用C编写的吗?
Andres F.

Answers:


19

return语句将值传递回当前函数的调用框架的直接调用者。在递归的情况下,此直接调用方可以是同一功能的另一次调用。

在大多数语言中,如果不使用调用的函数的返回值(递归或不递归),则该返回值将被丢弃,或者这是可诊断的错误。在某些语言中,最后一个函数调用的返回值会自动重新用作当前函数调用的返回值,但是它们无法区分普通函数调用和递归函数调用。

假设未编写的返回值被静默丢弃,如果您已编写如下代码:

list *search_list(list *l, item_type x) {
  if (l == NULL) return(NULL);
  if (l->item == x)
    return(l);
  else
    search_list(l->next, x); // no return!
}

那么search_list只会为空列表(NULL)或如果第一项与您要搜索的值匹配,则返回定义的值。一旦函数进入递归调用,您将不知道结果将是什么,因为递归调用的结果将被丢弃。

另外,您承诺从函数中返回一个值,但是您有一条路径(递归路径),在该路径中您没有指定要返回的值。根据您使用的语言,这通常会导致强制性诊断或未定义的行为(这是简写:任何事情都可能发生,并且随时可能在不通知的情况下发生变化。您最重要的演示文稿)。在某些情况下,缺少的返回值可能会起作用,但是在您下次运行程序时(有或没有重新编译),这可能会改变。


FWIW,Perl自动返回最后一个表达式的结果,我认为这意味着它将重用返回值。但是我好几年都没有碰过它,所以我不确定。
Bobson

1

两件事情; 在找到要查找的“ x”的情况下返回整个列表并不一定需要使用递归,但除此之外,请考虑以下事项:

假设您正在寻找X =“ December”的值,并且您的列表是一年中月份的数字值,指向下个月的指针,并且列表中的l-> items是该表的拼写名称。几个月。(一月,二月,...,十二月)。您需要三项回报才能获得可能的结果。如果列表不包含您要查找的X,则需要第一个return(NULL)。第二个(return(l))返回列表,在这种情况下,让您知道找到了“ x”。最后是堆栈模型起作用的地方。对函数的连续调用将具有如下所示的更新的局部变量(特别是l-> item):

1: l->item = January
   returns search_list(l->next, x)
2: l->item = February
   returns search_list(l->next, x)
3-11: March, April, May, June, July, August, September, October, November
   all return search_list(l->next, x)
12: l->item = December
  This matches the second if() and returns your list, letting you know you found your search item.

,感谢您的说明,但实际上并没有使用上一次返回
user1369975 2013年

如果没有最后的回报,你从来没有闯过第1步
panhandel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.