Professional Documents
Culture Documents
#include <stdio.h>
#include <conio.h>
#include<iostream>
getche();
}
37
Tema 3
TIPOS DE DATOS DEFINIDOS POR EL USUARIO
3.1 Estructuras
Una estructura se puede definir como una coleccin de datos de diferentes tipos
(designados por el programador) lgicamente relacionados. En C una estructura slo
puede contener declaraciones de variables. En otros compiladores, este tipo de
construcciones son conocidas como registros.
Ese tipo de dato se llama registro, y est formado por yuxtaposicin de elementos que
contienen informacin relativa a una misma entidad. Por ejemplo, el tipo de dato
asignatura puede tener diferentes elementos, todos ellos relativos a la entidad
asignatura, y no todos ellos del mismo tipo. Y as, ese tipo de dato registro que hemos
llamado asignatura tendra un elemento que llamaramos clave y que podra ser de tipo
long; y otro campo se llamara descripcin y sera de tipo char*; y un tercer elemento
sera el nmero de crditos y sera de tipo float, int etc. A cada elemento de un registro
se le llama campo.
struct nombre_estructura {
tipo1 nombre_campo1
tipo2 nombre_campo2
....
};
struct alumno {
char nombre[20];
int edad;
int curso;
};
Con esto tendramos un nuevo tipo de dato, llamado alumno, en el que podremos
guardar 3 datos: el nombre, la edad y el curso. A la hora de usar este nuevo tipo de
dato que hemos creado, lo haremos como si se tratase de un int o cualquier otro tipo
bsico.
37
Resumiendo:
Ejemplo:
struct alumno // en otros lenguajes el tipo de dato struct se le conoce con
{ // el nombre de registro.
char nombre[50]; // 1 registro= conjunto de campos.
char boleta [12]; // 1 campo= tipo de dato bsico.
};
Las formas ms comunes para declarar las estructuras son las siguientes.
1.- 2.-
struct alumno struct alumno
{ {
char nombre [50]; char nombre [50];
char boleta[12]; char boleta [12];
}; } x, y, z;
struct alumno x, y, z
x,y,z variables
37
Declaracin de Estructuras
struct coord
{
int x;
int y;
};
La palabra clave struct, que identifica el comienzo de una definicin de estructura, debe
ser seguida inmediatamente por el nombre de la estructura o etiqueta (que sigue las
mismas reglas que los nombres de las variables en C). Dentro de las llaves que se
encuentran a continuacin del nombre de la estructura va una lista de las variables
miembro de la estructura. Se debe dar un tipo de variable y un nombre para cada
miembro.
Los enunciados anteriores definen un tipo de estructura, llamada coord, que contiene
dos variables enteras, x y y, sin embargo, ellos no crean, de hecho, ninguna instancia
de la estructura coord, esto es, no declaran (reservan espacio) ninguna estructura.
struct coord
{
int x;
int y;
} primera, segunda;
Por medio del operador (punto) o bien por medio del operador ->
Ejemplo:
Ejemplos:
37
gets (alumno.nombre);
struct datos
{
int a ;
int b;
};
datos.a=365;
cin >> datos.a;
PROGRAMA #5
Usando datos de tipo struct, elabore un programa que sirva para leer y almacenar los
datos siguientes de un alumno. Una vez almacenados los datos desplegarlos en la
pantalla en el siguiente orden: nombre, boleta, peso(kg) y estatura(m).
#include<conio.h>
#include<string.h>
#include<iostream>
struct alumno
{
char nombre [50];
char boleta[12];
float peso;
float estatura;
}x[5];
system("cls");
for(i=0; i<5;i++)
{
cout<<"\n\n\nCAPTURA DE DATOS DEL ALUMNO # "<< i+1;
cout<<"\nNombre: ";
fflush(stdin);
gets(x[i].nombre);
cout<<"\nBoleta: ";
//fflush(stdin);
gets(x[i].boleta);
cout<<"\nPeso: ";
cin>>x[i].peso;
37
cout<<"\nEstatura:";
cin>>x[i].estatura;
system("cls");
}
s=0;
s2=0;
for(i=0;i<5;i++)
{
s=s+x[i].peso;
s2=s2+x[i].estatura;
}
ppeso=s/5.0;
pest=s2/5.0;
system("cls");
cout<<"\nPROMEDIO DE PESO: "<<ppeso;
cout<<"\nPROMEDIO DE ESTATURA: "<<pest;
getch();
system("cls");
for(i=0;i<5;i++)
{
if(ppeso>x[i].peso)
{
cout<<"\n\t"<< x[i].nombre <<" pesa "<< x[i].peso <<" esta por debajo del promedio de
peso que es "<<ppeso;
}
}
getch();
system("cls");
for(i=0;i<5;i++)
{
if(pest>x[i].estatura)
{
cout<<"\n\t"<< x[i].nombre <<" mide "<< x[i].estatura <<" esta por debajo del promedio
de estatura que es "<<pest;
}
}
getch();
}
37
PROGRAMA #6
/*-----------------------------------------------------------------------*/
37
Vectores y punteros a estructuras
Una vez que hemos creado un nuevo tipo de dato estructurado, no resulta extrao que
podamos crear vectores y matrices de este nuevo tipo de dato.
Si, por ejemplo, deseamos hacer un inventario de asignaturas, ser lgico que creemos
un arreglo de tantas variables asignatura como sea necesario.
struct asignatura curricula[100];
Y as, tenemos 100 variables del tipo asignatura, distribuidas en la memoria de forma
secuencial, una despus de la otra. El modo en que accederemos a cada una de las
variables ser, como siempre mediante la operacin de ndices: curricula[i]. Y si
queremos acceder a algn miembro de una variable del tipo estructurado, utilizaremos
de nuevo el operador de miembro: curricula[i].descripcin.
Tambin podemos trabajar operando con apuntadores. As como antes hemos hablado
de curricula[i], tambin podemos llegar a esa variable del array con la expresin
*(curricula + i). De nuevo, todo es igual.
Donde hay un cambio es en el operador de miembro: si trabajamos operando
apuntadores, el operador de miembro ya no es el punto, sino que est formado por los
caracteres ->. Si queremos hacer referencia al elemento o campo descripcion de una
variable del tipo asignatura, la sintaxis ser: *(curricula + i)->descripcion.
Y tambin podemos trabajar con asignacin dinmica de memoria. En ese caso, se
declara un apuntador del tipo struct, y luego se le asigna la memoria reservada mediante
la funcin malloc u otra. Si creamos un arreglo de asignaturas en memoria dinmica, un
programa de gestin de esas asignaturas podra ser el siguiente:
//PROGRAMA # 7
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
#include<string.h>
#include<iostream>
int main(void)
{
asig *curr;
short n, i;
cout<<"Indique el numero de asignaturas de su CV: ";
cin>>n;
/* La variable n almacena el nmero de elementos de tipo
asignatura que debe tener nuestro arreglo. */
curr = (asig*) malloc(n * sizeof(asig));
if(curr == NULL)
37
{
cout<<"Memoria insuficiente.\n";
cout<<"La ejecucion se interrumpira.\n";
cout<<"Pulse una tecla para terminar ... ";
getch();
exit(0);
}
for(i = 0 ; i < n ; i++)
{
cout<<"\n\nAsignatura: "<<i + 1;
cout<<"\nclave : ";
cin>>(curr + i)->clave;
cout<<"\nDescripcion: ";
fflush(stdin);
gets((curr + i)->descr);
cout<<"\ncreditos: ";
cin>>(curr + i)->cred;
}
// Listado ...
for(i = 0 ; i < n ; i++)
{
cout<<"\n\tclave: "<<(curr + i)->clave;
cout<<"\n\tdescripcin: "<<(curr + i)->descr;
cout<<"\n\tcrditos: "<<(curr + i)->cred<<"\n\n";
}
}
Observamos que (curr + i) es la direccin de la posicin i-sima del vector curr. Es, pues,
una direccin. Y (curr + i)->clave es el valor del campo clave de la variable que est en
la posicin i-sima del vector curr. Es, pues, un valor: no es una direccin. Y (curr + i)-
>descr es la direccin de la cadena de caracteres que forma el campo descr de la
variable que est en la posicin i-sima del vector curr. Es, pues, una direccin, porque
direccin es el campo descr: un arreglo de caracteres.
Que accedamos a la variable estructura a travs de un puntero o a travs de su
identificador influye nicamente en el operador de miembro que vayamos a utilizar. Una
vez que tenemos referenciado a travs de la estructura un campo o miembro concreto,
ste ser tratado como direccin o como valor dependiendo de que el miembro se haya
declarado como puntero o como variable de dato.
Anidamiento de estructuras
Podemos definir una estructura que tenga entre sus miembros una variable que sea
tambin de tipo estructura. Por ejemplo:
typedef struct
{
unsigned short dia;
unsigned short mes;
unsigned short anyo;
}fecha;
37
typedef struct
{
unsigned long clave;
char descripcion[50];
double creditos;
fecha convocatorias[3];
}asignatura;
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
#include<string.h>
#include<time.h>;
#include<iostream>
typedef struct
{
unsigned short dia;
unsigned short mes;
unsigned short anyo;
}fecha;
typedef struct
{
unsigned long clave;
char descripcion[50];
double creditos;
fecha c[3];
}asignatura;
int main(void)
{
asignatura asig;
time_t bloquehoy;
struct tm *hoy;
bloquehoy = time(NULL);
hoy = localtime(&bloquehoy);
asig.clave = 10102301;
37
*asig.descripcion = '\0';
strcat(asig.descripcion,"fundamentos de informatica");
asig.creditos = 7.5;
asig.c[0].dia = 15;
asig.c[0].mes = 1;
asig.c[0].anyo = hoy->tm_year - 100;
asig.c[1].dia = 21;
asig.c[1].mes = 6;
asig.c[1].anyo = hoy->tm_year - 100;
asig.c[2].dia = 1;
asig.c[2].mes = 9;
asig.c[2].anyo = hoy->tm_year - 100;
cout<<"Asignatura: \n"<<asig.clave;
cout<<"\t"<< asig.descripcion;
cout<<"\nCreditos:"<< asig.creditos;
cout<<"\nprimera convocatoria ... ";
cout<<asig.c[0].dia<<" - "<<
asig.c[0].mes<<" - "<<asig.c[0].anyo;
cout<<"\nsegunda convocatoria ... ";
cout<<asig.c[1].dia<<" - "<<
asig.c[1].mes<<" - "<<asig.c[1].anyo;
cout<<"\ntercera convocatoria ... ";
cout<<asig.c[2].dia<<" - "<<
asig.c[2].mes<<" - "<<asig.c[2].anyo;
}
Hemos asignado a cada uno de los tres elementos del vector c los valores de da, mes
y ao correspondientes a cada una de las tres convocatorias. Hemos utilizado ndices
de vectores para referenciar cada una de las tres fechas. Podramos haber trabajado
tambin con operatoria de punteros. Por ejemplo, la referencia al da de la segunda
convocatoria es, con operatoria de ndices
asig.c[1].dia = 21;
y mediante operatoria de punteros:
(asig.c + 1)->dia = 21;
Donde asig.c es la direccin del primer elemento del vector c.
Y donde (asig.c + 1) es la direccin del segundo elemento del vector c.
Y donde (asig.c + 1)->dia es el valor del campo da de la variable de tipo fecha cuya
direccin es (asig.c + 1).
Respecto a la funcin localtime, el tipo de dato estructurado tm, y sus campos (entre
ellos el campo tm_year) puede encontrarse abundante informacin sobre todo ello en la
ayuda on line que ofrece cualquier compilador. Son definiciones que vienen recogidas
en la biblioteca time.h y son estndares de ANSI C.
37
3.3 Unin
Una unin es una posicin de memoria compartida por dos o ms variables diferentes,
y en general de distinto tipo. Es una regin de memoria que, a lo largo del tiempo, puede
contener objetos de diversos tipos. Una unin permite almacenar tipos de dato
diferentes en el mismo espacio de memoria. Como las estructuras, las uniones tambin
tienen miembros; pero a diferencia de las estructuras, donde la memoria que ocupan es
igual a la suma del tamao de cada uno de sus campos, la memoria que emplea una
variable de tipo unin es la necesaria para el miembro de mayor tamao dentro de la
unin. La unin almacena nicamente uno de los valores definidos en sus miembros.
Una union es un rea de memoria comn que ser usada por distintos tipos de datos.
La sintaxis es muy similar a la de una estructura struct y tiene la forma siguiente:
Unin nombre_unin
{
campos que compartan
el rea comn
};
ejemplo:
unin datos
{
char x[4]; El rea de memoria que se reserva es el que ocupa mayor
int y; espacio de los campos indicados.
float z;
};
Cmo se declara variables de tipo unin?
1 union datos
{
char [4];
float z;
} a,b,c;
2 union datos
{
char x[2]
int y;
};
Existen bsicamente dos formas de declarar variables de tipo union, las cuales se
muestran a continuacin:
1.- 2.-
union datos union datos
{ {
char x [4]; char x[4];
float z; int y;
} a, b,c; }
union datos a,b,c;
37
PROGRAMA #8
PROGRAMA que maneja una union y despliega los valores que aparecen almacenados
en dicha union.
#include<conio.h>
#include<string.h>
#include<iostream>
int main()
{
system(cls);
cout<<"\n\n PROGRAMA No. 7";
cout<<PROGRAMA QUE MANEJA UNA UNION Y DESPLIEGA LOS VALORES
ALMACENADOS);
cout<<\n EL PROGRAMA ALMACENA LA CADENA DE CARACTERES AEIOU EN ;
cout<<\n UN ELEMENTO DE LA UNION Y DESPLIEGA LO ALMACENADO EN LOS
OTROS ELEMENTOS);
getch();
union x
{
char vocal[6];
short int a[3];
}v;
strcpy(v.vocal, AEIOU);
cout<<\n\n\nv.vocal= <<v.vocal;
cout<<\n\nv.a[0]= <<v.a[0];
cout<<\n\nv.a[1]= <<v.a[1];
cout<<\n\nv.a[2]= <<v.a[2];
cout<<\n\nv.vocal[0]= <<v.vocal[0];
cout<<\n\nv.vocal[1]= <<v.vocal[1];
cout<<\n\nv.vocal[2]= <<v.vocal[2];
cout<<\n\nv.vocal[3]= <<v.vocal[3];
cout<<\n\nv.vocal[4]= <<v.vocal[4];
getch();
}
37