Algunos errores típicos de los programas en C
while (i< LIM);
Estructura de una función
/*declaración del tipo de los parámetros */
tipo nom_par1;
tipo nom_par2;
. . .
tipo nom_parN;
{
/* declaración de las variables locales */
tipo variable1;
tipo variable2;
. . .
tipo variableK;
sentencias_del_cuerpo_de_la_función;
return valor;
}
tipo_dato nombre_var;
Si tenemos mas de una variable/parámetro del mismo tipo, se pueden
declarar en la misma sentencia, separando los nombres con el carácter
,:
tipo_dato nombre_var1,nombre_var2;
tipo_dato nombre_var=valor_inicial;
Algunos tipos de Datos en C
Enteros: short, int, long
Coma flotante: float, double
tipo_elemento nombre_var[num_elementos];
int dni[8];
Declara un array de 8 enteros
Y las siguientes sentencias modifican el primer y el último elemento
de la variable:
dni[0]=4;
dni[7]=8;
int matriz[8][10];
struct {
tipo1 campo1;
tipo2 campo2;
tipo3 campo3;
} nombre_var;
Por ejemplo:
struct {
char nombre[30];
int dni[8];
int edad;
} ficha_alumno_1;
struct nombre_patron{
tipo1 campo1;
tipo2 campo2;
tipo3 campo3;
};
Y luego, al declarar las variables se puede usar el nombre del
patrón:
struct nombre_patron nombre_var1, nombre_var2;
El tipo string no existe como tal. Un string es un array de
carácteres en el que se marca el final con el carácter nulo
(código ASCII 0: '\0').
El lenguaje C ofrece muchas
funciones de manipulación de strings,
pero para usarlas correctamente debemos estar seguros de que los arrays que
se le pasan tienen la marca de fin (si no es asi, el comportamiento de las
funciones es indefinido).
El programador puede definir nuevos tipos mediante la sentencia typedef.
Esta sentencia se tiene que situar fuera del ámbito de todas las
funciones:
typedef nuevo_tipo definicion;
typedef boolean short;
Constantes en C
char variable='A';
printf("Hello world");
Hay que tener presente que al poner una tira de caracteres entre
comillas dobles el compilador añade al final el carácter
nulo.
#define NOMBRE_CTE valor
#define MAX_VALOR 200
Operadores en C
Control de ejecución
Cuando el cuerpo de un bucle o de un condicional está formado por
mas de una sentencia es necesario marcar el principio y el final del cuerpo
con las llaves. Si sólo está formado por una sentencia las
llaves son opcionales.
while (expresion) {
sentencias;
}
do {
sentencias;
}while (expresion);
for (inicializaciones; expresion; actualizaciones) {
sentencias;
}
if (expresion) {
sentencias;
}
if (expresion) {
sentencias;
}
else {
sentencias;
}
if (expresion) {
sentencias;
}
else if (expresion) {
sentencias;
}
switch (expresion){
case etiqueta1: sentencias;
break;
case etiqueta2: sentencias;
break;
case etiqueta3: sentencias;
break;
default: sentencias;
}
Punteros
int *p_int;
Esta sentencia declara una variable de nombre p_int (por lo tanto, tendrá
una posición de memoria asignada), que va a contener una dirección
de memoria, en la que se almacenará un entero.
p_int=&i;
Esta sentencia utiliza el operador & para obtener la dirección
de memoria en la que se guarda la variable i y se la asigna a la
variable p_int.
*p_int=4;
Esta sentencia obtiene el valor que guarda p_int, y accede a la posición
de memoria que indica ese valor (es decir, accede a la posición de
memoria en la que se guarda la variable i) para dejar un 4.
Uso de punteros para paso de parámetros por referencia
Si interesa que esas modificaciones se conserven una vez que se sale de la
función, necesitamos una manera para que el código de la
función acceda a la posició de memoria en la que tenemos la
variable que se pasa como parámetro.
int funcion(param1,param2)
int *param1;
char *param2;
{
int i=*param1+10;
. . .
*param1=4;
*param2='a';
. . .
}
Esta función recibe dos parámetros que quiere modificar, por
lo tanto en lugar de pasarle los datos, se le tiene que pasar la
dirección de memoria donde se guardan esos datos. Y para acceder
a ellos utiliza el operador de indirección *.
main(){
int i=17;
char c='b';
. . .
funcion(&i,&c);
. . .
}
Uso de punteros en la gestión de memoria dinámica
Siempre que sea necesario utilizar memoria dinámica para almacenar
una estructura de datos, se puede declarar la variable como un apuntador
al tipo de la estructura, y retrasar la inicialización hasta que
se reserva la memoria. Cuando es posible hacer esta reserva, se asigna
a la variable que se había declarado la dirección de memoria
reservada, para que sea posible el acceso.
Por ejemplo, si se quiere implementar una lista de tamaño variable,
cada vez que haya que añadir un nodo, habrá que reservar
memoria para el nuevo nodo antes de inicializarlo. Suponiendo que
habeis definido el tipo nodo_t:
nodo_t *nodo_aux;
. . .
nodo_aux=malloc(tamanyo_nodo);
inicializar_nodo(nodo_aux);
insertar_nodo(lista, nodo_aux);
. . .
Uso de punteros en la manipulación de arrays
Por lo tanto, una función que tiene un array como
parámetro puede ser de cualquiera de las dos maneras siguientes:
funcion(param)
char param[];
{
. . .
param[0]=4;
. . .
}
funcion(param)
char *param;
{
. . .
param[0]=4;
. . .
}
Uso de ficheros cabecera
El nombre de este tipo de ficheros suele terminar con el sufijo .h
#include <nombre.h>
#include "nombre.h"
Cuando el preprocesador se encuentra con esta directiva, la substituye por el
contenido del fichero que se le indica (nombre.h). De manera, que el
efecto es el mismo que si se hubiera escrito directamente en ese punto el
contenido del fichero.
Paso de parámetros al main
Es posible pasarle parámetros al programa desde la línea de
comandos. Para ello se considera que la función main tiene dos
parámetros llamados argc y argv.
main (argc,argv)
int argc;
char *argv[];
{
. . .
}
argc es un entero que contendrá el número de
parámetros que ha recibido el programa. Y argv es un
array de strings, que contiene en cada posición uno de esos
parámetros. El nombre del ejecutable también se considera
un parámetro, así que argv[0] contendrá siempre
ese nombre.
Compilación de un programa sencillo escrito en C en un entorno Unix
La manera más simple de compilar un programa escrito en C, es mediante
el comando cc:
cc fichero_fuente
Este comando generará (si no hay ningún error de
compilación en el fichero fuente) un ejecutable al que llamará
a.out. Si queremos que el ejecutable tenga un nombre diferente podemos
utilizar la opción -o:
cc -o nombre_ejecutable fichero_fuente
La documentación de soporte a la práctica 2 contiene más
información sobre el proceso de generación de ejecutables.
Algunas funciones de la librería de C
Recordad que un string es un array de caracteres que tiene como marca de final
el carácter '\0'. Si utilzáis un array de caracteres que no tenga
este carácter, el comportamiento de estas funciones será
erróneo y aleatorio.
También debéis tener presente que "a" indica constante
de tipo string, mientras que 'a' indica constante de tipo carácter.
Así, para almacenar la constante "a" se necesitaría como
mínimo un array de 2 posiciones (para 'a' y para '\0').
Algunos errores comunes en la programación en C
Es un bucle infinito, por mucho que despues del ';' añadáis
lo que vosotros pretendíais que fuera el cuerpo del bucle.
(volver al tablón de anuncios de ISOP)
Si tienes alguna sugerencia sobre la página:
yolandab@ac.upc.es