Проще говоря, хвостовая рекурсия - это рекурсия, в которой компилятор может заменить рекурсивный вызов командой "goto", поэтому скомпилированная версия не должна будет увеличивать глубину стека.
Иногда разработка хвостовой рекурсивной функции требует создания вспомогательной функции с дополнительными параметрами.
Например, это не хвостовая рекурсивная функция:
int factorial(int x) {
if (x > 0) {
return x * factorial(x - 1);
}
return 1;
}
Но это хвосто-рекурсивная функция:
int factorial(int x) {
return tailfactorial(x, 1);
}
int tailfactorial(int x, int multiplier) {
if (x > 0) {
return tailfactorial(x - 1, x * multiplier);
}
return multiplier;
}
потому что компилятор может переписать рекурсивную функцию в нерекурсивную, используя что-то вроде этого (псевдокод):
int tailfactorial(int x, int multiplier) {
start:
if (x > 0) {
multiplier = x * multiplier;
x--;
goto start;
}
return multiplier;
}
Правило для компилятора очень простое: когда вы найдете " return thisfunction(newparameters);
", замените его на " parameters = newparameters; goto start;
". Но это может быть сделано только в том случае, если значение, возвращаемое рекурсивным вызовом, возвращается напрямую.
Если все рекурсивные вызовы в функции можно заменить таким образом, то это хвостовая рекурсивная функция.