Anda di halaman 1dari 12

Cosas a tener en cuenta cuando se programa

en C
Morgan Nicolás
A 5 dias del final

Los punteros se utilizan para pasar valores por referencia. Es una buena
idea no trabajar con punteros, sino utilizarlos para llenar vectores o
matrices

Keep it simple. Es más facil buscar soluciones triviales y hacer asocia-


ciones que hacer programas complejos teniendo en cuenta cada cosa en
particular. Se organizado, y te va a ir bien

Recordar: las matrices se cuentan de arriba hacia abajo, de izquierda


a derecha. Es un error común equivocarse con el orden de ingreso para
rellenar o manipular matrices

Poner comentarios de que hace la función que hiciste

Nunca esta de más terminar cada lı́nea que se va a imprimir con barra
n

Declarar las variables al principio, para evitar errores de sintaxis

Para dar mas claridad al programa, no escribire más de una instrucción


por lı́nea. Si la instrucción es larga, conviene escribirla en várias lineas
o separar la instrucción en instrucciones pequeñas

Cerciorarse de que la acción que maneja la lógica de while sea falsa en


algún momento, para no generar bucles

Para contadores donde no se conoce la cantidad de iteraciones, es po-


sible usar valores centinela, por ejemplo, pedirle al usuario que escriba
cierto valor o caracter, que el algoritmo tome como final de la cuenta.

1
Tener en cuenta a la hora de hacer cuentas que en las divisiones los
denominadores no deben ser 0. Una forma de evitar este tipo de pro-
blemas es que antes de la cuenta el programa se fije si el denominador
es nulo

Todo contador debe usar variables enteras, para evitar errores por las
aproximaciones generadas por variables de punto flotante

En los switch, es determinante utilizar la función break al final de cada


case. A su vez, es importante poner un caso default, por si no se cumple
ningún caso especificado.

La diferencia entre break y continue es que la primera da por terminado


el contador, mientras que la ultima anula las instrucciones que están
por debajo, y se siguen las iteraciones

Prestar atención sobre cuando debe usarse el comando de asignación =


y cuando el de igualdad ==. Este error no es visible por el compilador
y puede hacer que el programa entre en bucles infinitos

Es importante conocer las funciones de la biblioteca de C, para no


tener que reinventar la rueda si necesitamos de una función especifica
en nuestro programa

Para claridad y simpleza, las funciones deben de realizar una sola cosa

Utilizar muchas funciones pequeñas es lo más óptimo para resolver un


problema. Hay que tener en cuenta que las funciones se definen fuera
de otras funciones, y en orden de importancia, es decir, no se puede
llamar a una función que está escrita por debajo de donde se la llama.
Otra buena práctica es que las funciones sean autocontenidas, que su
nombre ya indique cual es la acción que realizan

Un truco para randomizar un algoritmo basado en la función rand(), es


utilizar al principio del main la instrucción srand(time(NULL)), pre-
viamente incluida la librerı́a time.h. Esto hará que la lista aleatoria
que genera la función rand() sea distinta cada vez que se ejecute el
programa

Para deiferenciar mejor las variables, es una buena idea utilizar letras
mayúsculas para contadores y minúsculas para variables, con lo cual
con un breve vistazo sabremos de antemano para que usamos la variable
en cuestión

2
La idea de la recursividad es tener un caso trivial conocido, y por medio
de repetidas llamadas de la función llegar a ese caso trivial si no lo es
de entrada. Es necesario que los pasos recursivos converjan al caso base
o trivial, de lo contrario nos hallamos en un bucle infinito, tal y como
sucede en un while

3
Figura 1: Idea de recursión, caso para 5!

Inicializar los arrays es recomendable para evitar errores. La forma mas


sencilla es, por ejemplo para un vector de enteros, int vector[10] = 0.
De esta manera incializamos el primer elemento en cero y por defecto
todos los demás tambı́en se inicializan en cero. También esta bueno
hacerlo para las variables, ası́ se mejora el rendimiento del programa

Para variables simbólicas definidas previamente mediante #def ine, es


recomendable usar letras mayúsculas y utilizar guiones bajos como es-
pacios. Esto hace que resalten en el programa y que sean más legibles

Para arrays definidos como tipo char, podemos no dimensionarlos pre-


viamente si lo igualamos a un string que proporcionamos en el progra-
ma, por ejemplo char frase[] = ”Los hermanos sean unidos, porque esa
es la ley primera.. El compilador ya reservó la cantidad de espacios que
precisa, más uno que da final al array

Si el string que vamos a utilizar tiene que se ingresado por el usuario


y estamos usando un array, debemos de darle el suficiente tamaño. Si
esto no sucede van a aparecer errores tales como la destrucción de los
datos del programa

Si no se quiere modificar el valor original del elemento que se provee a


una función, se puede utilizar const antes de definir la variable en la
función, para que la misma no cambie el valor original, aunque en la
función se manipulen los valores. Un ejemplo de uso serı́a int Minimo-
ComunDivisor(const int a, const int b)

4
Para punteros, es una buena idea utilizar el prefijo ptr antes del nombre
de la variable en cuestión para señalar que es un puntero. A su vez,
cuando se definen los punteros, se hacen de la forma int *ptrX, osea,
poniendo asterisco antes del nombre de la variable

Es buena idea inicializar los punteros. Para ello, podemos usar una
variable auxiliar y hacer que el puntero apunte a la misma. un ejemplo
serı́a

int i = 0;
int ∗ ptrX;
ptrX = &i

Desreferenciar un puntero significa usarlo en una instrucción con un


asterisco en su nombre, para asignarle un valor por ejemplo. Desrefe-
renciar un puntero que no fue inicializado desencadena errores fatales,
por ser problemas de memoria. No desreferenciarlo cuando se quiere
modificar el contenido de la memoria a la que apunta es un error de
sintaxis

En la aritmética de punteros utilizada cuando referenciamos un pun-


tero a un array, la suma de enteros nos devuelve lugares de memoria
(e.g. ptrX + 3 ). Ahora, si queremos el valor, debemos desreferenciar
la instrucción (*(ptrX + 3). Para suma y resta de punteros entre sı́, se
debe de referenciar ambos punteros al mismo arreglo, sino la aritmética
no tiene sentido alguno. Debe de tenerse en cuenta que cuando se su-
ma un entero a un puntero dirigido a un array, el puntero mantiene su
posición. Por ejmeplo, si ptrX apunta al primer elemento de un array,
y se realiza la instrucción ptrX + 3, ptrX ahora apunta al 3er elemento
del array

Si bien un array es una especie de puntero, no vale la aritmética de


punteros. Esto es porque un array siempre apunta al primer elemento,
mas allá de las instrucciones que se le asignen

Un string puede ser asignado a un puntero:

char color[ ] = ”azul”;


Es equivalente a
const char ∗ ptrColor = ”azul”;

5
Es importante notar que un solo caracter no es un string. Pueden apa-
recer errores de memoria por cuestiones de privilegios, es decir, nor-
malmente un string precisa de una cantidad apreciable de memoria,
mientras que un caracter es un número entre 0 y 255

Cuando se generan estructuras, es recomendable por una etiqueta, la


cual es escribe después de cerrar la estructura y antes de ;. La etiqueta
debe dser tal que ayude a que el programa esté autodocumentado

Si la estructura se definió con typedef, no es necesario una etiqueta, ya


que la estructura lleva el nombre de la misma. Es recomendable que,
para diferenciar, la primera letra sea una mayúscula

Cuando se abren archivos, el lenguaje lo ve como un array enorme de


caracteres, mas el caracter EOF, cuando se lo asigna a una variable para
su lectura. Esto debe de tenerse en cuenta para el análisis de archivos

Allocar memoria se utiliza para punteros, especialmente cuando se quie-


re trabajar de forma dinámica. Toda allocación de memoria debe de
liberarse mediante free

Para conocer el tamaño de una estructura, se utiliza sizeof. Esto es


imprescindible para la allocación de memoria. A su vez, es recomenda-
ble verificar que se alloco de forma exitosa, utilizando, por ejemplo, la
función assert de la librerı́a assert.h

6
Funciones de librerı́as y demás curiosidades

ACLARACIÓN:
Las funciones aquı́ mostradas son sus prototipos. Cada función trae consigo
una breve descripción de lo que realiza.

Figura 2: Librerı́as de C, con una breve descripción de las mismas

7
Figura 3: Librerı́a math.h

8
Figura 4: Librerı́a ctype.h

Figura 5: Funciones de sdlib.h para pasar de strings a números

9
Figura 6: Funciones de sdlib.h de entrada/salida

Figura 7: Funciones de la librerı́a string.h para manipulación de strings

Figura 8: Funciones de la librerı́a string.h para comparación de strings

10
Figura 9: Funciones de la librerı́a string.h para búsqueda en strings

Figura 10: Funciones de la librerı́a string.h para memoria en strings

11
Figura 11: Últimas 2 funciones de la librerı́a string.h

Figura 12: Modos de apertura de archivos

12