12 de diciembre de 2018

Errores frecuentes.

   La siguiente es una lista de errores frecuentes observados en mis estudiantes o lectores del blog. Es una lista necesariamente incompleta y en frecuente actualización; sin embargo la considero de utilidad para el lector interesado en aprender de las experiencias de otros. Sobre todo si se considera que muchas veces se aprende más de los errores que de los aciertos.

   He tratado de clasificar los errores para facilitar al lector su ubicación, espero que ésta sea también de utilidad.

Sintaxis:
  • Omitir el punto y coma (;)  al final de las sentencias.
  • Olvidar las llaves de bloque asociadas a una estructura de control, cuando el número de sentencias es mayor a uno.
 Lectura de datos:
  • Olvidar el ampersand (&) antes de la variable: 
    • Incorrecto: scanf("%d", variable_int);
    • Correcto:   scanf("%d", &variable_int);
  • Utilizar secuencias de escape:
    • Incorrecto: scanf("%d\n", &variable_int);
    • Correcto:   scanf("%d", &variable_int); 
  • Utilizar el especificador de formato incorrecto:
    • Incorrecto: scanf("%d",  &variable_float);
    • Correcto:   scanf("%f",  &variable_float);
  • Utilizar el especificador de precisión para flotantes:
    • Incorrecto: scanf("%.2f", &variable_float); 
    • Correcto:   scanf("%f", &variable_float);
 Impresión de datos:
  • Utilizar el especificador de formato incorrecto:
    • Incorrecto: printf("El valor es %d\n", variable_float);
    • Correcto:   printf("El valor es %.2f\n", variable_float);
Estructuras de control:
  • Omitir las llaves del bloque cuando el cuerpo de la estructura de control tiene más de una sentencia.
  • Utilizar el operador de asignación "=" en lugar del operador de comparación "==".
Variables:
  • Pensar que las variables son automáticamente inicializadas con algún valor cuando no es así, utilizando en consecuencia valores "basura".
  • No inicializar (normalmente con cero) variables de tipo acumulador. 
 Funciones:
  • Olvidar colocar el tipo de dato a cada variable en la lista de parámetros.
  • Invocar a una función con más o menos parámetros de los que necesita, o con tipos de datos distintos a los especificados en la lista de parámetros.
  • Colocar corchetes a los arreglos cuando se pasan como argumento a una función: los arreglos se pasan como argumentos solamente con su identificador. Consulte más abajo la sección referente a Arreglos.
  • Hacer lectura de datos dentro de una función: si la función NO es de lectura de datos, la función no debe leer datos en su definición. Esta es una consideración de diseño más que un error en sí mismo.
  • Hacer impresión de datos dentro de una función: si la función NO es de impresión de datos, la función no debe imprimir los datos que gestiona en su definición. Esta es una consideración de diseño más que un error en sí mismo.
  • En una "biblioteca" personalizada de funciones, si una función A utiliza a una función B, B debe estar definida antes que A.
  • Invocar funciones que regresan un apuntador con el operador de des referencia. Consulte más abajo la sección referente a Apuntadores.
Arreglos:
  • No definir el tamaño de un arreglo.
  • Definir el tamaño de un arreglo en función de una variable. La mayoría de los compiladores modernos soportan esta característica sin problema; sin embargo, en el estándar ANSI C hacer esto es incorrecto, por lo que su programa estaría sacrificando su portabilidad.
  • No inicializar los elementos del arreglo cuando su valor inicial será utilizado.
  • Colocar más inicializadores que elementos en el arreglo.
  • Omitir el ampersand (&) en la lectura de elementos individuales en el arreglo (para un arreglo de enteros):
    • Incorrecto: scanf("%d", arreglo[i]); 
    • Correcto:   scanf("%d", &arreglo[i]);
  • Colocar corchetes al pasarle un arreglo a una función:
    • Incorrecto: funcion(arreglo[ ], n);
    • Correcto:   funcion(arreglo, n);
Apuntadores:
  • No utilizar el operador de des referencia cuando se quiere acceder al valor de a lo que apunta el apuntador (el valor al que hace referencia el apuntador): 
    • Incorrecto: printf("El valor es: %d\n", intPtr);
    • Correcto:   printf("El valor es: %d\n", *intPtr);
  • Utilizar un apuntador y asumir que se tiene espacio de almacenamiento como en un arreglo. Error común con cadenas:
    • char *s1; es distinto de char s2[100]
      • Incorrecto: fgets(s1, 100, stdin);
      • Correcto:   fgets(s2, 100, stdin); 
  • Utilizar el operador de des referencia en la invocación a funciones que regresan un apuntador. Ejemplo, considere (vea el Ejercicio 12 de la entrada Ejercicios selectos (apuntadores)):
    • int *arreglo, original[100]; (apuntador a entero y arreglo) y el siguiente prototipo int *copia(const int *original, int n); 
      • Incorrecto: *arreglo = *copia(original, n);
      • Incorrecto: *arreglo = copia(original, n);
      • Incorrecto:  arreglo = *copia(original, n);  
      • Correcto:    arreglo = copia(original, n);
Estructuras (struct):
  • Acceder a los elementos miembro de una estructura con el operador incorrecto:
    • Si la variable es de tipo estructura, se utiliza el operador punto (.).
    • Si la variable es de tipo apuntador a estructura, se utiliza el operador flecha (->).
  • Para una estructura definir elementos miembros de otra estructura que no está definida:
    • Sean e1 y e2 dos variables de tipo struct distintos: e2 puede tener elementos miembro del tipo de e1 si y sólo si el tipo struct de e1 está definido antes que e2.
Archivos:
  • Utilizar las funciones fwrite y fread para archivos de texto. Los archivos de texto se usan con fprintf, fscanf, fputs, fgets, etc.
  • Utilizar las funciones fprintf, fscanf, fputs, fgets, etc. para archivos binarios. Los archivos de binarios se usan con las funciones fwrite y fread.

No hay comentarios.:

Publicar un comentario