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


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.