Los Arrays, son un ejemplo de estructuras (de tipo homogéneo), sin embargo, éste tipo de estructuras posee una gran limitante, puesto que, sólo admite datos del mismo tipo (entero, flotante, carácter); las estructuras que vamos a estudiar, están compuestas por un grupo de variables, no necesariamente del mismo tipo, en las cuales, podemos almacenar diferente información (en cuanto a tipo), pero referente a un mismo tópico.
Por ejemplo, en nuestro carnet de identidad, del colegio, de la universidad, aparecen muchos datos acerca de nosotros.
Nombres, apellidos, edad, dirección, fecha de nacimiento, grado, sección, ciclo...
Estos datos, son de diferente tipo, pero, en C, podemos almacenarlos utilizando un tipo de dato registro al que llamamos Estructura.
Por tanto, una estructura es una colección de una o más tipos de elementos denominados miembros, cada uno de los cuales puede ser de un tipo de dato diferente.
Es ello que radica la importancia de las estructuras, porque nos ahora tiempo además que las estructuras son una herramienta importante para la creación de programas potentes y bases de datos.
Declaración de una Estructura
Como toda variable, en C, debemos declarar una estructura para poder hacer uso de ella, y la forma de hacerlo es la siguiente:
struct <nombre de la estructura>
{
<tipo de dato del miembro1> <nombre del miembro 1>;
<tipo de dato del miembro 2> <nombre de miembro 2>:
...
<tipo de dato del miembro n> <nombre del miembro n>;
}
Por ejemplo, para los datos anteriores, la forma de declararla sería la siguiente:
struct datos
{
char nombre[30];
char apellido[20];
int edad;
char dirección[100];
char fecha_nac[8];
};
Definición de variables del tipo estructura
Al igual que las funciones, las estructuras son declaradas y definidas; en la declaración es que, le estamos indicando al compilador que las variables de tipo datos estarán compuestas por los elementos, tales como nombre, apellido etc; pero además, debemos definir variables que, serán de ese tipo. Así como en alguna parte de C, están declarados los tipos de datos char, int, float; así también nosotros debemos definir las estructuras. Y cuando en el main, definimos las variables que serán del tipo int, del tipo float o del tipo char, de igual manera, debemos definir que variables serán del tipo de la estructura que hemos creado. Para ello existen dos procedimientos:
- listar las variables inmediantamente después de cerrar la llave de la estructura
- Listar las variables que serpán del tipo estructura creadas, inmeditamente después del identificador de la estructura; en la zona de declaraciones del programa.
Ejemplo:
1. struct datos
{
char nombre[30];
char apellido[20];
int edad;
char dirección[100];
char fecha_nac[8];
} alumno1, alumno2, alumno3;
2. struct datos alumno1, alumno2, alumno3;
Si por algún caso, los datos de las tres variables, fuesen los mismos, podemos asignar los valores de ésta forma:
Alumno3=alumno2;
O también:
Alumno1=alumno3=alumno2;
Ya que, al contener los mismos miembros, es como si se tratacen de datos tipo int, float o char, por consiguiente podemos hacer las asignaciones anteriores.
Una estructura la podemos inicializar así:
struct datos
{
char nombre[30];
char apellido[20];
int edad;
char dirección[100];
char fecha_nac[8];
}alumno1 = {“Manuel”,
“Ortez”,
20,
“San Salvador, El Salvador”,
“27/04/86”,
};
o también así:
struct datos alumno2={“Carolina”,
“Pelayo”,
20,
“San Salvador, El Salvador”,
“14/05/86”,
};
El tamaño de una estructura es determinado de forma muy simple, consiste en sumar, el tamaño de todos los miembros, para nuestro caso particular, el tamaño (en bytes) de la estructura datos sería:
Ciertamente que, este proceso, lo podemos simplificar utilizando la sentencia:
Sizeof(datos);
Cuyo resultado será: 160.
Acceso a una estructura.
Para acceder a una estructura, o bién a la información guardada en ella, podemos hacer uso de dos nuevos amigos:
- El operador punto (.)
- El operador puntero –flecha- (->)
Por ejemplo:
Alumno1.nombre=”Manuel”;
Strcpy(alumno1.apellido, “Ortez”);
Para utilizar el operador flecha, debemos hacer uso de punteros (y creíste que ya nos habíamos olvidado de los punteros verdad?).
Por ejemplo, si tenemos un puntero a una estructura:
.struct datos *ptr;
ptr=&alumno1;
ptr->edad=20;
Ejemplo 1.
Diseñe un programa que guarde los datos de dos cd.
#include <stdio.h>
#include <conio.h>
/*declracion de la estructura*/
struct datos_cd
{
char titulo[20];
float precio;
char fecha[8];
};
main()
{
/*definicion de las variables estructuras*/
struct datos_cd cd1, cd2;
struct datos_cd *ptr;
int tam;
ptr=&cd2; /*asignacion de la direccion de cd2 al puntero*/
clrscr();
/*leemos los datos, usando el operador punto*/
printf("Introduzca el t¡tulo del primer cd:\n");
scanf("%s", &cd1.titulo);
printf("Introduzca el precio del cd1:\n");
scanf("%f", &cd1.precio);
printf("Ahora, la fecha de edicion (dd/mm/aa/):\n");
scanf("%s", &cd1.fecha);
printf("Introduzca el t¡tulo del segundo cd:\n");
scanf("%s", &cd2.titulo);
printf("Introduzca el precio del cd2:\n");
scanf("%f", &cd2.precio);
printf("Ahora, la fecha de edicion (dd/mm/aa/):\n");
scanf("%s", &cd2.fecha);
clrscr();
printf("\t\t\tAhora vamos a imprimir los valores guardados:\n\n");
printf("********************Datos del CD1*************************\n");
printf("Titulo %s \n", cd1.titulo);
printf("Precio %.2f\n", cd1.precio);
printf("Fecha %s\n", cd1.fecha);
printf("**********************************************************\n\n");
printf("********************Datos del CD2*************************\n");
printf("Titulo %s\n", ptr->titulo);
printf("Precio %.2f\n", ptr->precio);
printf("Fecha %s\n", ptr->fecha);
printf("**********************************************************\n\n");
printf("El tama¤o de la estructura es %d bytes\n\n", sizeof(datos_cd));
getch();
return 0;
}
Estructuras Anidadas
Al igual que los ciclos, las decisiones, las expresiones, etc, las estructuras también pueden estar dentro de otras, a esto es que se le llama estructuras anidadas.
Supongamos que tenemos dos estructuras siguientes:
stuct empleado
{
char nom[30];
char puesto[10];
int edad;
float sueldo;
char municipio[20];
char ciudad[10];
char dirección[50];
};
struct cliente
{
char nom[30];
char fecha_deuda[8];
float saldo;
char municipio[20];
char ciudad[10];
char dirección[50];
};
Observamos que, en ambas estructuras, hay fatos que se repiten, los cuales los podríamos ubicar en otra structura, así:
struct direc
{
char municipio[20];
char ciudad[10];
char dirección[50];
};
por tanto, las estructuras de empleado y cliente, sería de la siguiente forma:
stuct empleado
{
char nom[30];
char puesto[10];
int edad;
float sueldo;
struct direc direc_empleado;
};
struct cliente
{
char nom[30];
char fecha_deuda[8];
float saldo;
struct direc direc_cliente;
};
En C, podemos definir una estructura dentro de otra estructura, claro siempre y cuando la declaración de ésta, haya sido previo.
Ejemplo 2.
Se desea diseñar una estructura que contenga la información de operaciones financieras. Esta estructura debe contar con un número de cuenta, una cantidad de dinero, el tipo de operación (deposito=0, retiro de fondos=1, puesta al dia=2 o estado de cuenta=3) y la fecha y hora en que la operaciópn se ha realizado.
#include <stdio.h>
#include <conio.h>
#include <dos.h>
/*declaracion de las estructuras*/
struct fecha
{
unsigned int mes, dia, anyo;
};
struct tiempo
{
unsigned int horas, minutos;
};
struct registro_operacion
{
long numero_cuenta;
float cantidad;
int tipo_operacion;
struct fecha f;
struct tiempo t;
};
struct registro_operacion entrada();
main()
{
struct registro_operacion w;
w=entrada();
printf("\n\n operacion realizada\n");
printf("\t%ld\n", w.numero_cuenta);
/*ATENCION: note, la forma en la que llamamos a los miembros
de una estructura anidada*/
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);
getch();
return 0;
}
struct registro_operacion entrada()
{
struct time t;
struct date d;
struct registro_operacion una;
printf("\nNumero de cuenta:\n");
scanf("%ld", &una.numero_cuenta);
puts("\nTipo de Operacion:\n");
puts("Deposito (0)");
puts("Retirada 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;
getdate(&d);
una.f.anyo=d.da_year;
una.f.mes=d.da_mon;
una.f.dia=d.da_day;
return una;
}
Explicación
A fin de realizar el acceso correcto a los campos día, mes y año, así como el tiempo (la hora y los minutos) en que se efectuó la operación, se define una estructura fecha y una estructura tiempo. La estructura registro_operación tiene como miembro una variable (un campo) de tipo fecha, otra variable de tipo tiempo y otras variables para representar los otros campos. La estructura de tipo operación se hace con una variable entera. A continuación se declara tipos, se escribe una función que lee una operación financiera y devuelve la operación leída. La fecha y hora es capturada del sistema.