Вот код к примеру :
#include <iostream>
using namespace std;
void reverse(char *s);
int main ()
{
setlocale(LC_CTYPE, "Russian");
char str[] = "Это тест";
reverse(str);
system("pause");
return 0;
}
void reverse(char *s)
{
if(*s)
reverse(s+1);
else
return;
cout << *s;
}
То есть если указатель не ноль, то функция вызывает себя повторно и так пока не дойдет до нуля, а потом return возвращает управление инициализатору, то есть будет идти в обратном порядке, но куда тогда он приходит, если при этом ещё участвует cout инструкция, она же не участвовала когда цикл шел по нарастающей (хотя сомнительно, так как цикл ей не давал отработать) , почему тогда участвует когда он идет в обратном направлении?
Другие языки программирования и технологии
Не могу понять каким образом работает return в рекурсивной функции?
return всегда работает одинаково.
при вызове функции состояние вызывающей функции помещается в стек, программный счетчик тоже относится к состоянию.
при выполнении return выполняется много всего, но в том числе, восстанавливается состояние вызывающей функции из стека, а значит, что после возврата из функции вычисление продолжается в вызывающей функции, с команды, следующей за вызовом функции. Читай внимательно.
В ярких книжках для детей привели бы такой пример (не совсем правильный)
т. е.
; //1
f(); //2
;//3
в строке 2 вызывается функция, она завершает работу (выполняет return) и вычисления продолжаются в вызывающей функции со строки 3.
И еще раз, рекурсивность на работу return влияния не оказывает никакого (вцелом, возможно, и оказывает в редких случаях{явно не без хардкода} при использовании оптимизирующего компилятора, когда компилятор либо заменит хвостовую рекурсию циклом, либо развернет рекурсию, например) - но это не ваш случай.
Ну а про стэк Вам Ягами неплохо написал :) Первый пришел, последний ушел. Прототип стека.... стопка бумаг, бумажки ложите и берете сверху, в вашем случае это выглядит так (я пробую проиллюстрировать как работает программа ваша) .
void reverse(char *s) {
____if(*s) //1
________reverse(s+1); //2
____else //3
________return; //4
____cout << *s; //5
}
на вход reverse пришла строка s = "123"
__строка не равна нулю, и выполнится reverse( "23" ); со второй строчки
____на вход reverse пришла строка s = "23"
____строка не равна нулю, и выполнится reverse( "3" ); со второй строчки
______на вход reverse пришла строка s = "3"
______строка не равна нулю, и выполнится reverse( "" ); со второй строчки
_________строка равна нулю, выполнится return, управление будет передано на третью строку вызывающей функции
______т. к. условие ранее выполнилось - то ветка else Игнорируется, выполняется cout << *s т. е. cout << '3'
______выполняется возврат (тут return не написан, но он подразумевается, т. к. функция возвращает void, при этом
______управление передается на третью строку вызывающей функции (там где состояние содержит s="23")
____аналогично предыдущему разу, ветка else не выполняется, выводится cout << *s, т. е. cout << 's' (т. к. s = "23") - это
____выдернуто из стека
____выполняется return и управление передается на третью строку вызывающей функции где s="123" - это тоже
____восстанавливается из стека
__также как и раньше выполнится cout << *s, где на этот раз s = "123", т. е. cout << '1';
Ну и выведено будет 321.
Если не понятно - путь в кулинарный техникум, в моих детских книжках с большими рисунками так подробно не расписывалось )
при вызове функции состояние вызывающей функции помещается в стек, программный счетчик тоже относится к состоянию.
при выполнении return выполняется много всего, но в том числе, восстанавливается состояние вызывающей функции из стека, а значит, что после возврата из функции вычисление продолжается в вызывающей функции, с команды, следующей за вызовом функции. Читай внимательно.
В ярких книжках для детей привели бы такой пример (не совсем правильный)
т. е.
; //1
f(); //2
;//3
в строке 2 вызывается функция, она завершает работу (выполняет return) и вычисления продолжаются в вызывающей функции со строки 3.
И еще раз, рекурсивность на работу return влияния не оказывает никакого (вцелом, возможно, и оказывает в редких случаях{явно не без хардкода} при использовании оптимизирующего компилятора, когда компилятор либо заменит хвостовую рекурсию циклом, либо развернет рекурсию, например) - но это не ваш случай.
Ну а про стэк Вам Ягами неплохо написал :) Первый пришел, последний ушел. Прототип стека.... стопка бумаг, бумажки ложите и берете сверху, в вашем случае это выглядит так (я пробую проиллюстрировать как работает программа ваша) .
void reverse(char *s) {
____if(*s) //1
________reverse(s+1); //2
____else //3
________return; //4
____cout << *s; //5
}
на вход reverse пришла строка s = "123"
__строка не равна нулю, и выполнится reverse( "23" ); со второй строчки
____на вход reverse пришла строка s = "23"
____строка не равна нулю, и выполнится reverse( "3" ); со второй строчки
______на вход reverse пришла строка s = "3"
______строка не равна нулю, и выполнится reverse( "" ); со второй строчки
_________строка равна нулю, выполнится return, управление будет передано на третью строку вызывающей функции
______т. к. условие ранее выполнилось - то ветка else Игнорируется, выполняется cout << *s т. е. cout << '3'
______выполняется возврат (тут return не написан, но он подразумевается, т. к. функция возвращает void, при этом
______управление передается на третью строку вызывающей функции (там где состояние содержит s="23")
____аналогично предыдущему разу, ветка else не выполняется, выводится cout << *s, т. е. cout << 's' (т. к. s = "23") - это
____выдернуто из стека
____выполняется return и управление передается на третью строку вызывающей функции где s="123" - это тоже
____восстанавливается из стека
__также как и раньше выполнится cout << *s, где на этот раз s = "123", т. е. cout << '1';
Ну и выведено будет 321.
Если не понятно - путь в кулинарный техникум, в моих детских книжках с большими рисунками так подробно не расписывалось )
Потому что стэк, блин, что тут непонятного? Стэк - структура First in last out.
Точно так же, как и в обычной функции. Смотри:
if(*s) reverse(s+1); //если в строке что-то есть, вызываем reverse (оно выведет конец строки в обратном порядке)
else return; //если в строке ничего нет, ничего не выводим
cout << *s; //раз не произошло return, выведем один знак *s.
Может, тебе легче будет понять структурный код?
void reverse(char *s)
{
if(*s){
reverse(s+1);
cout << *s;
}
//здесь можно добавить какой-нибудь else return; или просто return;, но зачем - все равно функция закончилась
}
if(*s) reverse(s+1); //если в строке что-то есть, вызываем reverse (оно выведет конец строки в обратном порядке)
else return; //если в строке ничего нет, ничего не выводим
cout << *s; //раз не произошло return, выведем один знак *s.
Может, тебе легче будет понять структурный код?
void reverse(char *s)
{
if(*s){
reverse(s+1);
cout << *s;
}
//здесь можно добавить какой-нибудь else return; или просто return;, но зачем - все равно функция закончилась
}
явный return 1 раз обрезает заглубление
в остальных случаях срабатывает неявный ретурн по концу функции
Возвращаясь будет выполнять остаток кода после рекурсивного вызова и выводить последовательно от глубины до верха
в остальных случаях срабатывает неявный ретурн по концу функции
Возвращаясь будет выполнять остаток кода после рекурсивного вызова и выводить последовательно от глубины до верха
Похожие вопросы
- Здравствуйте. Никак не могу понять как нужно работать в Visual C++ 2010. Я только начинающий. Делаю следующее. Создаю
- Написал небольшую программу, не могу понять почему не работает цикл while и оператор else
- Что такое return. Объясните по простому, уже несколько статей и видеоуроков посмотрел, но так и не могу понять.
- Есть ли фактические параметры в рекурсивной функции? В ней же нет вызова функции?
- Помогите мне с рекурсивной функцией!
- Как работает return в языке программирования Java?
- Помогите. Не могу понять как работает поиск максимального элемента массива!!
- здравствуйте ,не давно начал изучать "язык програмиста" работаю в турбо паскале , не могу понят почему программа
- вам приходится работать с командной строкой в виндовс 7, она вообще нужна? чего то не могу понять для чего она, да и
- Помогите найти ошибку. Программа не работает. Пишет ELSE без IF. Не могу понять в чем дело.