Elementos de Programación 1ºA E.T.S.I. Informática Gestión

                   Práctica 8: Enumerados y Registros en C++.
Tipos Enumerados.
         Aunque los tipos de datos predefinidos son teóricamente adecuados para cualquier propósito, existe un gran
número de situaciones en las cuales es conveniente que el programador pueda definir sus propios tipos de manera que
especifique literalmente los valores que una variable de ese tipo puede tomar. Estos son los llamados tipos enumerados.
         Si , por ejemplo, quisiéramos definir una variable para que represente una situación de un problema en el que hay
cinco posibles colores, (rojo, amarillo, verde, azul y naranja) podríamos hacer lo siguiente:

        const int rojo             = 0 ;
        const int azul             = 1 ;
        const int verde            = 2 ;

        int color1, color2;

Sin embargo, en C++ podemos definir un nuevo tipo ordinal que conste de esos cinco valores exactamente:

        typedef enum
        { rojo, azul, verde
        } TColor;

        Tcolor color1, color2;

La declaración de un tipo de esta índole consiste en asociar a un identificador una enumeración de los posibles valores que
una variable de ese tipo puede tomar, por lo que una misma constante no puede aparecer en dos definiciones de tipo.
El orden de los valores de estos nuevos tipos declarados por el programador será aquel en que aparecen dentro de la lista
de enumeración de los elementos del tipo. El tipo enumerado es también un tipo escalar y ordinal, por lo que permite
calcular su ordinal y valor.
                              Expresión               Valor Expresión Valor
                              int(rojo)                  0      TColor(0) Rojo
                              int(azul)                  1      TColor(1) Azul
                              int(verde)                 2      TColor(2) Verde
Sin embargo, al no estar definidos sobre ellos las operaciones de suma y resta, ¿cómo obtener su sucesor o predecesor? La
solución consiste en la definición de una función que calcule su ordinal, incremente este, y posteriormente lo retorne a
enumerado. Veamos un ejemplo:

TColor SUC (TColor c)                                        TColor PRED (TColor c)
{ int ord;                                                   { int ord;
  TColor res;                                                  TColor res;

    ord = int(c) + 1;                                            ord = int(c) - 1;
    res = TColor(ord);                                           res = TColor(ord);
    return res;                                                  return res;
}                                                            }

Esta solución, tiene el problema de que es responsabilidad del usuario el no utilizarlas sobre el primer o último elemento,
pero tiene la ventaja de que permite también, que el implementador realice un modelo circular de sucesión como el
siguiente:

const int MAX_COLOR = 3;

TColor SUC (TColor c)                               TColor PRED (TColor c)
{ int ord;                                          { int ord;
  TColor res;                                         TColor res;

    ord = (int(c) + 1)% MAX_COLOR;                      ord = (MAX_COLOR + int(c) - 1) % MAX_COLOR ;
    res = TColor(ord);                                  res = TColor(ord);
    return res;                                         return res;
}                                                   }

Otro problema del uso de enumerados reside en que no pueden ser leídos y escritos directamente por pantalla/teclado, sin
embargo, no es difícil realizar funciones de conversión entre enumerados y cadenas o viceversa. (Ver apuntes).

                                                                                    José Luis Pastrana Brincones @ 2002
                                                            1
Elementos de Programación 1ºA E.T.S.I. Informática Gestión
Registros
Un registro es una estructura cuyos componentes pueden ser de diferente tipo. Para declarar un tipo registro se debe
incluir el nombre y el tipo de cada componente del mismo. En C++ se usa la palabra reservada struct para indicar que el
tipo que se está definiendo es un registro o estructura. Los campos de un registro pueden ser de cualquier tipo, incluyendo
arrays y registros y son llamados campos o variables miembro que pueden ser accedidas individualmente mediante
notación '.' Formalmente, podemos definir un registro de la siguiente manera:

        <TipoRegistro>::= struct <nombreTipo>
                          '{'
                          { <tipo> <nomVar> {, <tipo> <nomVar>}; }
                          '}';
Algunos Ejemplos:
        const char FINCAD = char(0);
        const int MAXCAD = 20;

        typedef char TCadena[MAXCAD+1]; // MAXCAD caracteres + FINCAD
        struct Tfecha
        { int dia, mes, anho;
        };

        struct TPersona
        { TCadena nombre, apellido1, apellido2;
           int edad;
           TCadena nif;
           Tfecha fecha_nacimiento;
        }
Las declaraciones de variables se realizan normalmente, es decir:
        TPersona per;
        Tfecha f1;

Los nombres de los campos de un registro son locales a él, por lo que no hay conflicto con otros nombres usados en el
módulo. Una referencia a un campo de un registro consiste en el nombre de la variable registro y el nombre del campo,
separados por un punto, por ejemplo:     per.edad = 30;
Un registro completo puede aparecer en cualquier parte de una sentencia de asignación y como parámetros de
procedimientos, por ejemplo:             per.fecha_nacimiento = f1;

Práctica
La empresa Los Planes Reformados S.A., ha decidido informatizar la gestión de sus trabajadores. Dicha empresa tiene un
máximo de 10 trabajadores en plantilla, debiéndose almacenar la siguiente información de cada trabajador: nombre,
apellidos (ambos son cadenas de un máximo de 80 caracteres), y turno (matinal, tarde, noche) que debe implementarse
obligatoriamente con un tipo enumerado. La aplicación deberá mostrar en pantalla un menú con las siguientes opciones:

A. Insertar Trabajador. Se pedirá el número de trabajador, que debe ser un número entre el 1 y el 10 y se comprobará
   que no hay ningún trabajador almacenado con ese número. Si el número de trabajador no fuera válido (no esté entre 1
   y 10) o ya estuviera algún trabajador almacenado con ese número, se informará del pertinente error y se volverá al
   programa principal. En cambio, si el número es válido, se pedirán el resto de los datos (nombre, apellidos y turno) y
   se insertará dicho trabajador en la estructura.
B. Buscar Trabajador. Se pedirá por teclado el número de trabajador. Si el número de trabajador no fuera válido (no
   esté entre 1 y 10) o no hubiera algún trabajador almacenado con ese número, se informará del pertinente error y se
   volverá al programa principal. En cambio, si el número es válido, se mostrará por pantalla todos los datos (nombre,
   apellidos y turno) de dicho trabajador.
C. Listar Trabajadores. Se mostrará por pantalla todos los datos (nombre, apellidos y turno) de los trabajadores que
   están almacenados en la estructura precedidos de su número de trabajador.
D. Borrar Trabajador. Se pedirá por teclado el número de trabajador. Si el número de trabajador no fuera válido (no
   esté entre 1 y 10) o no hubiera algún trabajador almacenado con ese número, se informará del pertinente error y se
   volverá al programa principal. En cambio, si el número es válido, se mostrará por pantalla todos los datos (nombre,
   apellidos y turno) de dicho trabajador y se informará de que va a ser borrado, pasándose a eliminarlo de la estructura
   (sin pedir conformidad).
X. Salir del Programa. Se pedirá al usuario una confirmación de abandono del programa, saliendo del mismo en caso
   de que sea afirmativa y mostrando el nombre, apellidos y curso del autor del programa o volviendo al menú principal
   si no lo es.
                                                                                    José Luis Pastrana Brincones @ 2002
                                                            2

Registro

  • 1.
    Elementos de Programación1ºA E.T.S.I. Informática Gestión Práctica 8: Enumerados y Registros en C++. Tipos Enumerados. Aunque los tipos de datos predefinidos son teóricamente adecuados para cualquier propósito, existe un gran número de situaciones en las cuales es conveniente que el programador pueda definir sus propios tipos de manera que especifique literalmente los valores que una variable de ese tipo puede tomar. Estos son los llamados tipos enumerados. Si , por ejemplo, quisiéramos definir una variable para que represente una situación de un problema en el que hay cinco posibles colores, (rojo, amarillo, verde, azul y naranja) podríamos hacer lo siguiente: const int rojo = 0 ; const int azul = 1 ; const int verde = 2 ; int color1, color2; Sin embargo, en C++ podemos definir un nuevo tipo ordinal que conste de esos cinco valores exactamente: typedef enum { rojo, azul, verde } TColor; Tcolor color1, color2; La declaración de un tipo de esta índole consiste en asociar a un identificador una enumeración de los posibles valores que una variable de ese tipo puede tomar, por lo que una misma constante no puede aparecer en dos definiciones de tipo. El orden de los valores de estos nuevos tipos declarados por el programador será aquel en que aparecen dentro de la lista de enumeración de los elementos del tipo. El tipo enumerado es también un tipo escalar y ordinal, por lo que permite calcular su ordinal y valor. Expresión Valor Expresión Valor int(rojo) 0 TColor(0) Rojo int(azul) 1 TColor(1) Azul int(verde) 2 TColor(2) Verde Sin embargo, al no estar definidos sobre ellos las operaciones de suma y resta, ¿cómo obtener su sucesor o predecesor? La solución consiste en la definición de una función que calcule su ordinal, incremente este, y posteriormente lo retorne a enumerado. Veamos un ejemplo: TColor SUC (TColor c) TColor PRED (TColor c) { int ord; { int ord; TColor res; TColor res; ord = int(c) + 1; ord = int(c) - 1; res = TColor(ord); res = TColor(ord); return res; return res; } } Esta solución, tiene el problema de que es responsabilidad del usuario el no utilizarlas sobre el primer o último elemento, pero tiene la ventaja de que permite también, que el implementador realice un modelo circular de sucesión como el siguiente: const int MAX_COLOR = 3; TColor SUC (TColor c) TColor PRED (TColor c) { int ord; { int ord; TColor res; TColor res; ord = (int(c) + 1)% MAX_COLOR; ord = (MAX_COLOR + int(c) - 1) % MAX_COLOR ; res = TColor(ord); res = TColor(ord); return res; return res; } } Otro problema del uso de enumerados reside en que no pueden ser leídos y escritos directamente por pantalla/teclado, sin embargo, no es difícil realizar funciones de conversión entre enumerados y cadenas o viceversa. (Ver apuntes). José Luis Pastrana Brincones @ 2002 1
  • 2.
    Elementos de Programación1ºA E.T.S.I. Informática Gestión Registros Un registro es una estructura cuyos componentes pueden ser de diferente tipo. Para declarar un tipo registro se debe incluir el nombre y el tipo de cada componente del mismo. En C++ se usa la palabra reservada struct para indicar que el tipo que se está definiendo es un registro o estructura. Los campos de un registro pueden ser de cualquier tipo, incluyendo arrays y registros y son llamados campos o variables miembro que pueden ser accedidas individualmente mediante notación '.' Formalmente, podemos definir un registro de la siguiente manera: <TipoRegistro>::= struct <nombreTipo> '{' { <tipo> <nomVar> {, <tipo> <nomVar>}; } '}'; Algunos Ejemplos: const char FINCAD = char(0); const int MAXCAD = 20; typedef char TCadena[MAXCAD+1]; // MAXCAD caracteres + FINCAD struct Tfecha { int dia, mes, anho; }; struct TPersona { TCadena nombre, apellido1, apellido2; int edad; TCadena nif; Tfecha fecha_nacimiento; } Las declaraciones de variables se realizan normalmente, es decir: TPersona per; Tfecha f1; Los nombres de los campos de un registro son locales a él, por lo que no hay conflicto con otros nombres usados en el módulo. Una referencia a un campo de un registro consiste en el nombre de la variable registro y el nombre del campo, separados por un punto, por ejemplo: per.edad = 30; Un registro completo puede aparecer en cualquier parte de una sentencia de asignación y como parámetros de procedimientos, por ejemplo: per.fecha_nacimiento = f1; Práctica La empresa Los Planes Reformados S.A., ha decidido informatizar la gestión de sus trabajadores. Dicha empresa tiene un máximo de 10 trabajadores en plantilla, debiéndose almacenar la siguiente información de cada trabajador: nombre, apellidos (ambos son cadenas de un máximo de 80 caracteres), y turno (matinal, tarde, noche) que debe implementarse obligatoriamente con un tipo enumerado. La aplicación deberá mostrar en pantalla un menú con las siguientes opciones: A. Insertar Trabajador. Se pedirá el número de trabajador, que debe ser un número entre el 1 y el 10 y se comprobará que no hay ningún trabajador almacenado con ese número. Si el número de trabajador no fuera válido (no esté entre 1 y 10) o ya estuviera algún trabajador almacenado con ese número, se informará del pertinente error y se volverá al programa principal. En cambio, si el número es válido, se pedirán el resto de los datos (nombre, apellidos y turno) y se insertará dicho trabajador en la estructura. B. Buscar Trabajador. Se pedirá por teclado el número de trabajador. Si el número de trabajador no fuera válido (no esté entre 1 y 10) o no hubiera algún trabajador almacenado con ese número, se informará del pertinente error y se volverá al programa principal. En cambio, si el número es válido, se mostrará por pantalla todos los datos (nombre, apellidos y turno) de dicho trabajador. C. Listar Trabajadores. Se mostrará por pantalla todos los datos (nombre, apellidos y turno) de los trabajadores que están almacenados en la estructura precedidos de su número de trabajador. D. Borrar Trabajador. Se pedirá por teclado el número de trabajador. Si el número de trabajador no fuera válido (no esté entre 1 y 10) o no hubiera algún trabajador almacenado con ese número, se informará del pertinente error y se volverá al programa principal. En cambio, si el número es válido, se mostrará por pantalla todos los datos (nombre, apellidos y turno) de dicho trabajador y se informará de que va a ser borrado, pasándose a eliminarlo de la estructura (sin pedir conformidad). X. Salir del Programa. Se pedirá al usuario una confirmación de abandono del programa, saliendo del mismo en caso de que sea afirmativa y mostrando el nombre, apellidos y curso del autor del programa o volviendo al menú principal si no lo es. José Luis Pastrana Brincones @ 2002 2