#include<stdio.h> #define MAX 16 long calculo(long numero); int main(int argc, char * argv[]) { long n; do { printf("Deme un número entero entre 1 y %d: ", MAX); scanf("%d", &n); fpurge(stdin); } while ( n < 1 || n > MAX); printf("El factorial de %d es %d\n", n, calculo(n)); return 0; } long calculo(long numero) { if (numero == 1) return numero; else return numero*calculo(numero-1); } /* Deme un número entero entre 1 y 16: 4 El factorial de 4 es 24 */
calculo()
. ¡Esta función contiene una llamada a sí misma!. La idea es sencilla: el factorial de 1 es 1, por definición. Si el número es 1, devolvemos 1 como factorial. Si el número es mayor que 1, digamos
n
, está claro que
n! = n*(n-1)!
, esto es, que el factorial de
n
es igual a
n
multiplicado por el factorial de
n-1
. Eso se expresa sin dificultad alguna mediante la sentencia
if-else
que constituye el bloque de la función
calculo()
. La sucesión de llamadas recursivas se detiene, finalmente, cuando el valor del parámetro real que se le proporciona es 1. Es instructivo seguir los valores que va tomando
número
, y sobre todo los valores que proporciona la sentencia
return
, a medida que progresa la sucesión de llamadas recursivas. Considérese esta nueva versión del programa, que proporciona idénticos resultados pero muestra la ruta de ejecución del código:#include<stdio.h> #define MAX 16 int numero_de_llamadas = 0; long calculo(long numero); int main(int argc, char * argv[]) { long n; long resultado; do { printf("Deme un número entero entre 1 y %d: ", MAX); scanf("%d", &n); fpurge(stdin); } while ( n < 1 || n > MAX); resultado = calculo(n); printf("El factorial de %d es %d\n", n, resultado); return 0; } long calculo(long numero) { long valor_proporcionado; int num_esta_llamada = numero_de_llamadas++; printf("Entrada - llamada: %d - número recibido: %d\n", num_esta_llamada, numero); if (numero == 1) valor_proporcionado = numero; else valor_proporcionado = numero*calculo(numero-1); printf("Salida - número de llamada %d- devuelve: %d\n", num_esta_llamada, valor_proporcionado); return valor_proporcionado; } /* Deme un número entero entre 1 y 16: 10 Entrada - llamada: 0 - número recibido: 10 Entrada - llamada: 1 - número recibido: 9 Entrada - llamada: 2 - número recibido: 8 Entrada - llamada: 3 - número recibido: 7 Entrada - llamada: 4 - número recibido: 6 Entrada - llamada: 5 - número recibido: 5 Entrada - llamada: 6 - número recibido: 4 Entrada - llamada: 7 - número recibido: 3 Entrada - llamada: 8 - número recibido: 2 Entrada - llamada: 9 - número recibido: 1 Salida - número de llamada 9- devuelve: 1 Salida - número de llamada 8- devuelve: 2 Salida - número de llamada 7- devuelve: 6 Salida - número de llamada 6- devuelve: 24 Salida - número de llamada 5- devuelve: 120 Salida - número de llamada 4- devuelve: 720 Salida - número de llamada 3- devuelve: 5040 Salida - número de llamada 2- devuelve: 40320 Salida - número de llamada 1- devuelve: 362880 Salida - número de llamada 0- devuelve: 3628800 El factorial de 10 es 3628800 */