Optimizacion de codigo en C.

Iniciado por oblivionxor, 10 Febrero 2013, 01:58 AM

0 Miembros y 1 Visitante están viendo este tema.

oblivionxor

Hola que tal. Es mi primer tema aqui en la pagina de elhacker.net, y pues solo me gustaria una pequeña ayuda en un programa que elabore. Este programa imprime los factoriales de los numeros del 0 hasta el 10 con sus respectivas llamadas recursivas, es decir imprime las llamadas recursivas que se hacen en cada factorial agregandoles un salto de linea y un nivel de sangrado. El punto es que tengo dudas respecto a la estructura de mi codigo, es decir, quisiera saber si lo elabore con la optimizacion de codigo correcta o si aun se puede optimizar mas. Con optimizacion de codigo me refiero a que si esta correctamente estructurado y en cualquier respuesta, si se puede estructurar mas.


/* Se despliegan los factoriales de los numeros del 0 al 10, se utiliza la recursividad para calcularlos */
#include <stdio.h>

/* Prototipo de funcion */
long calculaFactorial( long numero );
void muestraLlamadasRecursivas( long numero );

/* Inicia la ejecucion del programa */
int main()
{

int i; /* Contador */

printf( "\n\n***Este programa imprime los factoriales de los numeros del 0 al 10\n" );
printf( "y sus llamadas recursivas a la funcion que calcula los mismos.\n" );
printf( "Este programa se crea con la finalidad de hacer que sea mas facil\n" );
printf( "entender el tema de recursividad***\n\n" );

/* Repite 11 veces; durante cada iteracion calcula el factorial de i y lo despliega en pantalla */
for ( i = 0; i <= 10; i++ )
{
printf( "%d! = %ld\n", i, calculaFactorial( i ) ); /* Imprimimos el valor del factorial */
muestraLlamadasRecursivas( i ); /* Llamamos a la funcion que imprime las llamadas a funcion */
}

return 0; /* Terminacion exitosa */

} /* Fin de main */

/* Definicion recursiva de la funcion factorial */
long calculaFactorial( long numero )
{
/* Caso base */
if ( numero <= 1 ) {
return 1;
} /* Fin de if */
else { /* Paso recursivo o llamada recursiva */
return ( numero * calculaFactorial( numero - 1 ) );
} /* Fin de else */
} /* Fin de la funcion factorial */

void muestraLlamadasRecursivas( long numero )
{
static int contadorEspacios = 1; /* es static para que el valor no se destruya entre las llamadas recursivas a funcion */
int contador = contadorEspacios; /* Variable que determinara el numero de espacios a imprimir */

for ( contador; contador >= 1; contador-- ) { /* Imprimimos los espacios correspondientes */
printf( " " );
} /* Fin de for */

if ( numero <= 1 ) {
printf( "1\n" );
printf( "-------------------\n" );
}
else {
printf( "%ld * factorial( %ld - 1 )\n", numero, numero ); /* Imprimimos la llamada recursiva */
contadorEspacios++; /* Agregamos 1 a la variable de espacios */
muestraLlamadasRecursivas( numero - 1 ); /* Llamamos recursivamente a la funcion */
}

contadorEspacios = 1; /* Reestablecemos la variable a 1 para que no se vallan a imprimir los espacios ya calculados en el factorial anterior*/
} /* Fin de funcion muestraLlamadasRecursivas */


Enserio agradeceria muchisimo su ayuda.

BatchianoISpyxolo

En general el código está bien. Las funciones no sobrepasan un Xterm (23 líneas).

¿Qué cosas modificaría? Pues generalizar ese problema para mostrar los factoriales de 0 a N con una constante:

/* Se despliegan los factoriales de los numeros del 0 al N, se utiliza la recursividad para calcularlos */
#include <stdio.h>

#define N 15

/* Prototipo de funcion */
long calculaFactorial( long numero );
void muestraLlamadasRecursivas( long numero );

/* Inicia la ejecucion del programa */
int main()
{

int i; /* Contador */

printf( "\n\n***Este programa imprime los factoriales de los numeros del 0 al %d\n", N );
printf( "y sus llamadas recursivas a la funcion que calcula los mismos.\n" );
printf( "Este programa se crea con la finalidad de hacer que sea mas facil\n" );
printf( "entender el tema de recursividad***\n\n" );

/* Repite N+1 veces; durante cada iteracion calcula el factorial de i y lo despliega en pantalla */
for ( i = 0; i <= N; i++ )
{
printf( "%d! = %ld\n", i, calculaFactorial( i ) ); /* Imprimimos el valor del factorial */
muestraLlamadasRecursivas( i ); /* Llamamos a la funcion que imprime las llamadas a funcion */
}

return 0; /* Terminacion exitosa */

} /* Fin de main */

/* Definicion recursiva de la funcion factorial */
long calculaFactorial( long numero )
{
/* Caso base */
if ( numero <= 1 ) {
return 1;
} /* Fin de if */
else { /* Paso recursivo o llamada recursiva */
return ( numero * calculaFactorial( numero - 1 ) );
} /* Fin de else */
} /* Fin de la funcion factorial */

void muestraLlamadasRecursivas( long numero )
{
static int contadorEspacios = 1; /* es static para que el valor no se destruya entre las llamadas recursivas a funcion */
int contador = contadorEspacios; /* Variable que determinara el numero de espacios a imprimir */

for ( contador; contador >= 1; contador-- ) { /* Imprimimos los espacios correspondientes */
printf( " " );
} /* Fin de for */

if ( numero <= 1 ) {
printf( "1\n" );
printf( "-------------------\n" );
}
else {
printf( "%ld * factorial( %ld - 1 )\n", numero, numero ); /* Imprimimos la llamada recursiva */
contadorEspacios++; /* Agregamos 1 a la variable de espacios */
muestraLlamadasRecursivas( numero - 1 ); /* Llamamos recursivamente a la funcion */
}

contadorEspacios = 1; /* Reestablecemos la variable a 1 para que no se vallan a imprimir los espacios ya calculados en el factorial anterior*/
} /* Fin de funcion muestraLlamadasRecursivas */



En este caso no es recomendable usar recursividad porque derrochamos demasiada memoria con cada cambio de contexto, aunque está bien de forma didáctica (para comprender la recursividad y porque generalmente el código es mucho más inteligible).

Y si preguntas por reestructurar... dividiría el main en dos funciones: 1 para el título y otra para el proceso principal, aunque no es imprescindible.

Por último, tus comentarios están bien pero son excesivos. Para alguien al que le vas a explicar algo nuevo están bien pero pero hay que mantenerlos escuetos y tratar de no poner comentarios innecesarios.

En conclusión, es un código interesante para comprender como funciona la recursividad pero inviable en un código optimizado.

¡Enhorabuena!
Puede que desees aprender a programar desde 0: www.espascal.es

oblivionxor

BatchianoISpyxolo muchas gracias por tus consejos y la respuesta, en realidad como dices lo unico que queria con este codigo era entender un poco mas la recursividad. Hasta luego!