Скачиваний:
60
Добавлен:
15.09.2014
Размер:
1.25 Mб
Скачать

3.14. Рекурсии или итерации

В предыдущих разделах мы рассмотрели две функции, которые можно легко реализовать рекурсивно или итеративно. В этом разделе мы сравним эти два подхода и обсудим основания, по которым программист может пред­почесть в конкретной ситуации то или иной подход.

Как итерации, так и рекурсии основаны на управляющей структуре: итерации используют структуру повторения, рекурсии используют структуру выбора.

Как итерации, так и рекурсии включают повторение: итерации исполь­зуют структуру повторения явным образом, рекурсии реализуют повторение посредством повторных вызовов функции. Как итерации, так и рекурсии включают проверку условия окончания: итерации заканчиваются после на­рушения условия продолжения цикла, рекурсии заканчиваются после рас­познавания базовой задачи. Как итерации с повторением, управляемым счет­чиком, так и рекурсии постепенно приближаются к моменту своего завершения: в итерациях выполняется изменение счетчика до тех пор, пока он не примет значение, при котором перестает выполняться условие продол­жения цикла; в рекурсиях поддерживается процесс создания упрощенной

212 Глава 3

версии исходной задачи до тех пор, пока не будут достигнута базовая задача. Как итерации, так и рекурсии могут оказаться бесконечными: бесконечный итеративный цикл возникает, если условие продолжения цикла никогда не становится ложным; бесконечная рекурсия возникает, когда шаг рекурсии не упрощать исходную задачу таким образом, чтобы она сходилась к базовой. Рекурсия имеет много недостатков. Повторный запуск рекурсивного ме­ханизма вызовов функции приводит к росту накладных расходов: к нарас­тающим затратам процессорного времени или требуемого объема памяти. Каждый рекурсивный вызов приводит к созданию новой копии функции (на самом деле копируются только переменные данной функции); для этого может потребоваться значительная память. Итерации обычно не связаны с функциями, так что в них отсутствуют накладные расходы на повторные вызовы функции и дополнительные затраты памяти. Тогда для чего же при­менять рекурсию?

Замечание по технике программирования 3.13

Любые задачи, которые можно решить рекурсивно, могут быть решены также и итеративно (нерекурсивно). Обычно рекурсивный подход предпочитают итеративно­му, если он более естественно отражает задачу и ее результаты, то есть более нагляден и легче отлаживается. Другая причина предпочтения рекурсивного решения состоит в том, что итеративное решение может не быть очевидным.

Совет по повышению эффективности 3.5

Избегайте использования рекурсий в случаях, когда требуется высокая эффектив­ность. Рекурсивные вызовы требуют времени и дополнительных затрат памяти.

Типичная ошибка программирования 3.20

Случайный вызов нерекурсивной функции самой себя либо непосредственно, либо косвенно, через другую функцию.

Большинство учебников по программированию знакомит с рекурсией го­раздо позже, чем это сделано в этой книге. Мы считаем, что рекурсия — весьма обширная и сложная тема, так что лучше познакомиться с ней по­раньше и распределить ее примеры по всему остальному тексту книги. На рис. 3.17 приведена таблица, содержащая список примеров и упражнений по рекурсии в данной книге.

Давайте посмотрим еще раз на многочисленные советы, которые мы даем в этой книге. Хорошая техника программирования важна. Часто важна и высокая производительность. К несчастью, эти цели часто не совместимы друг с другом. Хорошая техника программирования — это ключевой момент в вопросе управления созданием все более сложных и крупных программных систем. Высокая производительность этих систем — ключ к созданию систем будущего, которые предъявят еще большие требования к аппаратным сред­ствам. Что же важнее?

Замечание по технике программирования 3.14

Функционализация программ в четком иерархическом стиле - свидетельство хоро­шей техники программирования. Но за все надо платить.

функции

213

Глава

Примеры и упражнения по рекурсии