Я просто сомневался. Следующая подпрограмма (например, для поиска элемента в списке) имеет оператор 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
делает последний .return
делает. На самом деле, в функциональных языках (и некоторых смешанных, таких как Scala)return
нет необходимости : значение рекурсивной функции - это значение ее последнего выражения. Простое написаниеsearch_list(l->next, x)
неreturn
сработало бы в Scala! Смыслreturn
заявления очевиден только для программистов с императивным фоном.Ответы:
Оператор return передает значение обратно непосредственному вызывающему кадру call-кадра текущей функции. В случае рекурсии этот непосредственный вызывающий объект может быть еще одним вызовом той же функции.
В большинстве языков, если вы не используете возвращаемое значение вызванной вами функции (рекурсивно или нет), либо возвращаемое значение отбрасывается, либо это диагностируемая ошибка. Есть некоторые языки, в которых возвращаемое значение последнего вызова функции автоматически повторно используется как возвращаемое значение текущего вызова функции, но они не различают обычные и рекурсивные вызовы функций.
Предполагая, что неиспользуемые возвращаемые значения молча отбрасываются, если вы написали такой код:
затем
search_list
возвращает только определенное значение для пустого списка (NULL) или если первый элемент соответствует значению, которое вы ищете. Как только функция переходит в рекурсивный вызов, вы не знаете, каким будет результат, потому что результат рекурсивного вызова отбрасывается.Кроме того, вы обещаете вернуть значение из вашей функции, но у вас есть путь (рекурсивный), в котором вы не указываете, какое значение возвращать. В зависимости от языка, который вы используете, это обычно приводит либо к обязательной диагностике, либо к неопределенному поведению (что означает сокращение: может произойти все, что угодно, и может измениться в любое время без уведомления. ваша самая важная презентация). В некоторых ситуациях пропущенное возвращаемое значение может работать, но оно может измениться при следующем запуске программы (с перекомпиляцией или без нее).
источник
Две вещи; Возвращение всего списка в том случае, если вы нашли искомую букву «х», не обязательно гарантирует использование рекурсии, но, кроме этого, рассмотрите следующее:
Предположим, вы ищете значение X = «Декабрь», и ваш список представляет собой числовое значение месяцев года, указатель на следующий месяц, а элементы l-> в списке - это прописанные имена месяцы. (Январь, февраль, ..., декабрь). Вам нужны три возврата для возможных результатов. Первый, return (NULL) необходим, если в списке нет нужного вам X. Второй (return (l)) возвращает список, в данном случае, давая вам знать, что вы нашли свой «x». Последнее, где модель стека вступает в игру. Последовательные вызовы функции обновляли бы локальные переменные (в частности, l-> item) следующим образом:
источник