Cursos gratuitos de programacion de ordenadores, en español

AnteriorPosterior

Tema 7: Constantes y tipos.

  Curso: Curso de Pascal, por Nacho Cabanes

Tema 7: Constantes y tipos.

Definición de constantes

Cuando desarrollamos un programa, nos podemos encontrar con que hay variables que realmente "no varían" a lo largo de la ejecución de un programa, sino que su valor es constante.

Hay una manera especial de definirlas, que es con el especificador "const", que tiene el formato

const Nombre = Valor;

Veamos un par de ejemplos antes de seguir

const MiNombre = 'Nacho Cabanes'; 
const PI = 3.1415926535; 
const LongitudMaxima = 128; 


Estas constantes se manejan igual que variables como las que habíamos visto hasta hora, sólo que no se puede cambiar su valor. Así, es valido hacer

Writeln(MiNombre); 
if Longitud > LongitudMaxima then ... 
OtraVariable := MiNombre; 
LongCircunf := 2 * PI * r; 

pero no podríamos hacer

PI := 3.14; 
MiNombre := 'Nacho'; 
LongitudMaxima := LongitudMaxima + 10;

Las constantes son mucho más prácticas de lo que puede parecer a primera vista (especialmente para quien venga de lenguajes como Basic, en el que no existen -en el Basic "de siempre", puede que sí existan en los últimas versiones del lenguaje-). Me explico con un ejemplillo:

Supongamos que estamos haciendo nuestra agenda en Pascal (ya falta menos para que sea verdad), y estamos tan orgullosos de ella que queremos que en cada pantalla de cada parte del programa aparezca nuestro nombre, el del programa y la versión actual. Si lo escribimos "de nuevas" cada vez, además de perder tiempo tecleando más, corremos el riesgo de que un día queramos cambiar el nombre (ya no se llamará "Agenda" sino "SuperAgenda" ;-) ) pero lo hagamos en unas partes sí y en otras no, etc., y el resultado tan maravilloso quede estropeado por esos "detalles".
O si queremos cambiar la anchura de cada dato que guardamos de nuestros amigos, porque el espacio para el nombre nos había quedado demasiado escaso, tendríamos que recorrer todo el programa de arriba a abajo, con los mismos problemas, pero esta vez más graves aún, porque puede que intentemos grabar una ficha con una tamaño y leerla con otro distinto...


¿Solución? Pues definir todo ese tipo de datos como constantes al principio del programa, de modo que con un vistazo a esta zona podemos hacer cambios globales:

const 
  Nombre = 'Nacho'; 
  Prog = 'SuperAgenda en Pascal'; 
  Versión = 1.95;
  LongNombre = 40; 
  LongTelef = 9; 
  LongDirec = 60; 
  ...

Las declaraciones de las constantes se hacen antes del cuerpo del programa principal, y generalmente antes de las declaraciones de variables:

program MiniAgenda; 
const 
  NumFichas = 50; 
var 
  Datos: array[ 1..NumFichas ] of string; 
begin 
  ...

 

Ejercicio propuesto: Modificar el programa de adivinar números (apartado 6.8) para que el número a adivinar deba estar entre 1 y 1000 (estos límites se definirán mediante constantes) y el máximo de intentos permitidos sea 10 (también mediante una constante).

Tema 7.2: Constantes "con tipo".

El identificador "const" tiene también en Turbo Pascal otro uso menos habitual: definir lo que se suele llamar constantes con tipo, que son variables normales y corrientes, pero a las que damos un valor inicial antes de que comience a ejecutarse el programa. Se usa

const variable: tipo = valor;

Así, volviendo al ejemplo de la clave de acceso, podíamos tener una variables "intentos" que dijese el número de intentos. Hasta ahora habríamos hecho

var 
  intentos: integer;
begin 
  intentos := 3; 
  ...

Ahora ya sabemos que sería mejor hacer, si sabemos que el valor no va a cambiar:

const 
  intentos = 3;
begin 
  ...

Pero si se nos da el caso de que vemos por el nombre que es alguien de confianza, que puede haber olvidado su clave de acceso, quizá nos interese permitirle 5 o más intentos. ¿Qué hacemos? Ya no podemos usar "const" porque el valor puede variar, pero por otra parte, siempre comenzamos concediendo 3 intentos, hasta comprobar si es alguien de fiar. Conclusión: podemos hacer

const intentos: integer = 3;
begin 
  ...

Insisto: a efectos de manejo, una "constante con tipo" es exactamente igual que una variable, con las ventajas de que está más fácil de localizar si queremos cambiar su valor inicial y de que el compilador optimiza un poco el código, haciendo el programa unos bytes más pequeño.

 


Tema 7.3: Definición de tipos.

El "tipo" de una variable es lo que determina qué clase de valores podremos guardar en ella. Para nosotros, es lo que indicamos junto a su nombre cuando la declaramos. Por ejemplo,

const intentos: integer = 3;
begin 
  ...

indica que vamos a usar una variable que se va a llamar PrimerNumero y que almacenará valores de tipo entero. Si queremos definir una de las fichas de lo que será nuestra agenda, también haríamos:

var ficha: record 
  nombre: string; 
  direccion: string; 
  edad: integer; 
  observaciones: string 
  end;

Tampoco hay ningún problema con esto, ¿verdad? Y si podemos utilizar variables creando los tipos "en el momento", como en el caso anterior, ¿para qué necesitamos definir tipos? Vamos a verlo con un ejemplo. Supongamos que vamos a tener ahora dos variables: una "ficha1" que contendrá el dato de la ficha actual y otra "ficha2" en la que almacenaremos datos temporales. Veamos qué pasa...

 {--------------------------}
 {  Ejemplo en Pascal:      }
 {                          }
 {    Intenta asignar dos   }
 {    tipos definidos como  }
 {    distintos. Da error   }
 {    y no compila.         }
 {    TIPOS1.PAS            }
 {                          }
 {  Este fuente procede de  }
 {  CUPAS, curso de Pascal  }
 {  por Nacho Cabanes       }
 {                          }
 {  Comprobado con:         }
 {    - Free Pascal 2.2.0w  } 
 {    - Turbo Pascal 7.0    }
 {    - Turbo Pascal 5.0    }
 {    - Surpas 1.00         }
 {    - Tmt Pascal Lt 1.20  }
 {--------------------------}
 
 program PruebaTipos;
 
 var
   ficha1: record
     nombre: string[20];
     direccion: string[50];
     edad: integer;
     observaciones: string[70]
   end;
   ficha2: record
     nombre: string[20];
     direccion: string[50];
     edad: integer;
     observaciones: string[70]
   end;
 
 begin
   ficha1.nombre := 'Pepe';
   ficha1.direccion := 'Su casa';
 
   ficha1.edad := 65;
   ficha1.observaciones := 'El mayor de mis amigos... ;-)  ';
   ficha2 := ficha1;
   writeln( ficha2.nombre );
 end. 
 

¿Qué haría este programa? Es fácil de seguir: define dos variables que van a guardar la misma clase de datos. Da valores a cada uno de los datos que almacenará una de ellas. Después hacemos que la segunda valga lo mismo que la primera, e imprimimos el nombre de la segunda. Aparecerá escrito "Pepe" en la pantalla, ¿verdad?

¡Pues no! Aunque a nuestros ojos "ficha1" y "ficha2" sean iguales, para el compilador no es así, por lo que protesta y el programa ni siquiera llega a ejecutarse. Es decir: las hemos definido para que almacene la misma clase de valores, pero no son del mismo tipo.


Esto es fácil de solucionar:

var ficha1, ficha2: record 
    nombre: string; 
    direccion: string; 
    edad: integer; 
    observaciones: string
  end;
 
begin 
... 
 

Si las definimos a la vez, SI QUE SON DEL MISMO TIPO. Pero surge un problema del que os iréis dando cuenta a partir del próximo día, que empezaremos a crear funciones y procedimientos. ¿Qué ocurre si queremos usar en alguna parte del programa otras variables que también sean de ese tipo? ¿Las definimos también a la vez? En muchas ocasiones no será posible.

Así que tiene que haber una forma de indicar que todo eso que sigue a la palabra "record" es un tipo al que nosotros queremos acceder con la misma comodidad que si fuese "integer" o "boolean", queremos definir un tipo, no simplemente declararlo, como estábamos haciendo.

Pues es sencillo:

type NombreDeTipo = DeclaracionDeTipo;

o en nuestro caso


 {--------------------------}
 {  Ejemplo en Pascal:      }
 {                          }
 {    Asignación correcta   }
 {    de tipos              }
 {    TIPOS2.PAS            }
 {                          }
 {  Este fuente procede de  }
 {  CUPAS, curso de Pascal  }
 {  por Nacho Cabanes       }
 {                          }
 {  Comprobado con:         }
 {    - Free Pascal 2.2.0w  }
 {    - Turbo Pascal 7.0    }
 {    - Turbo Pascal 5.0    }
 {    - Surpas 1.00         }
 {    - Tmt Pascal Lt 1.20  }
 {--------------------------}
 
 program PruebaTipos2;
 
 type TipoFicha = record
     nombre: string[20];
     direccion: string[50];
     edad: integer;
     observaciones: string[70]
   end;
 
 var ficha1, ficha2: TipoFicha;
 
 begin
   ficha1.nombre := 'Pepe';
   ficha1.direccion := 'Su casa';
   ficha1.edad := 65;
   ficha1.observaciones := 'El mayor de mis amigos... ;-)  ';
   ficha2 := ficha1;
   writeln( ficha2.nombre );
 end. 
 

Ahora sí que podremos asignar valores entre variables que hayamos definido en distintas partes del programa, podremos usar esos tipos para crear ficheros (eso lo veremos en el tema 11), etc, etc, etc...

Ejercicio propuesto: Crear un tipo de datos llamado "punto", que sea un registro formado por dos componentes, X e Y, números reales. Pedir al usuario el valor de X e Y para dos puntos distintos y calcular la distancia entre esos dos puntos.

Tema 7.4: Ejemplo completo - agenda

Vamos a juntar todo lo que hemos visto en una "agenda" que permita introducir datos de nuestros amigos, mostrarlos, buscar entre ellos...

Usará comprobación de condiciones sencilla (con "if", para ver si hay datos), múltiple (con "case", para el menú"), "arrays" de "records", bloques repetitivos ("repeat..until" para el bucle principal, "for" para recorrer el array"), declaración de tipos y de constantes...

Haremos ligeras mejoras en apartados posteriores, para incorporarle algunas de las posibilidades que vayamos viendo.

{--------------------------}
{  Ejemplo en Pascal:      }
{                          }
{    Ejemplo de "Agenda":  }
{    Permite añadir datos, }
{    mostrar, buscar.      }
{    AGENDA1.PAS           }
{                          }
{  Este fuente procede de  }
{  CUPAS, curso de Pascal  }
{  por Nacho Cabanes       }
{                          }
{  Comprobado con:         }
{    - Free Pascal 2.4.0   }
{--------------------------}
 
program Agenda;
 
type
    tipoPersona = record
        nombre: string;
        email: string;
        anyoNacimiento: integer;
    end;
 
const
    capacidad = 1000;
 
var
    gente: array[1..capacidad] of tipoPersona;  { Los datos }
    cantidad: integer;       { Cantidad de datos existentes }
    opcion: integer;                      { Opción escogida }  
    i: integer;                           { Para bucles for }
    textoBuscar: string;                   { Para búsquedas }
    encontrado: boolean;                             { Idem }
 
{Cuerpo del programa principal}
begin
    cantidad := 0;
    repeat
        WriteLn('Agenda');
        WriteLn;
        WriteLn('1- Añadir una nueva persona');
        WriteLn('2- Ver nombres de todos');
        WriteLn('3- Buscar una persona');
        WriteLn('0- Salir');
        Write('Escoja una opción: ');
        ReadLn(opcion);
        WriteLn;
 
        case opcion of
            1: { Añadir datos de una persona }
                if (cantidad < capacidad) then
                begin
                    inc(cantidad);
                    WriteLn('Introduciendo la persona ', cantidad);
 
                    Write('Introduzca el nombre: ');
                    ReadLn(gente[cantidad].nombre);
 
                    Write('Introduzca el correo electrónico: ');
                    ReadLn(gente[cantidad].email);
 
                    Write('Introduzca el año de nacimiento: ');
                    ReadLn(gente[cantidad].anyoNacimiento);
 
                     WriteLn();
                 end
                 else
                        WriteLn('Base de datos llena');
 
            2: { Ver nombres de todos }
                begin
                if cantidad = 0 then
                    WriteLn('No hay datos')
                else
                    for i := 1 to cantidad do
                        WriteLn(i, ' ', gente[i].nombre);
                WriteLn;
                end;
 
            3: { Buscar una persona }
                begin
                Write('¿Qué texto busca? ');
                ReadLn( textoBuscar );
                encontrado := false;
                for i := 1 to cantidad do
                    if pos (textoBuscar, gente[i].nombre) > 0 then
                    begin
                        encontrado := true;
                        WriteLn( i,' - Nombre: ', gente[i].nombre,
                          ', Email: ', gente[i].email,
                          ', Nacido en: ', gente[i].anyoNacimiento);
                    end;
                if not encontrado then
                    WriteLn('No se ha encontrado.');
                WriteLn;
                end;
 
            0: { Salir de la aplicación }
                begin
                WriteLn;
                WriteLn('Saliendo...');
                WriteLn;
                end;
 
             else
                begin
                WriteLn;
                WriteLn('Opción incorrecta!');
                WriteLn;
                end;
        end;  { Fin de "case" }
 
    until opcion = 0;
end.
 

Actualizado el: 28-12-2011 00:14

AnteriorPosterior