Documentos de Académico
Documentos de Profesional
Documentos de Cultura
6.1 REGISTROS
Los arrays nos permiten agrupar datos con la condicin de que sean todos de un mismo tipo. Existe un tipo de datos compuesto denominado registro que se puede utilizar para agrupar informacin relacionada entre s pero formada por datos de tipos distintos. Un tipo registro est definido por un conjunto de componentes, denominados campos, que establecen su estructura. Cada dato de tipo registro podr tener ciertos valores asignados a sus campos. Para trabajar con registros, es necesario en primer lugar definir la estructura de campos del tipo registro. Para ello, definiremos un nuevo tipo con el que posteriormente podremos declarar variables de dicho tipo. En la fase de diseo, la definicin de tipos se situar en una seccin especfica de la parte declarativa, que titularemos TIPOS e ir situada inmediatamente despus de la seccin CONSTANTES. En concreto, la definicin de un tipo registro utilizar el siguiente diagrama sintctico: identificador de tipo registro = identificador de campo , : tipo
73
6. ESTRUCTURAS
DE
DE
DATOS
En lenguaje C, el tipo registro se representa con el tipo estructura, cuya definicin se sita inmediatamente despus de la definicin de constantes y obedece al siguiente diagrama sintctico: typedef struct { tipo identificador de campo , ; }
identificador de tipo registro Por ejemplo, para representar la siguiente informacin de un alumno:
alumno id 5 nombre Antonio Gonzlez grupo B nota 6.125
En C:
typedef struct { int id; char nombre[35]; char grupo; double nota; } tipoAlumno;
Para utilizar un tipo registro, ser necesario declarar variables de dicho tipo: En algoritmia:
VARIABLES alumno: tipoAlumno
En C:
tipoAlumno alumno;
Ahora bien, un registro contiene varios campos de informacin, por lo que para acceder a ellos de forma independiente ser necesario especificar el campo que nos interesa. En concreto, deber indicarse el identificador de la variable registro que lo contiene seguido de un punto (operador denominado descriptor de campo) y del identificador de campo (por ejemplo, alumno.id, alumno.nombre, alumno.grupo o alumno.nota). Un campo as especificado puede tratarse como si fuera una variable del mismo tipo que el campo y, por tanto, se le podrn aplicar las operaciones permitidas sobre variables de ese mismo tipo (por ejemplo, podrn realizarse operaciones aritmticas sobre alumno.nota). En C, el descriptor de campo es un operador con mayor prioridad que ningn otro (incluidos todos los operadores unarios estudiados hasta el momento). Por lo tanto, cuando se pase un parmetro de tipo registro por referencia a un mdulo, dado que el parmetro formal ser un puntero a un registro, el acceso a uno de sus campos requerir que el operador de indireccin y el identificador del parmetro formal aparezcan encerrados entre parntesis. Por ejemplo, si pAlumno es un puntero a un registro de tipo tipoAlumno, para referirnos al campo grupo deberemos utilizar la sintaxis (*pAlumno).grupo. Para simplificar la sintaxis, existe en C una forma abreviada de indicar esto mismo utilizando el operador ->. As pAlumno->grupo equivale a (*pAlumno).grupo. 74
6. ESTRUCTURAS
DE
DE
DATOS
A diferencia de lo que ocurre con arrays, en C todos los valores de una variable registro pueden asignarse a otra variable registro en una sola instruccin mediante el operador de asignacin:
tipoAlumno alumno1,alumno2; (...) alumno2=alumno1;
Tambin, a diferencia de los arrays, en C un registro puede pasarse por valor as como devolverse asociado al nombre de la funcin. Por ejemplo, los siguientes prototipos de funciones son vlidos:
tipoAlumno leerAlumno(); void mostrarAlumno(tipoAlumno alumno);
Por otro lado, al igual que en el tipo registro tipoAlumno uno de los campos era de tipo cadena, es posible que otros campos sean de cualquier otro tipo de datos compuesto. Por ejemplo, podran representarse en el registro las calificaciones del alumno en 10 asignaturas distintas
alumno id nombre grupo notas 0123456789
utilizando un campo de tipo vector para las calificaciones, del siguiente modo:
typedef struct { int id; char nombre[35]; char grupo; double notas[10]; } tipoAlumno; (...) tipoAlumno alumno;
Para referirnos a la calificacin del alumno en la tercera asignatura utilizaremos la sintaxis alumno.notas[2]. Del mismo modo, a menudo es necesario representar en un programa, no un dato de tipo registro, sino una coleccin de datos de tipo registro. Esto se puede implementar utilizando arrays cuyos elementos son registros. Por ejemplo, lo ms probable es que un programa requiera procesar la informacin de un conjunto de alumnos y no de un solo alumno. As, la informacin de los alumnos matriculados en 3 titulaciones distintas, con 200 alumnos por titulacin, puede representarse con la siguiente matriz de registros:
0 id nombre grupo notas id nombre grupo notas id nombre grupo notas 01234567890123456789 1 ... 199 0
...
... 0123456789
75
6. ESTRUCTURAS
DE
DE
DATOS
Para referirnos al grupo del vigsimo tercer alumno de la segunda titulacin emplearemos la sintaxis alumnos[1][22].grupo, mientras que la sintaxis alumnos[0][33].notas[5] hara referencia a la sexta nota de trigsimo cuarto alumno de la primera titulacin.
EJEMPLO 6.1. Desarrollar un mdulo que, recibiendo del mdulo llamador un vector de registros de 'np' poblaciones, con el nombre de cada poblacin y su censo (nmero de habitantes en unidades de millar) durante 'nd' dcadas, muestre por pantalla, para cada poblacin, su nombre y el nmero de orden de la dcada con mayor nmero de habitantes (si hay varias dcadas con el mayor nmero de habitantes, deber mostrar el nmero de orden de la primera de ellas). El nmero mximo de dcadas es 10.
M. llamador
np, nd, lPob[np].nom, lPob[np].hab[nd]
mayorCenso
MDULO mayorCenso: 1) ANLISIS: a) Datos de entrada: np: Nmero de poblaciones. Mdulo llamador (np > 0) nd: Nmero de dcadas. Mdulo llamador (nd > 0) lPob[np].nom: Nombre de cada poblacin. Mdulo llamador. lPob[np].hab[nd]: Miles de habitantes de cada poblacin en cada dcada. Mdulo llamador. b) Datos de salida: lPob[np].nom: Monitor. decada[np]: Nmero de orden de la dcada con mayor censo de cada poblacin. Monitor. c) Comentarios: Se supone que en algn mdulo ascendiente se ha definido lo siguiente: CONSTANTES MAXDEC=10 TIPOS tipoPob= nom[40]:carcter hab[MAXDEC]:reales Se utilizar una variable ndice para recorrer la lista de poblaciones y otra para recorrer los censos de cada poblacin en busca del mayor censo. Se utilizar una variable para almacenar el nmero de orden de la dcada a la que pertenece el censo mayor de cada poblacin durante cada bsqueda. 2) DISEO: a) Parte declarativa: mayorCenso(lPob[]:tipoPob, np:entero, nd:entero) VARIABLES ip,id,iMax:entero
76
6. ESTRUCTURAS
DE
DE
DATOS
iMax0
id 1, nd-1, 1 lPob[ip].hab[id] > lPob[ip].hab[iMax]
3) CODIFICACIN:
#define MAXDEC 10 /* Nmero mximo de dcadas */
typedef struct { char nom[40]; double hab[MAXDEC]; } tipoPob; (...) /* mayorCenso(listaPob,np,nd) */ /* Muestra, para cada poblacin, su nombre y la dcada */ /* con mayor censo. */ void mayorCenso(tipoPob listaPob[], int np, int nd) { int ip,id,iMax; for (ip=0; ip<=np-1; ip=ip+1) { iMax=0; for (id=1; id<=nd-1; id=id+1) if (listaPob[ip].hab[id] > listaPob[ip].hab[iMax]) iMax=id; printf("La poblacin %s tiene su mayor censo en la dcada %d\n", listaPob[ip].nom,iMax+1); }
(...)
77
6. ESTRUCTURAS
DE
DE
DATOS
El manejo de archivos de datos en los programas permite cubrir esta necesidad. Los archivos de datos que se estudiarn aqu permiten leer o escribir secuencialmente en DAS bloques de datos, cada uno con un nmero de bytes determinado. Estos bloques de datos suelen ser estructuras de datos complejas, como registros, arrays o arrays de registros, aunque, en general, pueden ser datos de cualquier tipo. En C, un archivo de datos se representa mediante un puntero a un valor de tipo FILE. Para declarar un archivo de datos emplearemos la siguiente sintaxis: En algoritmia:
VARIABLES fAlumnos: archivo
En C:
FILE *fAlumnos;
Distinguimos cuatro operaciones bsicas sobre archivos de datos: apertura, cierre, escritura y lectura. En C, estas operaciones se realizan mediante funciones internas que se encuentran en la biblioteca de archivo de cabecera stdio.h.
78