Это не пример закрытия, а рекурсии.
Чтобы понять, как рекурсия может привести к правильному результату, можно на мгновение предположить, что рекурсивный вызов возвращает правильный результат, и посмотреть, делает ли это общее возвращаемое значение правильным.
Давайте возьмем для примера этот основной вызов:
mlt(20, 4)
Выполнение перейдет к части else
и выполнит рекурсивный вызов:
return (a + mlt(a, b - 1));
Как вы можете получить, рекурсивный вызов сводится к mlt(20, 3)
. Теперь давайте на мгновение предположим, что этот рекурсивный вызов возвращает правильный результат, то есть 60. Посмотрите, что происходит в приведенном выше выражении:
return (20 + 60);
Это 80, что действительно является правильным результатом для нашего первоначального вызова mlt(20, 4)
. Таким образом, мы можем получить представление о том, как эта функция будет возвращать правильный продукт для любого заданного b
, если предположить, что функция делает это правильно и для b-1
.
Что происходит, когда b = 1
? Затем функция возвращает a
. Мы также видим, что это правильно. Так что с предыдущим выводом мы теперь можем быть уверены, что если b >= 1
, результат будет правильным.
Обратите внимание, что функция также будет делать это правильно для b = 0
, после чего начнется первый if
. Также обратите внимание, что эта функция не хорошо справляется с отрицательными значениями b
: in в этом случае функция будет повторяться с b-1
и в конечном итоге столкнется с ошибкой емкости стека.