Es
un tipo de dato estructurado en el que las variables pueden almacenar varios
valores de un tipo simple, al cual se le denomina tipo base. La declaración de
un tipo conjunto se hace :
Type
Conjunto = SET of tipobase ;
Var
c :conjunto ;
El
tipo base ha de ser un ordinal. Los valores ordinales de los elementos han de
estar entre 0..255.
Las
siguientes declaraciones son ilegales :
Conjunto
= SET of integer ;
Conjunto
= SET of 1997..2000 ;
Las
siguientes declaraciones son legales :
Conjunto
= SET of char ;
Conjunto
=SET of ‘A’..’Z’ ;
Aunque
para facilitar la legibilidad se suele escribir :
Type
Letras =’A’.. ‘Z’ ;
Conjunto = SET of Letras ;
Ejemplo :
Conjunto de letras de una frase :
For
i :=1 to Lenght(frase) do
{para coger carácter a carácter no puedo Copy(frase,i,1)
}
frase[i] ;
{porque da una subcadena, y no puede entrar en un conjunto}
Podemos
simular conjuntos mediante arrays de booleanos :
ConjuntoArr
= ARRAY [1..6] of boolean ; { aprox. como Conjunto = SET of 1..6 ;}
Para
introducir un elemento :
ConjuntoArr[5] :=True ; {se mete el elemento 5 en el conjunto}
En
los conjuntos, no puede haber repeticiones en los elementos (solo habrá un
elemento de cada).
Type
Letras=’A’..’Z’ ;
Conjunto=SET of Letras ;
Arr= ARRAY[‘A’..’Z’] of boolean ;
Var
c :conjunto ;
a :arr ;
i :integer ;
car :char ;
Begin
{usando
conjuntos}
c :=[ ] ; { se asigna conjunto vacío, es obligatorio}
Readln (car) ;
c :=c+[car] ; {elemento c UNION conjunto car}{[car] = conjunto
del contenido de car}
{usando
arrays}
For car :=’A’.. ‘Z’
do ;
a[car] :=False ; {inicialización del conjunto}
Readln[car] ;
a[car] :=True ; {introducido elemento en conjunto}
Para
ver si un elemento está en un conjunto :
{usando conjuntos}
For car :=’A’.. ‘Z’ do
If car IN c then
{comprueba que esté en el conjunto}
Writeln(car) ;
{usando arrays}
For
car :=’A’.. ‘Z’
do
If a[car] then {comprueba que
esté en el conjunto}
Writeln(car) ;
Operaciones
de conjuntos :
·
Definición
de tipos :
Type
Conj=SET of tipobase ; {tipobase=simple y ordinal con valores
ordinales entre 0..255}
·
Declaración
de variables :
Var
c :Conj ;
también
es posible la forma :
c : SET of ‘A’..’Z’ ;
pero tiene poca utilidad, y en programación modular, para el paso por
variable, se necesita haber declarado el tipo, ya que :
Procedure
Ejemplo(variable p1 :SET of ‘A’..’Z’) ;
no
es válido, produciéndose un error de concordancia
Hay
que declarar también :
Var
car :char ;{tipobase}
c :Conj ;
Begin
{hay
que INICIALIZAR siempre}
c :=[
] ;{inicializamos a conjunto vacío} o c :=[‘A’..’Z’] ;{inicializa
a conjunto universal } ;
Para
dar valores a variables de tipo conjunto (que no pueden ser leidos desde teclado
o escritos por pantalla), debemos hacerlo elemento a elemento, para lo que
usamos la variable tipobase.
·
ASIGNACIÓN :
c :=[‘A’..’D’] ;
{también
se puede asi à
c :=[‘A’..’D’,’5’,car], pero se utiliza poco}
las
variables han de ser de tipo base.
{leemos variable de tipobase}
Repeat
Readln(car) ;
car :=Ucase(car) ;
{se
comprueba que es del rango al que tiene que pertenecr}
Until
(car>=’A’) AND (car<=’Z’)
c :=c + [car] ;
{car à
Elemento}
{[car]
à
Conjunto con el elemento}
Unión entre conjuntos
Una vez introducidos los datos podemos visualizarlos.
·
VISUALIZACIÓN
DE ELEMENTOS :
Se
puede realizar mediante un bucle for :
For
car : =’A’to ‘Z’ do
If
car IN c then
{el operador IN admite elemento de distinto tipo. Lo
usamos}
Writeln(car) ;
{para saber si car pertenece a c}
Aunque
es más conveniente un while (por si sólo hay 2 elementos en el conjunto) :
car :=’A’ :
caux :=c ;
{para no vaciar el conjunto inicial lo metemos en una variable auxiliar}
While
(car<=’Z’) AND (caux < > [ ] then
Begin
If car IN caux then
Begin
Writeln(car) ;
caux :=caux
- [car] ; {diferencia de conjuntos}
End ;
If caux < > [ ] then
car := Succ(car) ;
{siguiente elemento}
End ;
{como
car es de tipo char, habrá sucesor. Si fuese de tipo enumerado, podría no
haberlo}
Operadores
con conjuntos :
+ Unión
de conjuntos.
-
Diferencia de conjuntos.
*
Intersección de conjuntos.
IN Pertenencia
de elemento en un conjunto.
>= Un
conjunto incluye a otro conjunto.
<= Un
conjunto es incluido en otro conjunto.
Prioridad
de operadores :
·
NOT
·/,
*, AND
·
-,
+, OR
·
>,<=,
<,>=, =, <>, IN
Simulación
de conjuntos :
·
Mediante
conjunto de enumerados (ya que un conjunto no puede tener cadenas o más de 255
elementos)
·
Mediante
arrays :
Ejemplo :
Crear las primitivas (operaciones básicas) para trabajar con conjuntos.
Program
Conjuntos ;
Type
Conj=ARRAY
[1..5] of boolean ; {genérico}
Var
c :Conj ; {este es el conjunto}
e : 1.. 5 ;
{-------------------------------------------------------------------}
Procedure
Inicializar(variable c :conj) ;
Var
e :
1 .. 5 ;
Begin
For e :=1
to 5 do
c[e] :=False ;
End ;
{-------------------------------------------------------------------}
Procedure Introducir (variable c :conj ; e : integer) ;
Begin
c[e] :=True ;
End ;
{-----------------PROGRAMA PRINCIPAL------------------}
Begin
Inicializar
(c) ;
Readln(e) ;
Introducir (c,e) ;
End.
{-------------------------------------------------------------------}
Function En (c :conj ; e :integer) :boolean ;
{Implementación del IN}
Begin
If c[e] then
En :=True
Else
En :=False ;
End ;
{lo
mismo se puede hacer asi :
Begin
}
{
c :=c[e] ;
}
{
End ;
}
{-------------------------------------------------------------------}
Procedure Union (c1,c2 :conj ;variable c3 :conj) ;
Var
auxi :integer ;
Begin
For auxi :=1 to 5 do
c3[auxi] :=c1[auxi] OR c2[auxi] ;
End ;
{-------------------------------------------------------------------}
Procedure Interseccion (c1,c2 :conj ;variable c3 :conj) ;
Var
auxi :integer ;
Begin
For auxi :=1 to 5 do
c3[auxi] :=c1[auxi] AND c2[auxi] ;
End ;
Los
archivos son una colección de datos, tratados como estructura de datos,
almacenada en un dispositivo de almacenamiento externo, en la que los datos se
encuentran almacenados de forma lógica.
Pascal
tiene tres tipos diferentes de archivos :
1.
Archivos
de tipo Texto. (Acceso secuencial)
2.
Archivos
de tipo ‘file of tipobase’. (Acceso Directo)
3.
Archivos
sin tipo (se declaran como tipo ‘file’). (acceso directo)
Son
archivos de texto.La información sólo se puede leer y escribir de forma
secuencial (acceso secuencial). Se consideran formados por una serie de líneas
las cuales a su vez están formadas por una serie de caracteres. La longitud de
éstas líneas no puede exceder 127 caracteres.
En
Pascal, los archivos de texto vienen definidos como de tipo ‘text’. Para
Pasacal, la pantalla y el teclado son archivos de tipo texto asociados con la
E/S estándar de DOS.
·
Teclado :
Input.
·
Pantalla :
Output.
Pascal
estándar obligga a especificar el tipo de archivo, pero Turbo Pascal no.
En
un archivo, los registros hay que escribirlos campo a campo.Un registro se leerá
de teclado campo a campo. (las variables de tipo registro se leen y escriben
campo a campo).
En
un archivo de texto se pueden escribir tanto caractéres como numeros. Los datos
no sufren una conversión automática a carácter al escribir en pantalla, pero
se diferencian en memoria.
Los
ficheros de tipo texto son lentos trabajando con números, pero son útiles para
pasar datos de un programa a otro.
Son
editables. Los archivos de tipo texto, no sirven para escribir cartas, porque
todos son registros.
Para Pascal, todo el registro lo considera como una cadena, si está declarado así.
(no
sale nada, todo) 12ab ---------
---------- ----------
(es
cadena)
Espacio
para 8 caracteres
Se
soluciona usando cadenas de longitud fija : si cad[8], sólo lee los 8
caracteres, y después, el nuveno, puede ser otra cadena o una variable numérica.
Gotoxy
NO FUNCIONA en archivos de tipo texto.
Éste
tipo de archivos es el único ejemplo secuencial de Pascal (los archivos de
texto), por lo que NO se pueden abrir a la vez para lectura y escritura.
Para
laectura un archivo tipo texto hay que recorrerlo todo desde el principio.
Para
escritura, se puede posicionar el puntero de escritura al principio (se borraría
todolo anterior al introducir nuevos datos) o al final (se añaden datos).
Var
f : text ; {fichero de texto}
cad : string ;
Begin
Assign (f, <nombre_fichero_en_disco>) ;
{Asignamos nombre en el disco}
{Abre para escritura al principio del fichero y coloca marca de fda}
Rewrite(f) ; {hace
proceso de creación de archivo secuencial}
Readln(cad) ;
While cad < > ‘*’ do
Begin
Writeln(f, cad) ; {f,nombre variable tipo fichero}
Readln(cad)
End ;
Close(f) ;
{Cerramos el fichero}
End.
Cuando
queremos leer información, ha de haber sido primero cerrado, si ya está
asignado.
Reset (f) ;{Abrir lectura }
While
NOT EOF(f) do
Begin
Readln(f,cad) ;
Writeln(cad) ;
End ;
Close(f) ;
La
apertura de lectura pone el puntero al principio del archivo en modo lectura.
Con la lectura del último registro, se detecta la marca de fin de archivo
(EOF).
·
Mezcla
de 2 ficheros ordenados :
Comenzamos
leyendo 2 registros (uno de cada fichero). Los comparamos, escribimos el más
pequeño y se lee del que se ha escrito. Repetimos esto hasta que se detecta EOF
de uno de los archivos. Si en el otro aún quedan registros, se escriben todos
los que faltan (hasta detectar EOF de este fichero) y por último cerramos todos
los archivos.
·
Longitud
de un fichero de texto :
Var
f :text ;
n1,n2 :integer ;
Begin
Assign(f,’num.dat) ;
Rewrite(f) ;
Readln(n1) ;
While n1<>0 do
Begin
Readln(n2) ;
Writeln(f,n1,n2) ;
Readln(n2)
End ;
Close(f) ;
Reset(f) ;
While NOT EOF(f) do
Begin
Readln(n1,n2) ; àerror
à84àn1,
porque sobra n2, al no haber espacio separador lo almacena como una sóla
variable.
Writeln(n1,n2) ;
Solución :dar formato.
End ;
Writeln(f,n1 :5,n2 :4) o bien Writeln(f,n1,’ ‘,n2)
{escribiendo
separador}
Close(f)
End.
Var
f :text ;
n1,n2 :real ;
Idem.
El
contenido del fichero está en notación exponencial.
Funciones :
En
archivos secuenciales se puede escribir con : Write y Writeln.
Write (id, lista expresiones) ;
Writeln (id, lista expresiones) ;
Y se puede escribir con : Read y Readln.
Read (id, lista variables) ;
Readln (id, lista variables) ;
{En archivos de acceso directo NO se pueden usar WriteLn ni tampoco ReadLn}
La impresora (asi como el teclado y la pantalla), también se con sidera como un
archivo de texto :
Cada vez que se ejecuta un Write o un Read, el puntero avanza al siguiente
registro (tanto en secuencial como en acceso directo).
While NOT EOF(f) do
{secuencial : el puntero de registro avanza automáticamente}
Begin
ReadLn(f,v) ;
WriteLn(v) ;
End ;
Var
Impresora :text ;
Begin
Assign(Impresora,’LPT1’) ;
Rewrite(Impresora) ;
WriteLn(Impresora,’archivo’,’hola’,’adios’,’5’) ;
Close(Impresora) ;
End.
Esto
es similar a lo que hay en la unidad PRINTER, por lo que se indica el Uses
Pinter, sólo hay que hacer :
WriteLn(LST,
’archivo’,’hola’,’adios’,’5’) ;
Apertura
de archivo :
·
1ª
vez à
Rewrite (f) ; {abierto para escritura}
·
Si
ya existe à
Reset (f) ; {abre para lectura}
Append(f) ; {abre para escritura, al final (añadir)}