Отправляет email-рассылки с помощью сервиса Sendsay

Программирование. Форум !!!

Футкция - так?

...::: Приветствую, Всех :::...

Думаю, думаю, но логически понять так и не могу.
В итоге правильно получается что функция решает факториал так:

Index = 5
1) Result := Index*MulNumber(Index-1)
| | |
20 5 4
2) Result := Index*MulNumber(Index-1)
| | |
60 3 20
3) Result := Index*MulNumber(Index-1)
| | |
120 2 60
4) Result := Index*MulNumber(Index-1)
| | |
120 1 120
Только так я понял как она решает ( и понял зачем в конце стоит
Result:=1 ) факториал, но как цифры "скачут" в первом 1) не ясно.

Ведь если Result := Index*MulNumber(Index-1) то это с логической точки
зрения будет выглядеть так:

Result := Index * MulNumber(index-1)
| | | | | |
1) 0 <- 5 * 4 ( index-1 ) =4
2) 20 <- 4 * 3 ( index-1 ) =3
3) 12 <- 3 * 2 ( index-1 ) =2
4) 2 <- 2 * 1 ( index-1 ) =1


Но ведь эта какая-то ерунда!

Правильно ли я понял то как функция вызывает саму себя (рекурсия)?

index=5

...
? 5 ? 5-1
Result:=Index*MulNumber(index-1);
|
||
... ? ? ? 4-1
Result:=Index*MulNumber(index-1);
|
||
... ? ? ? 3-1
Result:=Index*MulNumber(index-1);
|
||
... ? ? ? 2-1
Result:=Index*MulNumber(index-1);
|
||
... ? ? ? 1-1
Result:=Index*MulNumber(index-1);

Если это правильно, то что происходит дальше?

...::: by GENEMI :::...

Номер выпуска : 4317
Возраст листа : 568 (дней)
Количество подписчиков : 523
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/349122
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Mon, 11 Apr 2005 21:27:55 +0300 (#349122)

 

Ответы:

Здравствуйте, GENEMI,

Да-а, намутил ты...

Правильно, тебе про это и говорили, только функция вызывает не просто
саму себя, а новую копию себя. Каждый вызов ничего не знает о
предыдущих и последующих.
1шаг ? 5 ? 5-1
Result:=Index*MulNumber(index-1);
|
2шаг(1копия) ... ? 4 ? 4-1
Result:=Index*MulNumber(index-1);
|
3шаг (2копия) ... ? 3 ? 3-1
Result:=Index*MulNumber(index-1);
|
4шаг (3копия) ... ? 2 ? 2-1
Result:=Index*MulNumber(index-1);
|
5шаг (4копия) ... 1 1
Result:=Index; Здесь конец
рекурсии, т.к. не
создается более копий.
Результ=1 возвращается в 4 шаг, откуда и была вызвана.
Шаг 4 получает значение шага 5 и расчитывает результат. Результ=2 возвращается
в 3 шаг...
И так далее, что тут не понятно?
Одна функция вызвала ДРУГУЮ. Пусть название и параметры одинаковы, но
это ДРУГАЯ функция. Для нее выделяется ДРУГОЕ адресное пространство.

Ответить   Tue, 12 Apr 2005 08:24:12 +0600 (#349203)

 

<skipнуто>

Правильно-то правильно, но не совсем. Не путай рекурсию и циклы. Ты написал
к примеру
someVar:=sin(someVar)*sqrt(cos(someVar/3))
Как в таком выражении умножение sin на sqrt может выполниться раньше, чем
отработают сами функции sin и sqrt? А как sqrt может начать работу, пока
неизвестно, что вернёт cos??
ШП уже объяснил. Но то же самое подробнее.
Ты ж у себя понимание рекурсии расписал так, что умножение 5 на 4!
выполняется раньше, чем этот самый 4! будет вычислен. Нет. Сначала функция
вызывает саму себя, передавая новую копию Index, та в свою очередь повторяет
этот процесс, пока Index не станет равным 1. И при этом у каждой функции
СВОЙ Index (так как он принимается ею по значению). Вот когда в очередной
иркарнации Index станет равным 1, вот тогда сработает Exit, и этот вызов
функции закончится, вернув 1 как разультат. Предыдущий вызов никто не
отменял. И Index в ней по прежнему 2, так как в ней Index не изменился. Да,
он уменьшился на единицу, но результат НЕ БЫЛ присвоен, а просто передан в
качестве параметра в очередной вызов MulNumber. Ещё раз заостряю внимание на
тот факт, что в каждом вызове Index свой, так как во-первых, представляет
собой локальную переменную, а во-вторых, как параметр принимаемую по
значению. Вот тут только и выполнится умножение 2 на 1 и получится 2! Обрати
также внимание, что здесь никакого Exit нет. Этот вызов тоже завершается и
управление возвращается ещё выше по иерархии вызовов, где Index по прежнему
равен 3, а умножение даст 3*2! и т.д.

Ну теперь OK?

PS 2ШП Не стоит смущать человека насчёт адресных пространств. Это всё ж таки

не совсем тот термин. Хотя суть конечно та же -)

--
С уважением, boroden***@s*****.ru

Номер выпуска : 4320
Возраст листа : 569 (дней)
Количество подписчиков : 524
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/349246
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Шматко А.А. Tue, 12 Apr 2005 09:22:37 +0400 (#349246)

 

Привет GENEMI,

Вы мне письмо написали 11 апреля 2005 г. (понедельник), а я Вам отвечу вот что:

т.к. Index=1, то Result:=1 и выход из рекурсии

А дальше вверх по лесенки
120 5 24 5-1
Result:=Index*MulNumber(index-1);
|
||
... 24 4 6 4-1
Result:=Index*MulNumber(index-1);
|
||
... 6 3 2 3-1
Result:=Index*MulNumber(index-1);
//Возвращаем 2: MulNumber(3-1=2)
|
||
... 2 2 1 2-1
//Т.к. 1!=1 то MulNumber(1) = 1
В конце концов функция возвращает в основной поток программы 120, что
и есть 5!

P.S. Функция возвращает значение туда, откуда была вызвана.

Афоризм напоследок: У нас по-прежнему самые главные и самые умные сидят в разных
кабинетах.
Winamp глаголит: пока он молчит
12 апреля 2005 г. 7:49:41

Просто студент
Eugene mailto:rav***@o*****.ru

Номер выпуска : 4329
Возраст листа : 569 (дней)
Количество подписчиков : 524
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/349605
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Tue, 12 Apr 2005 19:26:42 +0400 (#349605)