Foro de elhacker.net

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.

Código
  1. /* Se despliegan los factoriales de los numeros del 0 al 10, se utiliza la recursividad para calcularlos */
  2. #include <stdio.h>
  3.  
  4. /* Prototipo de funcion */
  5. long calculaFactorial( long numero );
  6. void muestraLlamadasRecursivas( long numero );
  7.  
  8. /* Inicia la ejecucion del programa */
  9. int main()
  10. {
  11.  
  12. int i; /* Contador */
  13.  
  14. printf( "\n\n***Este programa imprime los factoriales de los numeros del 0 al 10\n" );
  15. printf( "y sus llamadas recursivas a la funcion que calcula los mismos.\n" );
  16. printf( "Este programa se crea con la finalidad de hacer que sea mas facil\n" );
  17. printf( "entender el tema de recursividad***\n\n" );
  18.  
  19. /* Repite 11 veces; durante cada iteracion calcula el factorial de i y lo despliega en pantalla */
  20. for ( i = 0; i <= 10; i++ )
  21. {
  22. printf( "%d! = %ld\n", i, calculaFactorial( i ) ); /* Imprimimos el valor del factorial */
  23. muestraLlamadasRecursivas( i ); /* Llamamos a la funcion que imprime las llamadas a funcion */
  24. }
  25.  
  26. return 0; /* Terminacion exitosa */
  27.  
  28. } /* Fin de main */
  29.  
  30. /* Definicion recursiva de la funcion factorial */
  31. long calculaFactorial( long numero )
  32. {
  33. /* Caso base */
  34. if ( numero <= 1 ) {
  35. return 1;
  36. } /* Fin de if */
  37. else { /* Paso recursivo o llamada recursiva */
  38. return ( numero * calculaFactorial( numero - 1 ) );
  39. } /* Fin de else */
  40. } /* Fin de la funcion factorial */
  41.  
  42. void muestraLlamadasRecursivas( long numero )
  43. {
  44. static int contadorEspacios = 1; /* es static para que el valor no se destruya entre las llamadas recursivas a funcion */
  45. int contador = contadorEspacios; /* Variable que determinara el numero de espacios a imprimir */
  46.  
  47. for ( contador; contador >= 1; contador-- ) { /* Imprimimos los espacios correspondientes */
  48. printf( " " );
  49. } /* Fin de for */
  50.  
  51. if ( numero <= 1 ) {
  52. printf( "1\n" );
  53. printf( "-------------------\n" );
  54. }
  55. else {
  56. printf( "%ld * factorial( %ld - 1 )\n", numero, numero ); /* Imprimimos la llamada recursiva */
  57. contadorEspacios++; /* Agregamos 1 a la variable de espacios */
  58. muestraLlamadasRecursivas( numero - 1 ); /* Llamamos recursivamente a la funcion */
  59. }
  60.  
  61. contadorEspacios = 1; /* Reestablecemos la variable a 1 para que no se vallan a imprimir los espacios ya calculados en el factorial anterior*/
  62. } /* Fin de funcion muestraLlamadasRecursivas */
  63.  

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:

Código
  1. /* Se despliegan los factoriales de los numeros del 0 al N, se utiliza la recursividad para calcularlos */
  2. #include <stdio.h>
  3.  
  4. #define N 15
  5.  
  6. /* Prototipo de funcion */
  7. long calculaFactorial( long numero );
  8. void muestraLlamadasRecursivas( long numero );
  9.  
  10. /* Inicia la ejecucion del programa */
  11. int main()
  12. {
  13.  
  14. int i; /* Contador */
  15.  
  16. printf( "\n\n***Este programa imprime los factoriales de los numeros del 0 al %d\n", N );
  17. printf( "y sus llamadas recursivas a la funcion que calcula los mismos.\n" );
  18. printf( "Este programa se crea con la finalidad de hacer que sea mas facil\n" );
  19. printf( "entender el tema de recursividad***\n\n" );
  20.  
  21. /* Repite N+1 veces; durante cada iteracion calcula el factorial de i y lo despliega en pantalla */
  22. for ( i = 0; i <= N; i++ )
  23. {
  24. printf( "%d! = %ld\n", i, calculaFactorial( i ) ); /* Imprimimos el valor del factorial */
  25. muestraLlamadasRecursivas( i ); /* Llamamos a la funcion que imprime las llamadas a funcion */
  26. }
  27.  
  28. return 0; /* Terminacion exitosa */
  29.  
  30. } /* Fin de main */
  31.  
  32. /* Definicion recursiva de la funcion factorial */
  33. long calculaFactorial( long numero )
  34. {
  35. /* Caso base */
  36. if ( numero <= 1 ) {
  37. return 1;
  38. } /* Fin de if */
  39. else { /* Paso recursivo o llamada recursiva */
  40. return ( numero * calculaFactorial( numero - 1 ) );
  41. } /* Fin de else */
  42. } /* Fin de la funcion factorial */
  43.  
  44. void muestraLlamadasRecursivas( long numero )
  45. {
  46. static int contadorEspacios = 1; /* es static para que el valor no se destruya entre las llamadas recursivas a funcion */
  47. int contador = contadorEspacios; /* Variable que determinara el numero de espacios a imprimir */
  48.  
  49. for ( contador; contador >= 1; contador-- ) { /* Imprimimos los espacios correspondientes */
  50. printf( " " );
  51. } /* Fin de for */
  52.  
  53. if ( numero <= 1 ) {
  54. printf( "1\n" );
  55. printf( "-------------------\n" );
  56. }
  57. else {
  58. printf( "%ld * factorial( %ld - 1 )\n", numero, numero ); /* Imprimimos la llamada recursiva */
  59. contadorEspacios++; /* Agregamos 1 a la variable de espacios */
  60. muestraLlamadasRecursivas( numero - 1 ); /* Llamamos recursivamente a la funcion */
  61. }
  62.  
  63. contadorEspacios = 1; /* Reestablecemos la variable a 1 para que no se vallan a imprimir los espacios ya calculados en el factorial anterior*/
  64. } /* Fin de funcion muestraLlamadasRecursivas */
  65.  
  66.  

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!