О-о, что тут происходит? Во-первых, мы создали две переменные: одна для счётчика, чтобы считать от 1 до верхнего предела, а вторая для текущего результата.
Затем начинается главная часть: цикл while, который повторяется, пока счётчик меньше или равен n — числу, переданному в эту функцию. Код, который повторяется, простой: мы меняем значения наших двух переменных. Текущий результат умножается на счётчик, а счётчик увеличивается на 1.
В какой-то момент это условие — "счётчик меньше или равен n" — станет ложным, цикл больше не будет повторяться, а программа перейдёт к следующему этапу —
return result. К этому моменту результат станет ответом, потому что за время всех повторов в цикле, результат умножался на 1, затем на 2, 3 и так далее, пока не достиг значения n, каким бы оно ни было.
Давайте посмотрим, что компьютер делает шаг за шагом, когда мы вызываем факториал 3.
- Взять один аргумент — 3, известный внутри, как n
- Создать переменную counter, установить значение 1
- Создать переменную result, установить значение 1
- Проверить: в счётчике — 1, это меньше или равно n, поэтому
- Умножить result на counter и положить ответ — 1 — в result
- Добавить 1 к counter и положить ответ — 2 — в counter
- Вернуться и проверить: counter — 2, это меньше или равно n, поэтому
- Умножить result на counter и положить ответ — 2 — в result
- Добавить 1 к counter и положить ответ — 3 — в counter
- Вернуться и проверить: counter — 3, это меньше или равно n, поэтому
- Умножить result на counter и положить ответ — 6 — в result
- Добавить 1 к counter и положить ответ — 4 — в counter
- Вернуться и проверить: counter — 4, это не меньше и не равно n, поэтому остановить повтор и перейти к следующей строке
- Вернуть result — 6
Компьютер выполняет такие операции в миллиарды раз быстрее, но по сути это выглядит именно так. Общее название такого вида сформулированных повторений — "итерация". Наша программа использует итерацию, чтобы рассчитать факториал.
В прошлый раз мы рассматривали итеративный процесс с рекурсией, а в этот — итеративный процесс без рекурсии.
Оба используют технику итерации, но с рекурсивными вызовами нам не нужно менять значения, мы просто передаём новые значения в следующий вызов функции. А эта функция факториала не имеет рекурсивных вызовов вообще, поэтому все трансформации должны происходить внутри единственного экземпляра, единственной функциональной коробки. У нас нет выбора, кроме как менять значения содержимого.
Стиль программирования, который вы видели в предыдущих уроках, называется "декларативным". Сегодняшний стиль, с изменением значений, называется "императивным".
Сравните рекурсивный и нерекурсивный факториалы: