Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: oblivionxor en 10 Febrero 2013, 01:58 AM

Título: Optimizacion de codigo en C.
Publicado por: oblivionxor en 10 Febrero 2013, 01:58 AM
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.
Título: Re: Optimizacion de codigo en C.
Publicado por: BatchianoISpyxolo en 10 Febrero 2013, 03:50 AM
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!
Título: Re: Muchas gracias!
Publicado por: oblivionxor en 10 Febrero 2013, 05:01 AM
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!