![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
n199a |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.11.2011 Репутация: нет Всего: нет |
У меня мозг кипит от того, как же понять, что из себя представляет рекурсия,
![]() Определение рекурсии я знаю ![]() Расскажите, пожалуйста, по-подробнее про это. Вот код для вычисления факториала с помощью рекурсии (странно, что, все авторы приводят первых примером вычисление факториала):
Давай я распишу все подробно, т.к. это "разложение по полочкам" будет только полезным для понимания. Пусть N будет равно трем. 1: int Fact(int N) Объявляем функцию Fact с типом int. В скобках объявляем переменную N типа int, значение которой будет возвращать данная функция Fact. 2: Без комментариев 3: Если введенное значение N будет меньше единицы, то выход по коду ошибки 0 в функцию. Другими словами завершаем вычисления. 4: Тогда если введенное значение N будет равно единице, то выход по коду ошибки 1. Возвращаем (return) единицу. 5: Если не то и не другое (описанное выше), то возвращаем в функцию Fact число, равное 3* (а вот что и как тут происходит меня заводит в тупик, объясните пожалуйста). |
|||
|
||||
mexanika |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 9.1.2011 Репутация: нет Всего: нет |
дальше вызывается Fact(2)
Добавлено через 2 минуты и 47 секунд в результате: 3 * 2 * 1 = 6 |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 4 Всего: 459 |
return возвращает не код ошибки, а вычисленный факториал. Когда функция вызывает сама себя, то происходит так как если бы вызвали не себя, а любую другую функцию. Т.е. переходим на 1ю строчку и начинаем все вычислять с новым входным параметром. При этом предыдущий вызов еще не завершился, он ожидает когда Fact(N-1); вернет свое значение чтобы продолжить свое выполнение. Фактически получаем число вложенных вызовов равное N . В каждом новом вызове N уменьшается на единицу, пока не станет равным 1, в этом случае сработает условие 4й строки и функция перестанет сама себя вызывать. После того как завершилась функция с N==1 это значение попадет в вызов где N==2 и 1 умножиться на 2 . Произведение 1 * 2 и есть результат функции Fact(2) . Fact(2) вернет значение 2 в вызов Fact(3) в котором оно умножиться на текущий N, который уже равен 3м, что даст 2*3=6 и так далее, пока мы не вернемся в самый первый вызов, который Fact(N) . В конечном итоге там уже получиться N*N-1*N-2...1
Этот ответ добавлен с нового Винграда - http://vingrad.com |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Я не придираюсь, я хочу понять. Вы действительно утверждаете, что функция Fact будет возвращать значение переменной N, которая объявлена в скобках? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
n199a |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.11.2011 Репутация: нет Всего: нет |
else return N * Fact(N-1);
Или можно так объяснить? ![]() Возьмем N=5. 5 * a-1 * b-1 * c-1 * d-1 // это целые числа, которые будут получаться на каждом последующем шаге, пока не достигнем N == 1 a b c d e // обозначения каждого шага Т.е. обозначим каждый шаг по букве (a,b,c,d,e) и ниже записаны просто результаты. a=5; b=5-1=4 c=4-1=3 d=3-1=2 e=2-1=1 В итоге в Fact получится a*b*c*d*e=5*4*3*2*1=120 Это сообщение отредактировал(а) n199a - 30.5.2013, 23:06 |
|||
|
||||
n199a |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.11.2011 Репутация: нет Всего: нет |
Вот меня это и вводит в заблуждение. Т.е. Fact(2) = 2 ?
Добавлено через 5 минут и 42 секунды
А как тогда правильно? ![]() |
||||
|
|||||
Arantir |
|
||||||||
Рыбак без удочки ![]() ![]() Профиль Группа: Участник Сообщений: 960 Регистрация: 18.11.2012 Репутация: нет Всего: 55 |
Это ближе к истине...
Функция — не одноразовый код. Ее можно вызывать сколько угодно, но под каждый вызов выделяется собственная область. Ее переменные в этих вызовах не пересекаются друг с другом. Она просто выполняет свой код, используя заданные аргументы, и возвращает значение. Вызов функции изнутри самой себя абсолютно ничем не отличается от ее вызова извне.
Читайте вызов функции в коде так же, как функции на уроке алгебры в школе. Если пишем "x = 5 * cos(n)", то нету никакого никакого "возвращаем в косинус...". Имеется ввиду, что 5 умножается на значение косинуса от аргумента n.
N умножается на значение, которое вернула функция Fact при значении аргумента равном N-1. И это точно такое же значение, как если бы вы эту функцию вызвали где-то еще, а не изнутри себя. Вот так по цепочке постоянно вызывая эту функцию компьютер приходит к Fact(1) из которой он просто возвращает единицу. Дальше вверх по цепочке во всех местах, где компьютер ждет, пока выполнится эта функция.
Да, все именно так. Добавлено @ 23:26 Чтобы проще представить, запишите это в алгебраическом представлении... Внутренние функции — это просто как вложенные скобочки. Вы ведь нормально воспринимаете запись "cos(cos(sin(5)))". вот тут то же самое.
Это сообщение отредактировал(а) Arantir - 30.5.2013, 23:29 -------------------- interface Жопа { // ATTENTION: has to be implemented by every class of the project for proper project work } |
||||||||
|
|||||||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Может так поможет ?
Добавлено через 1 минуту и 16 секунд
|
||||
|
|||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
![]() не столь важно, вопрос о рекурсии кал таковой ![]() |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
Arantir |
|
|||
Рыбак без удочки ![]() ![]() Профиль Группа: Участник Сообщений: 960 Регистрация: 18.11.2012 Репутация: нет Всего: 55 |
-------------------- interface Жопа { // ATTENTION: has to be implemented by every class of the project for proper project work } |
|||
|
||||
EgoBrain |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 537 Регистрация: 23.3.2008 Где: Комната Репутация: нет Всего: 2 |
mes подытожил: "рекурсия - кал"... в топку рекурсию.. ![]() Добавлено через 3 минуты и 5 секунд
Удобно рекурсировать главную функцию, когда нужно проверить работу программы при разных условиях/обрабатываемых данных/входных параметрах. |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
EgoBrain, вызов main запрещён по стандарту. Такое работает только в студии. В GCC - нет.
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
хоть и в топку, понять ее все равно не мешало бы ![]() вот еще один примерчик, для эксперимента :
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |