Los 10 errores de programación para principiantes más comunes

Como programador de un comienzo de C ++, puede que nunca reconocer los errores que se realicen. Todo lo que cuenta es que se necesita mucho más tiempo para escribir y depurar sus programas. Incluso entonces, una vez que se implementan los programas que aún parecen tener errores molestos que deberían haber sido encontrados durante las pruebas.

Para ahorrar tiempo y problemas, busque los diez errores más comunes que hacen los programadores principiantes.

No seguir un estilo consistente escritura

Los seres humanos tienen una cantidad muy limitada de potencia de cálculo para trabajar con (la potencia de cálculo entre las orejas). Ellos necesitan para maximizar su efectividad cuando se toma en una tarea ciertamente difícil como la programación.

Los programadores no están utilizando sus computadoras de carbono a efecto máximo cuando tienen que vadear a través de programas que

  • ¿No tiene sangría constante

  • No utilice una convención clara para nombrar las cosas

  • No proporcione nombres significativos para las cosas

  • ¿No tiene comentarios significativos pero concisas

Una vez que usted ha adoptado un estilo de programación clara, empieza a sentir tan natural como los vaqueros de trabajo se tira cuando usted está combatiendo el trabajo de fin de semana en la casa. Usted no tiene que pensar en ello - usted sabe dónde están las cosas. Usted sabe, por ejemplo, que si un nombre se escribe con mayúscula, entonces es probable que el nombre de una clase. Si se trata de todas las tapas, entonces es una constante de algún tipo. Si se trata de una sangría, entonces es dentro de un bucle o un si comunicado. Tales convenciones le permiten pasar más de su valioso pensamiento el poder del cerebro sobre el problema que estamos tratando de resolver - y menos sobre los detalles de codificación.

Escritura de funciones que son demasiado grandes

La gente no comienzan con la intención de escribir funciones enormes. Ellos simplemente empezar a escribir. Esta función tiene que hacer esto, y después de eso, y, oh sí, esta otra cosa aquí. Muy pronto usted es de hasta 500 líneas de código o más - y es difícil de averiguar exactamente lo-todo que hace la función.

Grandes funciones son difíciles de depurar y mantener por varias razones:

  • Es difícil de entender exactamente lo que están tratando de hacer.

  • Hay demasiadas interacciones.

  • Hay demasiados caminos a través del código.

Una función es demasiado grande si viola cualquiera de las siguientes reglas:

  • Debe ser no más de 50 líneas de longitud.

  • Debe ser explicable en una frase que no contenga AND u OR.

  • Debe contener no más de ocho en total si declaraciones, interruptor declaraciones, o construcciones de bucle.

Por supuesto, la regla de 50 líneas es arbitrary- se hizo popular porque eso es lo que cabe en una sola página de papel impreso de computadora. Pero aún así es el tamaño adecuado para una cota superior. Por el momento se excede ese número, te estás metiendo "Cuando esta función se va a acabar?" territorio.

Así que, ¿qué hacer si usted se encuentra exceder estos límites? Se toma la función existente en varias subfunciones por preguntarse, "¿Qué hace esta función hace?" Cada vez que vea un AND u OR, es el momento de pensar función. Considere el siguiente ejemplo:

"Mi función recibe el nombre de un archivo desde el teclado, a continuación, abre el archivo y lee objetos estudiantiles hasta que llegue a la final y luego un promedio de sus GPA y muestra los resultados."

Esta descripción sugiere las siguientes funciones:

  • fstream getFileObject ()devuelve el identificador de un archivo indicado por el usuario.

  • ReadStudents Estudiante * (fstream) lee objetos Student desde un archivo.

  • averageStudentGPAs (Estudiante *) Es de las GPA para una colección de los estudiantes.

  • displayGPA (ostream cabo, doble ACP) muestra que el estudiante promedio de la corriente de salida.

Cada una de estas funciones es fácil de entender y se podría escribir en mucho menos de 50 líneas. La función original no hace más que llamar a estas subfunciones que hacer todo el trabajo.

Escribir código sin un plan

Dado un problema, los programadores principiantes son demasiado rápida para empezar a programar sin un plan. LA plan incluye toda una serie de cosas que el programador experimentado viene a dar por sentado:

  • Especificar los requisitos: El programador tiene que entender lo que el programa tiene que hacer.

    Esto puede sonar obvio, pero en el fragor de la batalla, es fácil pensar en sólo un aspecto del problema sin considerar el problema completo. Es necesario documentar el programa para impartir cierta comprensión a su usuario de lo que se supone que el programa para hacerlo. No se olvide de incluir los casos extremos. Esta es tu oportunidad de determinar la alcance del programa - a menudo el programador se centra en la solución de un problema particular mientras que los usuarios asumen que el programa va a resolver todos los problemas.

  • Diseñar el programa: El programador entonces tiene que sentarse y considerar, en un nivel muy alto, ¿cómo debería funcionar el programa.

    Esto es difícil para los principiantes porque no tienen la experiencia para caer de nuevo. El programador debe decidir cómo el programa funciona internamente - incluyendo cómo se colocan las tablas de base de datos (si los hay).

  • Diseño de la interfaz: El programador tiene que decidir cuál es la interfaz de usuario se verá así y cómo va a funcionar.

  • # 42 ¿El programa tiene su propia interfaz o va a ser visitada a través de un navegador?

  • # 42 ¿Cómo será la interfaz de usuario parece?

  • # 42 ¿Cómo va el usuario navegar de una ventana a otra?

  • Diseño de la prueba: Los principiantes se sorprenden al saber que el inicio del proyecto es el mejor momento para pensar acerca de las pruebas. Determinar cómo se prueba su programa afectará cómo usted pone hacia fuera.

  • El aprendizaje de un lenguaje de programación es sólo el primer paso para aprender a programar.

    Las variables globales

    Programadores principiantes tienden a declarar todas las variables a nivel mundial. "¿Por qué preocuparse por todas esas tonterías alcance? ¿Por qué no declarar la variable a nivel mundial para que pueda utilizarlo cuando quiero?" Pues bien, los problemas se producen cuando la variable tiene un valor que no esperas.

    ¿La variable no conseguir inicializado - ya sea porque se le olvidó o porque el flujo lógico no pasó por el código de inicialización? ¿O es que la variable obtener inicializado incorrectamente? ¿O es que la variable obtener inicializado correctamente pero luego restablecer por alguna otra función de un valor inesperado? Realmente no hay manera de decir - a no ser que se ejecuta el programa de una sección a la vez, manteniendo un ojo de águila en la variable.

    No hay nada más frustrante que encontrar que el problema que ha estado persiguiendo durante todo el día se remonta a una variable global, el cambio de los valores de forma inesperada, después de llamar a alguna función que no tiene nada que ver con esa variable.

    No validar la entrada del usuario

    Un programa debe tener mucho cuidado cuando se acepta la entrada externa. En primer lugar, el programa debe asegurarse de que la entrada del usuario no se desborde algunos buffer interno. En segundo lugar, si el programa utiliza la entrada del usuario para crear consultas, debe asegurarse de que dicha entrada no contiene controles que pueden filtrarse en la consulta. El no hacer estas comprobaciones básicas pueden hacer que su programa hackeable y un peligro para la sociedad.

    Más allá de ese riesgo, sin embargo, es necesario asegurarse de que lo que estás leyendo es en realidad lo que usted espera. Esto se hace normalmente con los marcadores. Por ejemplo, el siguiente formato se lee en las puntuaciones en una prueba del estudiante:

    1234 35 2345 37 3456 29 5678 31

    El primer número es la identificación de estudiante. El segundo valor es la puntuación correspondiente.

    El problema es que hay muy poca información posicional proporcionada que se puede utilizar para detectar al menos cuando el programa está fuera de sincronización - y tal vez para obtener de nuevo en sincronización. Considere lo que sucede si el archivo de entrada tiene incluso el más pequeño error:

    1234 3 5 2,345 37 3,456 29 5,678 31

    Aquí se inserta un espacio extra entre el '3' y el '5'. Así que ahora 1234 se le asignará el valor 3 en lugar de 35. Sin embargo, ¿qué pasa con pobre estudiante 0005? Ahora consigue un valor de 2.345 y así sucesivamente en la línea.

    La situación mejora si cada entrada se coloca en una línea independiente:

    1234 3 52 345 373 456 295 678 31

    Ahora es posible detectar un error en la primera fila. Aunque no fue detectado ese error, un programa bien escrito usaría los saltos de línea para volver a sincronizar de forma que sólo el valor para 1234 sería almacenado incorrectamente.

    El uso de un objeto de secuencia sin comprobar fallar

    Éste es tan fácil de meter la pata - y por lo tanto difícil darse cuenta hasta que lo haga.

    Es muy fácil escribir algo como lo siguiente:

    int valor while (! input.eof ()) {entrada >> valor processValue (valor)}

    Se supone que este bucle para leer valores de un flujo de entrada y procesa hasta que encuentre el archivo de Findel. El problema con este bucle es que funciona bien la mayor parte del tiempo. Si el programa encuentra un no entero en el archivo, sin embargo, el programa se convierte en un bucle infinito. Esto se debe a que una vez que el extractor se encuentra con algo que no entiende - por ejemplo, un personaje donde un número debe ser - que establece el indicador fallar en el objeto de entrada. A partir de ese momento, el extractor se niega obstinadamente a realizar ninguna entrada.

    Peor que la negativa a realizar E / S cuando la bandera fallar se establece es el hecho de que las funciones de flujo no se quejan de ello. El programa asume que todo lo que pasa a ser en valor se acaba de leer el archivo - cuando, en realidad, es sólo queda de una lectura anterior.

    El siguiente bucle es mucho mejor:

    int valor while (! input.eof ()) {entrada >> valor si (input.fail ()) {} desglose processValue (valor)}

    Ahora el bucle sale de si el programa o bien llega a fin de archivo o se encuentra con un valor que no entiende.

    El mal manejo de una excepción

    El mecanismo de excepción es una gran herramienta para el manejo de errores. Como cualquier herramienta, sin embargo, las excepciones pueden ser mal aplicados. El error más común es atrapar excepciones que usted nunca tuvo la intención. El siguiente fragmento de código muestra el principio:

    // Eliminar el filetry {deleteFile (nombre del archivo) -} // ignorar el error si el archivo no se presentcatch (...) {}

    El programador sabe que la borrar archivo() función emite un FileNotFoundException si el archivo que desea eliminar no está presente. En vez de coger esa excepción, sin embargo, ella coge todo. La mayoría de las veces, la excepción, probablemente se debe a que el archivo no está ahí, pero la excepción podría muy bien ser completamente ajenos. Por la captura y haciendo caso omiso de la excepción, el usuario no es consciente de que el archivo no se ha eliminado.

    El código apropiado aparecerá como sigue:

    // Eliminar el filetry {deleteFile (nombre del archivo) -} // ignorar el error si el archivo no se presentcatch (FileNotFoundException e) {}

    Nota: Las semillas de este error se establecieron en la decisión de lanzar una excepción si no se encuentra el archivo que desea borrar. Se podría argumentar que esto no es una situación excepcional, sino una parte del proceso normal - y debería haber dado lugar a un simple retorno de error.

    El no poder mantener un registro del programa

    Un sistema de producción necesita para grabar lo que está haciendo. Esto es especialmente cierto para los sistemas con acceso al Internet. A veces, "no funcionó" se trata de toda la información de depuración que un programador consigue. ¿Cómo en el mundo puede un programador decir qué ha pasado? Al referirse a los registros.

    Los sistemas de producción mantienen un registro constante de lo que están haciendo y que pidió que se haga. Al obtener el ID de la persona y el tiempo aproximado que se ha formulado la solicitud fracasado, un programador puede volver a entrar en los registros y encontrar la solicitud. Lo ideal sería que el registro le dirá el programador de la solicitud, si funcionaba o no, y si no, por qué no.

    La mayoría de las veces un programador llega a decirle a la gente lo que perdió en sus solicitudes -, pero si realmente hicieron tropezar con un problema con el programa, el registro debe ser capaz de dar el programador suficiente información para, al menos, volver a crear el error en el laboratorio donde puedo estudiar fuera de línea, encontrar el problema, y ​​empujar una solución a salir a la producción.

    No usar un depurador

    Un depurador da al programador la oportunidad de dar un paso lentamente a través de su código para entender mejor exactamente lo que está haciendo. Este paso es fundamental para un programa que no funciona - pero es igual de importante para un programa que parece estar funcionando bien.

    No sé el número de veces que he entramos por una función que está generando los resultados apropiados sólo para darse cuenta que la función no está funcionando de la manera que quiero que haga. O bien no maneja todos los posibles valores de entrada legal o - más probable - no detecta los posibles valores de entrada no válidos.

    El depurador le da más información para trabajar cuando se necesita una comprensión más detallada de lo que su programa está haciendo.

    No realizar copias de seguridad de su trabajo

    "Mi disco se ha estropeado y he perdido dos semanas de trabajo!" Realmente no hay excusa para esto a la antigua catástrofe, aunque puede tardar mucho tiempo para recuperarse de un fallo del disco. Es posible que tenga que volver a formatear un disco, reconstruir el sistema operativo, y quién sabe qué más - pero no debe ser más difícil de lo que la copia de archivos de un sistema a otro recuperar el código fuente que has escrito.

    Existen sistemas de bajo costo que automáticamente copias de seguridad de todo el disco en las noches. Otros sistemas de copias de seguridad de sus archivos a través de Internet, de manera casi continua. Estos sistemas no son caros - especialmente en comparación con programador horario.

    Otra cosa: las copias de seguridad nocturnas se pueden mantener en la misma habitación que el disco original - pero al menos una vez por semana, las copias de seguridad se deben mover a una ubicación física diferente para protegerse contra la pérdida debido al daño de fuego o agua.

    Si eres instalación de desarrollo como el acceso a Internet, puede mantener una copia de su código fuente y toda la documentación en la nube a través de un servicio comercial como DropBox.




    » » » » Los 10 errores de programación para principiantes más comunes