You are on page 1of 11

CAPTULO 4 ESTRUCTURAS, PUNTEROS Y ASIGNACIN DINAMICA DE MEMORIA

4.1. TIPOS DE DATOS El lenguaje C proporciona cinco maneras diferentes de crear tipos de datos, stos son:

Estructuras Campos de bits Uniones Enumeraciones (ANSI) typedef

Estructuras

Las estructuras son un conjunto de datos agrupados que forman una entidad lgica. Tambin se dice que son una agrupacin de variables bajo un mismo nombre (o que se referencia bajo un mismo nombre). El formato general es el siguiente:
struct tipo_estructura{ tipo nombre_var; ... tipo nombre_var; } variable_estructura;

Ej 4.1. Definiendo un estructura llamada fecha.


struct fecha { int dia; int mes; int a; } d; /* Elementos de la estructura */

/*

Nombre de la variable

*/

/* fecha es el nombre de la estructura */

Este no es el nico formato, existen otros ms simples, los cuales estn indicados en la tabla 4.1.

34

Preparado por Juan Ignacio Huircn

Formato
struct fecha {...};

Descripcin Se define el nombre de la estructura fecha y la descripcin, pero no se ha definido ninguna variable. No se le ha dado nombre a la estructura, pero si se ha definido una variable j la cual tiene una descripcin que est definida entre { y }. Se declara una variable llamada s, cuya definicin del contenido es X. (El que fue o debe ser previamente definido). Se declaran 3 variables, todas con la estructura X

struct {....} j;

struct X s;

struct X a,b,c;

Tabla 4.1. Otras formas de definir una estructura.

Se pueden realizar operaciones con los miembros de las estructuras y no con la estructura en su conjunto. La nica operacin que se puede hacer es & (clculo de direccin). Al aplicrselo a la estructura devuelve la direccin del primer byte (octeto) que ocupa la estructura. Para referenciar los elementos individuales de la estructura, se usa el operador punto (.).
variable_estructura.nombre_elemento

Ej 4.3. Accesando los elementos de una estructura.


#include <string.h> void main() { struct direccion{ char calle[25]; int numero; char nombre[30]; } d; strcpy(d.calle,"Avd. Alemania"); d.numero=2010; strcpy(d.nombre,"Fulano"); }

Ej 4.4. Se pueden realizar operaciones si los elementos son de tipo numrico.


void main() { struct complex { float x; float y;} x; float modulo; x.x=0.5; x.y=10.0; modulo=sqr(x.x*x.x+x.y*x.y); }

Herramientas de Programacin

35

En el caso de ser requerido pueden definirse matrices o arrays, es decir:


struct direccion dir[100];

Para acceder a ella se puede hacer de la siguiente forma:


dir[1].numero= 1002;

Punteros a estructuras

Si se desea acceder a un miembro concreto de la estructura debe utilizarse un puntero de direccin. El formato para acceder es el siguiente:
nombre_puntero->nombre_elemento

Ej 4.5. Declaracin de un puntero a estructura.


struct direccion{ char calle[25]; int numero; char nombre[30]; } d; void main() { struct direccion *p; /* puntero a estructura */ ..... } /* En este caso no hay ninguna variable definida */

Ej 4.6. Forma de acceder a una estructura mediante un puntero.


#include<string.h> struct direccion { char calle[25]; int numero; char nombre[30]; }; void main() { struct direccion d, *p; /* se declara d */ p=&d; /* p contiene la direccion del primer byte de d */ strcpy(p->calle,"Avd. Alemania"); p->numero=2010; strcpy(p->nombre,"Fulano"); ..... }

36

Preparado por Juan Ignacio Huircn

Estructuras de bits El lenguaje C permite manipular y definir campos de longitud inferior a un byte. O sea, permite acceder a un bits individual dentro de un byte. Si el almacenamiento es limitado (RAM), se pueden definir y almacenar varias variables booleanas dentro de un byte. Algunos perifricos devuelven la informacin codificada dentro de un byte. La forma general de definir estos campos de bits es:
struct nombre_estructura { tipo nombre1: longitud; tipo nombre2: longitud; tipo nombre3: longitud; ... };

Los campos de bits, cuando son ms de uno, tienen que declararse como int, signed o unsigned . Si los campos de bits son de longitud uno, debe declararse como unsigned (Obvio!). Ej 4.7. Definicin de una variable en la que se especifcan los campos de bits.
#include<stdio.h> void main() { struct uart_reg { unsigned cardis:1; unsigned overrun:1; unsigned errorpar:1; } uart_st; if(uart_st.cardis)printf("Lleg } dato..!");

El conjunto de estos bits se trata como palabra de microprocesador. Si es IBM PC es de 16 bits. La estructura anterior se extiende a 16 bits, rellenndose por la izquierda. Las Uniones En C una union es una posicin de memoria que es utilizada por diferentes variables, la cuales pueden tener diferente tipo. La definicin de una union en cdigo es similar a una estructura.
union tipo_union{ int i; char c; } u;

Cuando se declara una union el compilador crea automticamente una variables suficientemente grande para guardar el tipo ms grande de variable de la union. Para acceder a las uniones se utiliza la misma sintaxis que se utiliza para las estructuras.
u.i=120;

Otro formato puede ser el siguiente:

Herramientas de Programacin

37

union{ int i; char c[2]; }u_var;

/* U: nombre de la union */ /* Puede considerarse como un int o */ /* dos bytes */ /* Nombre de la variable */

Segn el momento de ejecucin del programa, esa zona de memoria pude considerarse como entero o una cadena de caracteres o un campo de 16 bits, etc.. Ej 4.8. Declaracin de una union.
union { int i; char c[2]; } u; u.i=263;

/* 263 10 = 00000001 0000 0111 2 = 0107h */

Para este caso los valores para c[0] y c[1] son:


u.c[0]=7; u.c[1]=1;

Enumeraciones El estandar ANSI incorpor los tipos enumerados como extensin del C. Se define como el conjunto de constantes enteras con nombre que especifica todos los valores vlidos que una variable de ese tipo puede tomar. Un ejemplo en TurboC es la asignacin de los colores (en modo grfico) a una variable enum.

Ej 4.9. Definicin de enumeraciones.


enum COLORS { BLACK, BLUE,GREEN, CYAN,RED, MAGENTA,BROWN, LIGHTGRAY,DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE };

Para este caso BLACK es equivalente a decir 0 y WHITE es igual a decir 15.

38

Preparado por Juan Ignacio Huircn

Ej 4.10. Otra forma.


void main() { enum color { rojo, azul, verde=4, amarillo}; enum color x, *px; x=rojo; /* x=0 */ *px=amarillo; /* *px=5 */ }

typedef El C permite al programador definir explcitamente nuevos nombre para los tipos de datos usando la palabra clave typedef. Realmente no se crea un nuevo tipo de datos, sino que se define un nuevo nombre para un tipo ya existente. Ej 4.11. Utilizacin del typedef.
void main() { typedef struct{ char nombre[20]; int edad; } persona; persona p[100]; /* Declaracin de una matriz de 100 personas */ }

Herramientas de Programacin

39

4.2. ASIGNACIN DE MEMORIA DINMICA Recordando la estructura direccin , declarada el apartado anterior, podramos definirnos una matriz de 1000 elementos, sin embargo, estaramos definiendo demasiadas variables dentro de la zona de datos. Si esta es una zona limitada, tendremos problemas. Suponiendo que tenemos un limite de 64Kb para datos:
void main() { struct direcciones dir[1000]; int a[20000]; .... }

Para solucionar este problema podemos usar memoria dinmica. Para este efecto debemos saber cuanta memoria en bytes requieren nuestros datos, entonces, debemos determinar el largo de la estructura en bytes. Para este propsito se utiliza la funcin sizeof.

Ej 4.12. Reservando memoria dinmica.


#include<string.h> #include<alloc.h> void main() { struct direcciones d, *pdir, *pdiri; int largoreg; largoreg=sizeof(d); pdiri=pdir=(struct direcc iones *)farmalloc(1000*largoreg); strcpy(pdir->calle,"Avd. Alemania"); pdir->numero=2010; strcpy(pdir->nombre,"Fulano"); pdir++; /* para accesar el segundo dato */ }

4.3. PASO DE ESTRUCTURAS A FUNCIONES El paso de estructuras a funciones se puede realizar pasando un puntero asociado a la direccin de dicha estructura, el tratamiento es similar a paso de argumentos por referencia. Ej 4.13. El siguiente programa permite el paso de las variables z y z2, definidas en una estructura llamada complejo , a una funcin llamada suma, la que realiza dicha operacin con dos nmeros complejos devolviendo el resultado en z.

40

Preparado por Juan Ignacio Huircn #include<conio.h> #include<stdio.h> struct complejo { float x; float y; }; /* Definicin de un complejo */ /* real */ /* imag */

void suma(struct complejo *z1, struct complejo *z2); void main() { struct complejo z, z2;

/* Definiendo z, z2 "complejos" */

z.x=1.0;z.y=2.0; z2.x=3.0;z2.y=3.0; suma(&z,&z2); /* Deuelve la suma en z */ printf("%f +j %f", z.x, z.y); getch(); } void suma(struct complejo *z1, struct complejo *z2) { (*z1).x=(*z1).x+( * z2).x; (*z1).y=(*z1).y+(*z2).y; /* Retorna el resultado en z1 */ }

Finalmente muestra el resultado en pantalla: 4.000000 + j 5.000000

Herramientas de Programacin

41

4.4. FUNCIONES Y PUNTEROS El uso de punteros y funciones est bastante relacionado, por un lado tenemos el paso de parmetros por referencia, cuando se utiliza alguna funcin, y por otro la llamada de funciones usando punteros. Punteros a funciones Una caracterstica (un poco confusa) muy til del lenguaje C es el puntero a funcin. La confusin surge porque una funcin tiene una direccin fsica en memoria que puede asignarse a un puntero, aunque la funcin no es una variable. La direccin de la funcin es el punto de entrada de la funcin; por lo tanto el puntero a funcin puede utilizarse para llamar dicha funcin. Bsicamente un puntero a funcin es una direccin, usualmente un segmento de cdigo, donde el cdigo ejecutable de la funcin est almacenado. Un puntero a funcin se declara de la siguiente forma
tipo (*nombre_puntero_funcion)();

Donde tipo es el tipo retornado por la funcin. Ej 4.14. Formas de declaracin de punteros a funcin.
void (*func)(); /* No recibe argumentos y no retorna nada */ void (*func)(int); /* No retorna nada pero toma un argumento entero*/

La direccin de la funcin se obtiene utilizando el nombre de la funcin sin parntesis ni argumentos (similar a como se obtiene la direccin de un array). Ej 4.15. Utilizando un puntero a funcin.
#include <stdio.h> void funcion(void); void (*f)(); void main() { f=funcion; (*f)(); }

/*

Ejecuta funcion() */

void funcion() { printf("Funcion \n"); }

42

Preparado por Juan Ignacio Huircn

Los punteros a funciones son muy cmodos cuando se utilizan tablas de decisin. Veamos el siguiente ejemplo: Ej 4.16. Utilizando punteros a funciones.
#include <stdio.h> #include <conio.h> int int int int f1(void); f2(void); f3(void); f4(int j);

void main() { int (*g)(int); /* puntero a funcion */ struct { int (*f)(); } mpf[3]={ {f1}, {f2}, {f3} }; int i=2; g=f4; i=(*g)(i); (*mpf[i].f)(); } int f1(void) { printf("Funcion 1\n"); getch(); return(1); } int f2(void) { printf("Funcion 2\n"); getch(); return(2); } int f3(void) { printf("Funcion 3\n"); getch(); return(3); } int f4(int j) { printf("Funcin 4\n"); return(j); }

/* se llama f4 con argumento 2 */ /* llama a la funcion f3 */

Herramientas de Programacin

43

You might also like