Está en la página 1de 20

La capacidad para crear nuevos tipos de datos es una caracterstica importante y potente de C y libera a un programador de restringirse al uso de los

tipos ofrecidos por el lenguaje. Una estructura contiene multiples variables, que pueden ser de tipos diferentes. La estructura es importante para la creacin de programas potentes, tales como bases de datos u otras aplicaciones que requieran grandes cantidades de datos. Una estructura es una coleccion de una o mas tipos de elementos denominados miembros, cada uno de los cuales pueden ser un tipo de dato diferente. Una estructura puede contener cualquier nmero de miembros, cada uno de los cuales tiene un nombre nico denominado nombre del miembro. Supongamos que se desea almacenar los datos de una colección de discos compactos (CD) de msica.

Nombre Artista Ttulo Nmero de cancin Precio Fecha de compra

Tipo de dato Array de caracteres de tamao 30 Array de caracteres de tamao 30 Entero Flotante Array de caracteres de tamao 8

DECLARACIN DE UNA ESTRUCTURA Una estructura es un tipo de dato definido por el usuario, que se debe declarar antes de que se pueda utilizar. El formato para la declaracin de una estrucutra se muestra en los siguientes ejemplos: Ejemplo: La declaracin de la estructura CD es: struct coleccion_CD { char titulo[30]; char artista[30]; int num_canciones; float precio; char fecha_compra[8]; };

Ejemplo: En este caso la declaracin de una estructura de ventas: struct venta { char vendedor[30]; unsigned int codigo; int inids_articulos; float precio_unit; };

DEFINICIN DE VARIABLES DE ESTRUCTURAS Al igual que los tipos de datos enumerados, a una estructura se accede utilizando una variable o variables que se definen despus de la declaracin de la estructura. Una declaracin especifica simplemente el nombre y el formato de la estructura de datos, pero no reserva almacenamiento en memoria; la declaracin especifica un nuevo tipo de dato:struct <nombre_estructura>. Las variables de estructuras se pueden definir de las siguientes formas: 1)Listndolos inmediatamente despus de la llave de cierre de la declaracin de la estructura. struct coleccion_CD { char titulo[30]; char artista[30]; int num_canciones; float precio; char fecha_compra[30]; } cd1, cd2, cd3; 2) Listando el tipo de estructura creado seguido de las variables correspondientes en cualquier lugar del programa antes de utilizarlas. struct coleccion_CD cd1, cd2, cd3;

USO DE ESTRUCTURAS EN ASIGNACIN Como una estructura es un tipo de dato similar a un int o un char, se puede asignar una estructura a otra. Por ejemplo, se puede hacer que cd2 y cd3 tengan los mismos valores en sus miembros que cd1. Por lo consiguiente seria necesario realizar las siguientes sentencias: cd2=cd1; cd3=cd1; De modo alternativo se puede escribir: cd3=cd2=cd1;

INICIALIZACIN DE UNA DECLARACIN DE ESTRUCTURAS Se puede inicializar la estructura de 2 formas: 1. Dentro de la seccin de cdigo de su programa. 2. Como parte de la definicin. Formato general: struct <tipo><nombre variable estructura>={ valor miembro1,valor miembro2,........valor miembro n}; Ejemplo: struct info_libro { char titulo[60]; char auto[30]; char editorial[30]; int ao; }libro1={"Maravilla del saber","Lucas Garcia","Mc Graw-Hill",1999};

ACCESO A ESTRUCTURAS Cuando se accede a una estructura o bien se almacena informacin en la estructura o se recupera la informacin de la estructura, se puede acceder a los miembros de una estructura de una de estas 2 formas: 1. Utilizando el operador punto(.) 2. Utilizando el operador puntero -->

Almacenamiento de la informacin Se puede almacenar informacin en una estructura mediante inicializacin, asignacin directa o lectura del teclado. El proceso de inicializacin ya se ha examinado, veamos ahora la asignacin directa y la lectura del teclado.

Acceso mediante operador punto La asignacin de datos a los miembros de una variable estructura se hace mediante el operador punto. La sintaxis es: <nombre variable estructura> . <nombre miembro> = datos; Ejemplo: strcpy(cd1.titulo,"Granada"); cd1.precio=3450.75; cd1.num_cancion=7; otro ejemplo:

struct coleccion_CD cd1; printf("Titulo:"); gets(cd1.titulo); printf("Precio:"); scanf("%f",&cd1.precio); printf("Numero de cancines:"); scanf("%d",&cd1.num_canciones);

Acceso a una estructura de datos mediante el operador puntero El operador puntero,-->, sirve para acceder a los datos de la estructura a partir de un puntero. Para utilizar este operador se debe definir primero una variable puntero para apuntar a la estructura. A continuacin, utilice simplemente el operador puntero para apuntar a un miembro dado. La asignacin de datos a estructuras utilizando el operador puntero tiene el formato: <puntero estructura> -> <nombre miembro>=datos;

Por ejemplo una estructura estudiante: struct estudiante { char nombre[40]; int matricula; float nota; }

Se puede definir ptr_est como un puntero a la estructura struct estudiante *ptr_est; struct estudiante mejor;

A los miembros de la estructura estudiantes se pueden asignar datos como sigue ( siempre y cuando la estructura ya tenga su espacio de almacenamiento, por ejemplo con malloc(); O bien tenga la direccin de una varible estructura ). ptr_est=&mejor; /* ptr_ obtiene la direccin de mejor */ strcpy( ptr_est->nombre,"Francisco Meraz"); ptr_est->matricula=60007; ptr_est->nota=8.5;

Lectura de informacin de una estructura Si ahora desea introducir la informacin en la estructura basta con acceder a los miembros de la estructura con el operador punto o flecha ( puntero ). Se puede introducir la informacin desde el teclado o desde un archivo, o asignar valores de calculos. As, si z es una variable de tipo estructura complejo, se lee parte real, parte imaginaria y se calcula el modulo: struct complejo { float pr; float pi; float modulo; }; struct complejo z; printf("\nParte real:"); scanf("%f",&z.pr); printf("\nParte imaginaria:"); scanf("%f",&z.pi); z.modulo=sqrt(z.pr*z.pr + z.pi*z.pi);

Recuperar informacin Se recupera informacin de una estructura utilizando el operador de asignacin o una sentencia de salida ( printf( ), puts( ),...). Igual que antes, se puede emplear el operador punto y el operador flecha( puntero ). El formato general toma uno de estos formatos:

<nombre variable>=<nombre variable estructura>.<nombre miembro> o bien <nombre variable>=<puntero de estructura> -> <nombre miembro> printf(" ",<nombre variable estructura>.<nombre miembro>); o bien printf(" ",<puntero de estructura> -> <nombre miembro>);

Algunos ejemplos del uso de la estructura complejo:

float x,y; struct complejo z; struct complejo *pz; pz=&z; x=z.pr; y=z.pi; ... printf("\nNumero complejo (%.1f, %.1f), modulo : %.2f",pz->pr,pz->pi,pz->modulo);

ESTRUCTURAS ANIDADAS Una estructura puede contener otras estructuras llamadas estructuras anidadas. Las estructuras anidadas ahorran tiempo en la escritura de programacin que utiliza estructuras similares. Se han de definir los miembros comunes solo una vez en su propia estructura y a continuacin utilizar esa estructura como un miembro de otra estructura. Consideramos las siguientes 2 definiciones de estructuras: struct empleados { char nombre_emp[30]; char direccion[40]; char telefono[15];

double salario; }; struct clientes { char nombre_cliente[30]; char direccion[40]; char telefono[15]; double saldo; }; Estas estructuras contiene muchos datos diferentes, aunque hay datos que estan solapados. As, se podria disponer de una estructura, info_dir, que contuviera los miembros comunes. struct info_dir { char direccion[40]; char telefono[15]; }; struct empleados { char nombre_emp[30]; struct info_dir direccion_emp; double salario; }; struct clientes { char nombre_cliente[30]; struct info_dir direccion_clien; double saldo; }; Ejemplo de estructuras anidadas #include<stdio.h> #include<dos.h> struct registro_operaciones entrada( ); struct fecha { unsigned int mes, dia, anyo; }; struct tiempo { unsigned int horas, minutos;

}; struct registro_operaciones { long nuemro_cuenta; float cantidad; int tipo_operacion; struct fecha f; struct tiempo t; }; int main( ) { struct registro_operacion w; w=entrada( ); printf("\n\n Operacion relacionada \n"); printf("\t%1d\n",w.numero_cuenta); printf("\t %d / %d / %d \n",w.f.dia,w.f.mes,w.f.anyo); printf("\t %d : %d \n",w.t.horas,w.t.minutos); return 0; } struct registro_operaciones entrada( ) { struct time t; struct date d; struct registro_operaciones una; printf("\n Numero de cuenta: \n"); scanf("%1d",&una.numero_cuenta); puts("\n\t Tipo de operacion"); puts("Deposito(0)"); puts("Retiro de fondos(1)"); puts("Puesta al dia(2)"); puts("Estado de cuenta(3)"); scanf("%d",&una.tipo_operacion); /* Fecha y tiempo del sistema */ gettime(&t); una.t.horas=t.ti.hour; una.t.minutos=t.ti.min; getdata(&d); una.f.anyo=d.da.year; una.f.mes=d.da.mon; una.f.dia=d.da.day; return una; }

ARRAYS DE ESTRUCTURAS Se pueden crear array de estructuras tal como se crea un array de otro tipo. La declaracin del array de estructuras info_libro de un modo similar a cualquier array, es decir, struct info_libro libros[100]; asigna un array de 100 elementos denominado libros. Para acceder a los miembros de cada uno de los elementos estructurados se utiliza una notacin de array. Para inicializar el primer elemento de libros, por ejemplo, su codigo debe hacer referencia a los miembros de libros[0] de la forma siguiente: strcpy(libros[0].titulo,"C++ aqui"); strcpy(libros[0].autor,"Pablo"); strcpy(libros[0].editorial,"McGraw-Hill"); libros[0].ao=1999; Tambin puede inicializarse un array de estructuras en el punto de la declaracin encerrando la lista de inicializadores entre llaves,{ }. Por ejemplo, struct info_libro libros[3] = { "C++ aqui","Pablo","McGraw -Hill",1999 "VisualC++","Jesus","Pirata",2001 "J++","Joaquin","McGraw -Hill",1999 }; En el siguiente ejemplo se declara una estructura que representa a un numero racional, un array de nmeros racionales es inicializado con valores al azar. struct racional { int N; int D; }; struct racional rs[4]={1,2, 2,3, -4,7, 0,1};

ARRAYS COMO MIEMBROS

Los miembros de las estructuras pueden ser asimismo arrays. En este caso ser preciso extremar las precauciones cuando se accede a los elementos individuales del array. Considerese la siguiente definicin de estructura. Esta sentencia declara un array de 100 estructuras, cada estructura contiene informacin de datos de empleados de una compaia. struct nomina { char nombre[30]; int dependientes; char departamento[10]; float horas_dias[7]; /* Array de tipo float */ float salario; }empleado[100]; /* Un array de 100 empleados */ Para acceder a un miembro que es un array dentro de una estructura se hace de la siguiente manera: scanf("%d",&empleado[I].horas_dias[J]);

UTILIZACIN DE ESTRUCTURAS COMO PARMETROS C permite pasar estructuras a funciones, bien por valor o por referencia utilizando el operador de &. Si la estructura es grande, el tiempo necesario para copiar un parmetro struct a la pila puede ser prohibitivo. En tales casos, se debe considerar el mtodo de pasar la direccin de la estructura. A continuacin se muestra un programa que pasa la direccin de una estructura a una funcin para entrada de datos. La misma variable estructura la pasa por valor a otra funcin para salida de los campos. #include <stdio.h> /* Define el tipo estructura info_persona */ struct info_persona { char nombre[20]; char calle[30];

char ciudad[25]; char provincia[25]; char codigo_postal[6]; }; /* Prototipos de funciones */ void entrad_pna( struct infro_persona* pp); void ver_info( struct info_persona p); void main(void) { struct info_persona reg_dat; /* Pasa por referencia la variable */ entrad_pna(&reg_dat); /* Pasa por valor */ ver_info(reg_dat); } void entrad_pna( struct infro_persona* pp) { printw("\nEntrada de los datos de una persona\n"); /* Para acceder a los campos se utiliza el selector -> */ printw("Nombre: "); getstr(pp->nombre); printw("Calle: "); getstr(pp->calle); printw("Ciudad: "); getstr(pp->ciudad); printw("Provincia: "); getstr(pp->provincia); printw("Codigo Postal: "); getstr(pp->codigo_postal); } void ver_info( struct infro_persona p) {

printw("\nInformacion de la Persona\n"); printw("%s",p.nombre); printw("%s",p.calle); printw("%s",p.ciudad); printw("%s",p.provincia); printw("%s",p.codigo_postal); } Si se desea pasar la estructura por referencia, necesita situar un operador de referencia & antes de reg_dat en la llamada a la funcin entrada_pna(). El parmetro correspondiente debe de ser tipo puntero struct info_persona* pp. El acceso a miembros dato de la estructura a partir de un puntero requiere el uso del selector ->.

UNIONES Las uniones son similares a las estructuras en cuanto que agrupa a una serie de variables, pero la forma de almacenamiento es diferente y, por consiguiente, efectos diferentes. Una estructura ( struct ) permite almacenar variables relacionadas juntas y almacenadas en posiciones contiguas en memoria. Las uniones, declaradas con la palabra reservada union, almacenan tambin miembros mltiples en un paquete; sin embargo, en lugar de situar sus miembros unos detrs de otros, en una unin, todos los miembros se solapan entre s en la misma posicin. El tamao ocupado por una unin se determina as: es analizado el tamao de cada variable de la unin, el mayor tamao de variable ser el tamao de la unin. La sintaxis de una unin es la siguiente: union nombre { tipo1 miembro1; tipo2 miembro2; ... }; Ejemplo: union PruebaUnion {

float Item1; int Item2; }; La cantidad de memoria reservada para una unin es igual a la anchura de la variable ms grande. En el tipo union, cada uno de los miembros dato comparten memoria con los otros miembros de la unin. La cantidad total de memoria utilizada por la unin comparte es de 8 bytes, ya que el elemento double es el miembro dato mayor de la unin. union comparte { char letra; int elemento; float precio; double z; }; Una razn para utilizar una unin es ahorrar memoria. En muchos programas se deben tener varias variables, pero no necesitan utilizarce todas al mismo tiempo. Considrese la situacin en que se necesitan tener diversas cadenas de caracteres de entrada. Se pueden crean varios arrays de cadenas de caracteres, tales como las siguientes: char linea_ordenes[80]; char mensaje_error[80]; char ayuda[80]; Estas tres variables ocupan 240 bytes de memoria. Sin embargo, si el programa no necesita utilizar las tres variables simultaneamente, por qu no permitirle compartir la memoria utilizando una unin?. Cuando se combinan en el tipo union frases, estas variables ocupan un total de slo 80 bytes. union frases { char linea_ordenes[80]; char mensaje_error[80]; char ayuda[80]; } cadenas, *pc;

Para referirse a los miembros de una unin, se utiliza el operador punto (.), o bien el operador -> si se hace desde un puntero a una unin. As: cadenas.ayuda; cadenas.mensaje_error; pc -> mensaje_error;

Ejemplo: union persona { char nombre[10]; char inicial; };

Se creo una unin y sus elementos son un nombre de 10 bytes (nombre[10]) y la


inicial (1 byte). Como se dijo la unin ocupa el espacio de su elemento ms grande, en este caso nombre. Por lo tanto la unin ocupa 10 bytes. Las variables nombre e inicial comparten el mismo sitio de la memoria. Si accedemos a nombre estaremos accediendo a los primeros 10 bytes de la unin (es decir, a toda la unin), si accedemos a inicial lo que tendremos es el primer byte de la unin.

Nuestro programa quedara de la siguiente manera: #include <stdio.h> union _persona { char nombre[10]; char inicial; } pers; int main() { printf("Escribe tu nombre: "); getstr(pers.nombre); printf("\nTu nombre es: %s\n", pers.nombre); printf("Tu inicial es: %c\n", pers.inicial);

} Ejecutando el programa se tendrn los siguientes resultados: Escribe tu nombre: Gorka Tu nombre es: Gorka Tu inicial es: G Para comprender mejor eso de que comparten el mismo espacio en memoria vamos a ampliar el ejemplo. Si aadimos unas lneas al final que modifiquen slo la inicial e imprima el nuevo nombre: #include <stdio.h> union _persona { char nombre[10]; char inicial; } pers; int main() { printf("Escribe tu nombre: "); gets(pers.nombre); printf("\nTu nombre es: %s\n", pers.nombre); printf("Tu inicial es: %c\n", pers.inicial); /* Cambiamos la inicial */ pers.inicial='Z'; printf("\nAhora tu nombre es: %s\n", pers.nombre); printf("y tu inicial es: %c\n", pers.inicial); }

Ejecutando el programa se tendrn los siguientes resultados: Escribe tu nombre: gorka Tu nombre es: gorka Tu inicial es: g Ahora tu nombre es: Zorka y tu inicial es: Z

ENUMERACIONES

Un enum es un tipo de dato definido por el usuario con constantes de nombre de tipo entero. En la declaracin de un tipo enum se escribe una lista de identificadores que internamente se asocian con las constantes enteras 0,1,2, etc. Por ejemplo: enum { primero, segundo, tercero, cuarto, quinto }; De esta forma hemos definido las constantes primero, segundo,... quinto. Si no especificamos nada la primera constante (primero) toma el valor 0, la segunda (segunda) vale 1, la tercera 2,... Podemos cambiar estos valores predeterminados por los valores que deseemos: enum { primero=1, segundo, tercero, cuarto, quinto }; Ahora primero vale 1, segundo vale 2, tercero vale 3,... Cada constante toma el valor de la anterior ms uno. Si por ejemplo hacemos: enum { primero=1, segundo, quinto=5, sexto, septimo }; Tendremos: primero=1, segundo=2, quinto=5, sexto=6, septimo=7.

Con esta nueva forma podemos volver a escribir el ejemplo de antes: #include <stdio.h> enum { primero=1, segundo, tercero, cuarto, quinto } posicion; int main() { posicion=segundo; printf("posicion = %i\n", posicion); }

Las constantes definidas con enum slo pueden tomar valores enteros (pueden ser negativos). Son equivalentes a las variables de tipo int. Un error habitual suele ser pensar que es posible imprimir el nombre de la constante: #include <stdio.h> enum { primero=1, segundo, tercero, cuarto, quinto } posicion; int main() { printf("posicion = %s\n", segundo); }

Es habitual pensar que con este ejemplo tendremos como resultado: posicion = segundo. Pero no es as, en todo caso tendremos: posicion = (null) Debemos pensar en las enumeraciones como una forma de hacer el programa ms comprensible para los humanos, en nuestro ejemplo el ordenador donde vea segundo pondr un 2 en su lugar.

TIPOS DE DATOS DEFINIDOS POR EL USUARIO Ya conocemos los tipos de datos que nos ofrece C: char, int, float, double con sus variantes unsigned, arrays y punteros. Adems tenemos las estructuras. Pero existe una forma de dar nombre a los tipos ya establecidos y a sus posibles variaciones: usando typedef. Con typedef podemos crear nombres para los tipos de datos ya existentes, ya sea por capricho o para mejorar la legibilidad o la portabilidad del programa. Por ejemplo, hay muchos programas que definen muchas variables del tipo unsigned char. Imaginemos un hipottico programa que dibuja una grfica: unsigned char x0, y0; unsigned char x1, y1; unsigned char x, y; /* Coordenadas del punto origen */ /* Coordenadas del punto final */ /* Coordenadas de un punto genrico */

int F; int i;

/* valor de la funcin en el punto (x,y) */ /* Esta la usamos como contador para los bucles */

La definicin del tipo unsigned char aparte de ser larga no nos da informacin de para qu se usa la variable, slo del tipo de dato que es. Para definir nuestros propios tipos de datos debemos usar typedef de la siguiente forma: typedef tipo_de_variable nombre_nuevo; En nuestro ejemplo podramos hacer: typedef unsigned char COORD; typedef int CONTADOR; typedef int VALOR; y ahora quedara: COORD x0, y0; /* punto origen */ COORD x1, y1; /* punto final */ COORD x, y; /* punto genrico */ VALOR F; /* valor de la funcin en el punto (x,y) */ CONTADOR i; Ahora, nuestros nuevos tipos de datos, aparte de definir el tipo de variable nos dan informacin adicional de las variables. Sabemos que x0, y0, x1, y1, x, y son coordenadas y que i es un contador sin necesidad de indicarlo con un comentario. Realmente no estamos creando nuevos tipos de datos, lo que estamos haciendo es darles un nombre ms cmodo para trabajar y con sentido para nosotros.

Tipos Punteros
Tambin podemos definir tipos de punteros: int *p, *q; Podemos convertirlo en: typedef int *ENTERO; ENTERO p, q; Aqu p, q son punteros aunque no lleven el operador '*', puesto que ya lo lleva ENTERO incorporado.

Tipos Arrays
Tambin podemos declarar tipos array. Esto puede resultar ms cmodo para la gente que viene de BASIC o PASCAL, que estaban acostumbrados al tipo string en vez de char: typedef char STRING[255]; STRING nombre; donde nombre es realmente char nombre[255];.

Tipos Estructuras
Tambin podemos definir tipos de estructuras. Primero se muestra un ejemplo de como se hace sin el uso de typedef: struct _complejo { double real; double imaginario; } struct _complejo numero; Con typedef quedara de la siguiente manera: typedef struct { double real; double imaginario; } COMPLEJO COMPLEJO numero;

También podría gustarte