Buenas Prácticas de Programación en Lenguaje C

Anuncio
Buenas Prácticas de Programación en Lenguaje C
El presente documento recopila un conjunto de buenas prácticas de programación en lenguaje C
provenientes de diferentes fuentes que están especificadas al final del documento. Estas normas
pueden no ser estrictamente necesarias para que un programa funcione, pero son recomendables
para tener menos errores y para que, si los hay, sea más fácil encontrarlos. Los profesores tendrán
en cuenta en la corrección de los proyectos que usted emplee un buen estilo de programación.
La presente lista no está necesariamente completa, pero si contiene una cantidad significativa de
buenas prácticas de programación que deben seguir los estudiantes del curso.
1. Cada programa debe comenzar con un comentario que describa su propósito.
2. Hacer un diseño previo al programa (pseudo código, diagramas, ...). Se aconseja revisarla
antes de empezar a programar. Se empieza por la descomposición del problema en funciones,
para pasar luego al detalle de cada una. El pseudo código se emplea con frecuencia para
pensar el programa durante el proceso de diseño. Luego el programa en pseudo código se
convierte a su equivalente el C.
3. Su computadora y su compilador son buenos maestros. Si tras la lectura de su manual del
lenguaje C no está seguro del funcionamiento de alguna característica de C, experimente con
un pequeño programa de prueba y vea lo que sucede. Ajuste las opciones de su compilador
para que le devuelva el máximo de avisos. Estudie cada mensaje que aparezca al compilar sus
programas y corríja los errores y advertencias reportados para eliminar los mensajes.
4. Declaré las variables con nombres significativos ( o mnemotécnicos) esto ayuda a que los
programas estén auto documentados, es decir, que resulte más fácil entenderlos simplemente
leyéndolos en lugar de tener que consultar manuales o hacer referencia a muchos
comentarios.
5. Como en álgebra, para hacer más clara a una expresión es aceptable agregarle paréntesis
aunque estos no sean imprescindibles. Dichos paréntesis se llaman paréntesis redundantes.
Estos se emplean normalmente para agrupar sub-expresiones de expresiones más grandes.
6. Capture los resultados de todas las llamadas al sistema que su programe realice, y aplique el
tratamiento que corresponda en cada caso.
7. Idente la instrucción del cuerpo de una estructura if para que resalte la estructura y
simplificar la lectura del programa.
8. Su programa no debe tener instrucciones no alcanzables, es decir, que nunca se ejecuten, ni
realizar varias veces la misma operación sobre los mismos datos.
9. Al escribir expresiones que contengan muchos operadores, consulte la tabla de precedencia
de los operadores. Confirme que los operadores de la expresión se ejecutan en el orden que
espera. Si no está seguro del orden de evaluación de una expresión compleja, coloque
paréntesis para forzar el orden, justo igual como lo haría en una expresión algebraica.
Además, observe que algunos operadores, como el de asignación (=), se asocian de derecha a
izquierda, y no de izquierda a derecha.
10. La iniciación de variables cuando se declaran ayuda al programador a evitar los problemas
provocados por datos no inicializados.
11. En los programas no debe haber más que una instrucción por línea.
12. Sangre o idente las instrucciones de ambos cuerpos de las estructuras if/else.
13. Si hay varios niveles de sangrado, todos deben sangrarse con espacios iguales.
14. Siempre ponga llaves en las estructuras if/else (y en cualquier estructura de control) para
ayudarle a evitar su omisión accidental, especialmente si después le agrega instrucciones a
una cláusula if o else.
15. Inicialice todas las variables que use como los contadores y totalizadores.
16. Declare cada variable en una línea diferente.
17. Al efectuar divisiones entre una expresión cuyo valor podría ser cero, busque explícitamente
esta condición y manéjela de manera adecuada (imprimiendo un mensaje de error) en lugar de
permitir que suceda un error fatal.
18. Mediante un mensaje pídale al usuario todas las entradas de teclado. Dicho mensaje debe
especificar la forma de la entrada y los valores especiales que pueda tener (como el valor
centinela que debe indicar el usuario para terminar algún ciclo)
19. En los ciclos controlados por un valor centinela, las solicitudes de entrada de información
deben recordarle explícitamente al usuario dicho valor centinela.
20. No compare la igualdad o desigualdad de los valores de punto flotante. En cambio, pruebe
que el valor absoluto de la diferencia sea menor que un valor pequeño especificado.
21. Controle los ciclos con contadores por medio de variables enteras.
22. Para ayudarle a evitar los errores por diferencia de uno, utilice el valor final en la condición
de una estructura while o for y el operador relacional <=. Por ejemplo, para un ciclo que
imprime los valores 1 a 10, la condición de continuación del ciclo debería ser contador <= 10,
en lugar de contador < 10 (lo que es un error por diferencia de uno) o contador < 11 (que,
sin embargo, es correcta) No obstante, muchos programadores prefieren el llamado conteo
basado en cero, en el que para contar 10 veces, habría que inicializar contador a cero y la
prueba de continuación del ciclo sería contador < 10.
23. En las secciones de iniciación e incremento de las estructuras for sólo ponga expresiones
relacionadas con las variables de control. Las manipulaciones de otras variables deben
aparecer antes del ciclo (si sólo se ejecutan una vez, como las instrucciones de inicialización)
o en el cuerpo del ciclo (si se ejecutan una vez por repetición, como en el caso de las
instrucciones de incremento o decremento)
24. Aunque el valor de la variable de control puede cambiarse en el cuerpo del ciclo for, evite
hacerlo, pues esta práctica puede generar sutiles errores de lógica.
25. Evite reinventar la rueda. Cuando sea posible, utilice las funciones de la biblioteca estándar
de C en lugar de escribir nuevas. Con esto se reduce el tiempo de desarrollo de los
programas. A menos que al hacerlo, no cumpla con los objetivos del proyecto en cuanto al
aprendizaje de las herramientas descritas en las clases.
26. Cada función debe limitarse a efectuar una sola tarea bien definida, y el nombre de dicha
función debe expresar claramente la tarea. Esto promueve la reutilización del software.
27. Si no puede seleccionar un nombre conciso que exprese lo que hace la función es posible que
ésta haga demasiadas tareas. Generalmente es mejor dividir dicha función en varias partes
más pequeñas.
28. Agregue un caso default en las instrucciones switch. Los casos no probados explícitamente
en una instrucción switch que no tenga un caso default son ignorados. Al incluir el caso
default se enfoca al programador en la necesidad de procesar condiciones excepcionales. Hay
situaciones en las que no es necesario el procesamiento default.
29. Aunque las cláusulas case y el caso default de la estructura switch pueden suceder en
cualquier orden, se considera una buena práctica de programación poner la cláusula default al
último.
30. La declaración de una variable como global en lugar de local permite que sucedan efectos
secundarios cuando una función, que no necesita tener acceso a ella, la modifica
accidentalmente o por malicia. En general, las variables globales deben evitarse, excepto en
ciertas situaciones en las que hay requerimientos de desempeño especiales.
31. Las variables que sólo se utilizan en una función particular deben declararse como variables
locales de dicha función, en lugar de cómo variables globales.
32. Los programas deben escribirse como conjuntos de funciones pequeñas. Esto hace más fácil
escribir, depurar, mantener y modificar los programas.
33. Las funciones que requieran de un gran número de parámetros podrían estar efectuando
demasiadas tareas. Considere dividir la función en funciones más pequeñas que realicen las
distintas tareas. El encabezado de la función debe caber en una línea, de ser posible.
34. Cualquier problema que pueda resolverse por recursividad también puede resolverse por
iteración (de manera no recursiva) Normalmente se prefiere un enfoque recursivo sobre un
enfoque iterativo cuando el primero refleja de manera más natural el problema y su resultado
es un programa más fácil de entender y depurar. Otra razón para seleccionar la solución
recursiva es que tal vez no se encuentre una solución iterativa aparente.
35. Todo valor constante que se use más de una vez deberá estar declarado al principio del
programa con #define.
36. Los nombres usados para constantes, variables, tipos y funciones deben seguir las siguientes
reglas:
• Serán verbos para las funciones y nombres para tipos, variables y constantes.
• Se podrá abreviar una palabra en vez de ponerla completa, pero debe quedar claro
su significado.
• Los nombres de constantes deben ir en mayúscula.
• Los nombres de tipos tendrán la inicial mayúscula y el resto debe ir ́ en minúsculas.
• Los nombres de variables y funciones deben ir en minúsculas.
• Las variables cuyo sentido no quede suficientemente aclarado con su nombre,
deberá tener un comentario explicativo junto a su declaración.
• Las funciones deben llevar un comentario indicando sus objetivos, así como a que
resultados pretenden llegar en función de los datos de entrada.
• Toda entrada de datos (individual o ciclo de ellas) con scanf debe ir precedida de
un mensaje de petición con printf.
37. Evite los identificadores que comiencen con uno o dos caracteres de subrayado, pues podría
ser que el compilador de C utilice nombres de este tipo para fines internos. Esto evitará que
los nombres que usted determine se confundan con los nombres que el compilador
seleccione.
38. Dentro de los corchetes que definen el cuerpo de una función, idente el cuerpo de la función
un nivel. Esto resalta la estructura funcional de los programas y ayuda a simplificar su
lectura.
39. Sólo indique letras mayúsculas para los nombres de constantes de enumeración. Con esto se
resaltan las constantes en el programa, recordándole al programador que las constantes de
enumeración no son variables.
40. Algunos programadores siempre incluyen llaves en las estructuras do/while, incluso cuando
no son necesarias. Esto ayuda a eliminar las ambigüedades entre la estructura while y la
estructura do/while que contiene una sola instrucción.
41. Algunos programadores prefieren declarar las variables en líneas separadas. Este formato
permite la fácil inserción de comentarios descriptivos junto a cada declaración.
42. Para hacer más legibles sus programas, ponga espacios después de las comas (, )
43. La consistencia en la aplicación razonable de convenciones de sangrado a sus programas
simplificará notablemente su lectura. Sugerimos una tabulación fija de 1⁄4 de pulgada o tres
espacios en blanco por cada sangría.
44. Cada función debería caber en una ventana del editor. Sin importar su tamaño, lo importante
es que efectúe bien una tarea. Las funciones pequeñas promueven la reutilización del
software.
45. Establezca una convención para el tamaño de las sangrías y luego aplíquela de manera
uniforme. La tecla Tab sirve para crear sangrías, pero las tabulaciones pueden variar.
Recomendamos manejar tabulaciones de 1⁄4 de pulgada o (de preferencia) de tres espacios
por cada nivel de sangría.
46. Es posible distribuir una instrucción grande sobre varias líneas. Si tiene que dividir una
instrucción sobre varias líneas, seleccione puntos de ruptura que tengan sentido, como
después de una coma en el caso de una lista separada por comas o después de un operador
en el caso de una expresión larga. Si necesita dividir una instrucción en varias líneas, sangre
todas las líneas subsecuentes.
47. Algunos programadores prefieren colocar primero las llaves izquierda y derecha y después
introducir las instrucciones que van dentro de ellas. Con esto se evita la omisión de alguna
de dichas llaves.
48. Si hay demasiados niveles de anidamiento puede volverse difícil entender el programa. Como
regla general, trate de evitar codificar más de 5 niveles de sangrado.
49. Donde va una condición (if, while, for, ...) no se pondrá un número.
50. Ponga espacios en ambos lados de los operadores binarios. Con esto se resalta el operador y
se simplifica la lectura del programa.
51. Muchos programadores hacen que el último carácter impreso por una función sea un salto de
línea (\n) Esto asegura que la función dejará el cursor al inicio de una nueva línea. Las
convenciones de esta naturaleza promueven la reutilización del software, meta clave en los
entornos de desarrollo de software.
52. Los operadores unarios deben ponerse junto a sus operandos, sin espacios intermedios.
Enlaces a Otros Documentos que contienen Buenas Prácticas de Programación en C y que fueron
usados como base para la elaboración de este documento.
http://pis.unicauca.edu.co/moodle/mod/resource/view.php?inpopup=true&id=3623
http://www.google.co.ve/url?sa=t&source=web&ct=res&cd=6&url=http%3A%2F%2Fpersonales.unican
.es%2Fzorrillm%2FPDFs%2FDocencia%2FProgramacionComputadoras%2Festilo.pdf&ei=O77ASojGJJfk
8Ab2tmyAQ&rct=j&q=buenas+practicas+de+programacion+en+c&usg=AFQjCNH9W7LPMNx8RTCwELXIf
TynrSdDmQ
http://www.google.co.ve/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fazul2.bnct.ipn.mx
%2Fc%2Ffunciones%2Farchivos%2520%2528.pdf%2529%2Fcomplemento%2520lecciones%25201017.pdf&ei=O77ASojGJJfk8Ab2tmyAQ&rct=j&q=buenas+practicas+de+programacion+en+c&usg=AFQjCNF2kVSUyyGIxW9DL0TT53
vKNKYbFQ
Recopilación hecha por el Prof. Ricardo Gonzalez para el Curso de Redes 1 CI4835
Descargar