Ingeniero Técnico en Informática de Sistemas


Pascal


Indice:

2. Introducción .................................................................... 2

3. Desarrollo ......................................................................... 3

Tema 3: Estructuras de control .................................... 4

Tema 4: Entrada / Salida de datos ................................ 6

Tema 5: Tipos de datos definidos por el

Usuario, y conjuntos ....................................... 8

Tema 6: Subprogramas ................................................... 11

Tema 7: Arrays .............................................................. 17

Tema 8: Registros ......................................................... 34

Tema 9: Ficheros .......................................................... 42

Tema 10: Punteros ......................................................... 58

Tema 11: Recursividad ................................................... 100

4. Conclusiones .................................................................... 105

5. Bibliografía ..................................................................... 106


INTRODUCCIÓN

Con el trabajo propuesto, se pretende afianzar los conocimientos obtenidos durante todo el curso, y sobre todo adquirir mayor grado de conocimientos que el exigido por la asignatura. El trabajo consiste en la solución mediante programación en Pascal de diversos problemas, propuestos como ejercicios. Dichos ejercicios están clasificados por temas, según las estructuras de control y/o de datos necesarias para su resolución. Asimismo, dentro de cada tema, los ejercición están ordenados según su grado de dificultad, de manera que para resolver los últimos de cada tema será necesario un nivel de conocimientos mayor que el exigido por la asignatura.

Para la realización del trabajo, se ha contado con el compilador de pascal de Borland ®, TURBO PASCAL 7.0, cuyo manejo no es el objetivo del presente trabajo, pero que ha requerido de un estudio específico a nivel de funciones y procedimientos propios de las unidades que incluye, especialmente de la unidad “Crt”, para el control de las entradas y salidas de datos.

El presente trabajo, puede servir de ayuda a aquellos alumnos que quieran consurtarlo, ya que los programas están comentados, y están disponibles en soporte magnético. Además se ha realizado un esfuerzo por hacer que la interacción de los mismos con el usuario sea agradable, con presentaciones por pantalla estudiadas, e introducción de datos en muchos casos controladas para evitar errores en tiempo de ejecución (“run time errors”).

Con el presente trabajo, se ha conseguido adquirir conocimientos más alla de los exigidos por la asignatura, en cuanto a que ya no se limita a la programación de Pascal estándar, y que se ha adquirido práctica en métodos de presentación por pantalla, y de entradas de datos desde el teclado, cuestiones que quedan fuera de los requisitos específicos de la asignatura.


DESARROLLO

A lo largo del curso se han realizado una serie de ejercicios, destinados a la asimilación de técnicas para la programación, así como de adquirir la metodología necesaria. En la realización de estos ejercicios, sin embargo, no se tubieron en cuenta aspectos de la programación tales como la comunicación entre el programa y el usuario, aunque sea éste un aspecto fundamental en la programación de aplicaciones hoy en día.

Además, los ejercicios realizados a continuación, han sido programados en Turbo Pascal, habiendo sido compilados con éxito, estando por tanto disponibles en soporte magnético, para ser revisados.

El trabajo podría dividirse en dos partes: Una primera en la que se resuelven problemas sin excesiva dificultad, y que tienen como objetivo el afianzamiento de las nociones teóricas sobre el tema al que pertenecen, y una segunda parte en la que se resuelven problemas con mayor grado de dificultad, con lo que se consigue un mayor grado de conocimientos sobre el tema específico.

Sin más comenzamos con el desarrollo del trabajo:

Ejercicios tema 3

8. Escribir un programa que lea 7 valores de temperatura, y escriba el número de veces que esta tuvo un valor inferior a 0º. Hacer una traza del código para las siguientes entradas:

  • 10, 0, -3. 12. 18, 5, 1

  • 20, 15, 18, 5, -5, -3, -2

  • 5, 10, 12, 18, 22, 30, 35

program t3e8(Input, Output);

var cont, temp, index: integer;

begin

cont := 0;

{Contador, nº de veces que la temperatura es inferior a 0 grados.}

for index := 1 to 7 do

begin

write('Dime temperatura(',index,'): ');

readln(temp);

{ Leer temperatura desde teclado}

if temp < 0 then cont := cont + 1

{ Si es menor que cero, incrementar el contador}

end;

write('La temperatura fue ',cont);

{ Escribir resultado por pantalla.}

if cont = 1 then write(' vez ') else write(' veces ');

writeln('inferior a cero.')

end.

12. Calcular los M primeros factoriales de un valor N entero.

program t3e12(Input, Output);

Uses Crt;

var index1, index2, N, M: integer;

fac: longint;

begin

ClrScr;

writeln('Calcular los factoriales de los números entre N y M:');

write('Dime N: ');

readln(N);

repeat

{Para no aceptar M > N }

write('Dime M (ha de ser M <= N): ');

readln(M);

{Se lee desde teclado hasta que sea M <= N}

until (M <= N);

for index1 := N downto M do

{Calcular el factorial de los números

comprendidos entre N y M ambos inclusive.}

begin

fac := 1;

{inicializar la variable que acumular  los productos}

for index2 := index1 downto 1 do fac := fac * index2;

{Cálculo del factorial}

writeln('El factorial de ',index1,' es ',fac,'.');

{Escribir resultado.}

end;

readkey

end.


Ejercicios tema 4

4. Escribir un programa que lea un número entero, lo multiplique por dos y a continuación lo escriba en la pantalla:

program t4e4(Input, Output);

Uses Crt;

var num: integer;

begin

ClrScr;

{Borrar la pantalla. Rutina de la unidad Crt}

write('Dime un número entero: ');

{Se pide por pantalla lo que ha de introducir el usuario (write),

y se lee desde teclado (readln).}

readln(num); num := 2 * num;

{Se opera y se guarda el resultado en la misma variable.}

writeln('Tu número multiplicado por 2 es ',num);

{Se Muestra el resultado.}

readkey

{Lee un carácter desde teclado, y no lo muestra por pantalla

(rutina de la unidad Crt)}

end.

6. Escribir un programa que lea dos números enteros A y B, y obtenga los valores A div B, A mod B.

program t4e6(Input, Output);

Uses Crt;

var A, B, aDb, aMb: integer;

begin

ClrScr;

write('Dime un número entero:');

readln(A);

write('Dime otro número entero:');

readln(B);

aDb := A div B;

aMb := A mod B;

writeln('A div B = ',aDb);

writeln('A mod B = ',aMb);

readkey

end.

8. Escribir un programa que convierta un número de segundos en su equivalente en minutos y segundos.

program t4e8(Input, Output);

uses Crt;

var iniseg, segundos, minutos: integer;

begin

ClrScr;

write('Dime un número de segundos:');

readln(iniseg);

minutos := iniseg div 60;

{Cada 60 segundos, son 1 minuto}

segundos := iniseg mod 60;

{Son los segundos que sobran de hacer grupos de 60 segundos}

writeln(iniseg,' segundos son ',minutos,' minutos y ',segundos,' segundos.');

readkey

end.


Ejercicios tema 5

4. Implementar en Pascal un algoritmo que solicitando al usuario una hora de un determinado día en el formato hora (de 1 a 24), minutos (de 1 a 60) y segundos (de 1 a 60), el programa calcule y visualice la hora un segundo más. Usar para ello los tipos mas apropiados.

program t5e4(Input, Output);

uses Crt;

var Horas, horasf: 0..23;

minutos, segundos, minf, segf: 0..59;

{formatos: Horas (de 0 a 23), Minutos y segundos (de 0 a 59)}

begin

ClrScr;

write('Dime horas: ');

readln(horas);

write('Dime minutos: ');

readln(minutos);

write('Dime segundos: ');

readln(segundos);

segf := segundos;

minf := minutos;

horasf := horas;

{Para no perder los valores iniciales, se asignan a las variables segf,

minf y horasf, y se opera con ellas. Así, los valores que introduzca

el usuario no se modifican, y se pueden usar luego}

if segundos < 59 then segf := segundos + 1

{si los segundos son menos de 59 se suma uno m s.}

else begin

{si son 59, al sumarle uno, habrá  que sumar un minuto y poner los

segundos a cero.}

segf := 0;

if minutos < 59 then minf := minutos + 1

{Si los minutos eran menos de 59, se suma el minuto.}

else begin

{Si eran 59 habrá  que sumar una hora, y poner a cero los minutos}

minf := 0;

if horas < 23 then horasf := horas + 1

{Si las horas eran menos de 23, se suma una hora más,

y si eran 23, se ponen a cero.}

else horasf := 0

end

end;

write(horas, 'h ',minutos, 'm ',segundos, 's + 1s = ');

writeln(horasf, 'h ',minf, 'm ',segf, 's.');

readkey

end.

10. Análisis de un texto. El usuario introduce una serie de caracteres por teclado, hasta finalizar con un asterisco. Obtener las letras del alfabeto que han aparecido y las que no han aparecido.

program t5e10(Input, Output);

Uses Crt;

var Estan: Set of Char;

Entrada: Char;

begin

clrscr;

Writeln('Introduce una frase, y termina con un * (asterisco):');

writeln;

Estan := [];

{Se inicializa el conjunto "Estan" como vacío}

repeat

entrada := upcase(readkey);

{Se lee de teclado un carácter, y se pasa a mayúsculas con

la función upcase().}

if entrada in ['A'..'Z',' ',',','.',';'] then write(entrada);

{Si el carácter introducido es una letra, un signo de puntuación,

o un espacio en blanco, entonces se muestra por pantalla. }

if not(entrada in Estan) then Estan := Estan + [entrada]

{Si el carácter no est  en el conjunto "Estan", entonces se añade}

until entrada = '*';

{Se repite el proceso hasta que se introduzca un *}

writeln;

writeln;

writeln('Las siguientes letras han aparecido:');

{Se procede a mostrar los caracteres que pertenecen al conjunto}

for entrada := 'A' to 'Z' do

{Se recorren los valores desde la A hasta la Z}

if entrada in Estan then write(entrada,' ');

{para cada letra, si est  en el conjunto "Estan", significa

que ha sido introducido por teclado, y entonces se muestra

por pantalla}

writeln;

writeln;

writeln('Las siguientes letras NO han aparecido:');

{Ahora se procede a mostrar los que no pertenecen al conjunto. Para ello

se sigue el mismo proceso que antes, pero mostrando la letra sólo si NO

pertenece al conjunto. }

for entrada := 'A' to 'Z' do

if not(entrada in Estan) then write(entrada,' ');

readkey

end.

12. Las notas de un examen pueden ser únicamente enteras, del 0 al 10. Obtener el numero de veces que ha aparecido el 0, el 5 y el 10 en el examen. Obtener las notas que no ha obtenido ningún alumno en la clase. El usuario debe introducir tantas notas como alumnos tenga la clase.

program t5e12(Input, Output);

Uses Crt;

var Notas: Set of 0..10;

index, alumno, veces0, veces5, veces10, N: integer;

begin

clrscr;

Notas := [];

{Se inicializa a conjunto vacío el conjunto donde se guardar n

las calificaciones obtenidas por los alumnos}

write('Cuántos alumnos hay en clase?: ');

readln(N);

veces0 := 0;

veces5 := 0;

veces10 := 0;

{Se inicializan a cero los contadores que guardarán las veces que

se obtuvieron puntuaciones de 0, 5, y 10 }

for index := 1 to N do

{N es el número de alumnos.}

{Repetir N veces el siguiente proceso:}

begin

write('Nota de alumno(',index,'): ');

readln(alumno);

{Leer la nota del alumno. Si la nota no esta en el conjunto,

entonces se añade:}

if not(alumno in notas) then notas := notas + [alumno];

case alumno of

{si la nota es cero, cinco o diez, se incrementa en uno el contador

correspondiente: veces0, veces5 o veces10}

0: veces0 := veces0 + 1;

5: veces5 := veces5 + 1;

10: veces10 := veces10 + 1

end

end;

writeln;

writeln('Número de alumnos con un cero: ',veces0); {Se muestran los }

writeln('Número de alumnos con un cinco:',veces5); {resultados }

writeln('Número de alumnos con un diez: ',veces10);

writeln;

writeln('Ningún alumno ha obtenido ninguna de las siguientes puntuaciones:');

{Se muestran las notas que no est n en el conjunto, que no estar n, porque

ningún alumno habrá  obtenido esa calificación.}

for index := 0 to 10 do

if not(index in notas) then write(index,' ');

readkey

end.


Ejercicios tema 6

2. Escribir un programa que lea dos números enteros A y B, y obtenga los valores A div B, A mod B, utilizando subprogramas.

Program t6e2(Input, Output);

Uses Crt;

Var A, B: Integer;

Function XdivY(X, Y: Integer): Integer;

{Función de dos par metros, que devuelve un entero que es el resultado

de realizar la división entera de los par metros pasados:}

begin

XdivY := X div Y

end;

Function XmodY(X, Y: Integer): Integer;

{Función de dos par metros, que devuelve un entero que es el resultado

de realizar la operación resto (mod) de los par metros pasados:}

begin

XmodY := X mod Y

end;

Begin

ClrScr;

writeln('*** Escribe dos números enteros ***');

write('Numero A = ');

readln(A);

write('Numero B = ');

readln(B);

writeln;

writeln('Calculando la división entera (div), y el resto (mod) ...');

writeln;

write(A,' div ',B,' = ', XdivY(A, B));

write(' porque ',B,' x ',XdivY(A, B),' es ',B * XdivY(A, B));

writeln(' y ',B,' x ',XdivY(A, B)+1,' es ',B*(XdivY(A, B)+1),' que se pasa.');

writeln;

write(A,' mod ',B,' = ', XmodY(A, B),' porque es lo que sobra de dividir ');

writeln(A,' entre ',B);

writeln;

writeln(A,' = ',XdivY(A,B),' x ',B,' + ',XmodY(A,B));

readkey

end.

10. Escribir un programa que lea tres números enteros y emita un mensaje que indique si están o no en orden numérico.

Program t6e10(Input, Output);

Uses Crt;

Var n1, n2, n3: integer;

Function ordenados(i, j: Integer): Boolean;

{Función booleana de dos par metros enteros, que devuelve TRUE si el

primer número es menor o igual que el segundo y FALSE si es mayor:}

begin

ordenados := (i <= j)

end;

Begin

ClrScr;

writeln('*** Introduce tres números enteros ***');

write('Primero: ');

readln(n1);

write('Segundo: ');

readln(n2);

write('Tercero: ');

readln(n3);

writeln;

{Mediante la función, se comprueba si el primer número es menor que

el segundo, y si el segundo es además menor que el tercero.}

if ordenados(n1,n2) and ordenados(n2,n3)

then writeln('Los tres números est n en orden.')

else writeln('Los tres números NO est n en orden');

readkey

end.

14. Implementar un programa que calcule recursivamente el factorial de un número.

Program t6e14(Input, Output);

Uses Crt;

Var n: Longint;

Function Factorial(n: longint): longint;

{Función de un par metro entero, que devuelve un entero largo (longint)

que es el resultado de calcular recursivamente su factorial:}

begin

if n <= 1 then factorial := 1

else factorial := n * factorial(n-1)

end;

Begin

ClrScr;

repeat

write('Introduce un número entero positivo: ');

readln(n);

if n < 0 then writeln('­ Positivo significa mayor o igual que cero !')

until n >= 0;

writeln;

writeln('El factorial de ',n,' es: ',n,'! = ',factorial(n));

readkey

end.

16. Torres de Hanoi. Se tienen tres postes y una serie de discos de diferentes tamaños, cada disco tiene un agujero en el centro permitiendo que los discos de apilen en los postes. Inicialmente los discos están apilados en el poste de la izquierda, ordenados según su tamaño, el menor en la parte de abajo y el menor en la parte de arriba. El objetivo del juego es trasladar los discos desde el poste izquierdo al derecho sin colocar nunca un disco mayor sobre uno mas pequeño. Los discos se deben mover de uno en uno y las discos siempre deben estar en un poste.

La estrategia es considerar uno de los postes como origen y otro como destino, el tercer poste se utiliza como almacenamiento intermedio para permitir el traslado de discos. Por tanto si los discos se encuentran inicialmente en el poste izquierdo el problema se convierte en:

  • Trasladar los n-1 discos superiores al poste central, usando el poste derecho como almacenamiento intermedio.

  • Trasladar el disco restante al poste derecho.

  • Trasladar los n-1 discos del poste central al poste derecho, usando el poste izquierdo como almacenamiento intermedio.

  • El problema se define de forma recursiva.

    Program t6e16(Input, Output);

    Uses Crt;

    Const Max = 9;

    Type disco = String[max];

    arrdisco = array [1..max] of disco;

    Var vdiscos: arrdisco; {Array que contendrá  los discos}

    poste: array [1..3] of arrdisco; {tres postes para mover los discos}

    cima: array [1..3] of 0..max; {altura del último disco de cada poste}

    maxdiscos: 1..max; {número de discos}

    movimientos: word; {número de movimientos de disco efectuados.}

    ralentizar: boolean; {Si es True la visualización ser  m s lenta}

    Function sacardisco(numposte: integer): disco;

    {Extrae el último disco de un poste, y devuelve un String con el disco

    que ha extraído}

    begin

    gotoxy(20*numposte-maxdiscos, 24-cima[numposte] );

    write(' ':maxdiscos, '³',' ':maxdiscos);

    sacardisco := poste[numposte, cima[numposte]];

    {Este es el último disco.}

    poste[numposte, cima[numposte]] := '';

    {En el poste ya no queda disco.}

    dec(cima[numposte]);

    {El último disco en el poste est  una posición m s abajo.}

    end;

    Procedure meterdisco(numposte: integer; nuevodisco: disco);

    {Inserta un disco encima del último que haya en un poste.}

    begin

    inc(cima[numposte]);

    {El último disco, está  ahora una posición más alta.}

    gotoxy(20*numposte-length(nuevodisco), 24-cima[numposte] );

    write(nuevodisco, '³', nuevodisco);

    poste[numposte, cima[numposte]] := nuevodisco

    {Este es el disco insertado}

    end;

    Procedure inicio;

    {Prepara la posición inicial de los postes, y llena el primero con

    los discos que se hayan determinado.}

    var i: integer;

    Procedure hacerdiscos;

    {Crea los discos, que son Strings}

    var i: integer;

    begin

    vdiscos[1] := 'ß';

    {El primer disco: Radio = 1, di metro = 2}

    for i:= 2 to maxdiscos do vdiscos[i] := vdiscos[i-1]+'ß'

    {Cada disco es una unidad m s grande que el anterior.}

    end;

    Procedure verposte(numposte: integer);

    {Visualiza por pantalla los postes y los discos que contienen.}

    var i: integer;

    begin

    gotoxy(20*numposte-(maxdiscos+1), 24);

    for i := 1 to 2*(maxdiscos+1)+1 do write('±');

    {Base de los postes}

    for i := 1 to maxdiscos do

    begin

    if length(poste[numposte, i]) = 0 then

    {Si la altura "i" del poste est  vacía, entonces:}

    begin

    gotoxy(20*numposte, 24-i );

    write('³')

    {Solo est  el poste, no hay disco.}

    end

    else begin

    {Si en la altura "i" hay un disco:}

    gotoxy(20*numposte-length(poste[numposte, i]), 24-i );

    write(poste[numposte, i],'³', poste[numposte, i])

    {Se dibuja el disco: mitad-poste-mitad}

    end

    end

    end;

    begin

    movimientos := 0;

    {Inicializar el nº de movimientos de disco realizados.}

    hacerdiscos;

    cima[1] := maxdiscos;

    {El primer poste empieza lleno.}

    for i:= 1 to maxdiscos do

    begin

    {Los discos se sitúan el m s grande abajo, y en orden ascendente}

    poste[1,i] := vdiscos[maxdiscos-i+1];

    poste[2,i] := '';

    poste[3,i] := ''

    {Los postes 2 y 3, empiezan vacíos.}

    end;

    cima[2] := 0;

    cima[3] := 0;

    {No hay discos inicialmente en los postes 2 y 3.}

    for i := 1 to 3 do verposte(i)

    {Visualizar los 3 postes.}

    end;

    Procedure transferir (n, origen, destino, otro : integer);

    { Transfiere n discos del origen al destino (Recursivamente)}

    Procedure moverdisco (origen, destino : integer);

    { Traslada un disco desde el origen al destino }

    var dibu: disco;

    {Contendrá  el disco que sale de un poste hasta que sea

    introducido en el siguiente.}

    begin

    inc(movimientos);

    {Incrementar el n§ de movimientos}

    gotoxy(50,8);

    write(movimientos:3);

    dibu := sacardisco(origen);

    {se saca el disco del poste origen}

    meterdisco(destino, dibu);

    {y se mete en el poste destino}

    if ralentizar

    {para que de tiempo a ver el proceso: }

    then delay(25 + 100*(max-maxdiscos+1))

    {La velocidad depende del n§ de discos.}

    else delay(25)

    end;

    begin

    if n > 0 then

    begin

    {transferir los discos que est n encima (que ser n "n-1" discos)

    desde el poste origen al otro, utilizando el destino de apoyo.}

    transferir(n-1, origen, otro, destino);

    {Mover el disco deseado del origen al destino}

    moverdisco(origen, destino);

    {y transferir al destino los que se quedaron en el otro.}

    transferir(n-1, otro, destino, origen)

    end

    end;

    Begin

    ClrScr;

    write('Número de discos [Máximo 9]: ');

    repeat

    maxdiscos := ord(readkey) - ord('0')

    until (maxdiscos <= 9) and (maxdiscos > 0);

    writeln(maxdiscos);

    write('¨ Ralentizar ? [S/N]:');

    ralentizar := (upcase(readkey) = 'S');

    inicio;

    gotoxy(24,8);

    write('Movimientos realizados ..:');

    transferir(maxdiscos, 1, 3, 2);

    gotoxy(1,3);

    writeln('That`s All Folks ...');

    readkey

    end


    Ejercicios tema 7

    2. Contar el número de vocales que aparecen en un array. El array termina con un punto.

    Program t7e2(Input, Output);

    Uses Crt;

    Const vocales: Set of Char = (['A','E','I','O','U',' ',' ','¡','¢','£','£']);

    LetBuenas: Set of Char = (['a'..'z','A'..'Z','0'..'9',

    ' ','.',',',':',';','(',')','-','¨',' ',' ','¡','¢','£',

    '£','?','­','!','"','%','/','<','>']);

    Var letra: Char; {para guardar cada carácter introducido desde teclado.}

    Frase: array [1..80] of Char;

    index, numvocales: integer;

    Begin

    ClrScr;

    Writeln('Escribe tu frase, y termina con un punto.');

    index := 0;

    numvocales := 0;

    repeat

    letra := readkey;

    if letra in letbuenas then

    {para no guardar caracteres especiales.}

    begin

    inc(index);

    {incrementar el ¡índice del array.}

    write(letra);

    {Readkey no muestra por pantalla el carácter leído.}

    frase[index] := letra;

    {se asigna el carácter al array.}

    if upcase(letra) in vocales then inc(numvocales)

    {Si el carácter está en el conjunto "vocales" se incrementa el

    contador de vocales "numvocales":}

    end

    until (index >= 80) or (letra = '.'); {La frase termina con un punto.}

    writeln;

    writeln;

    writeln('La frase tiene ',numvocales,' vocales.');

    readkey

    end.

    4. Comparar dos arrays de caracteres y obtener si son idénticos o no.

    Program t7e4(Input, Output);

    Uses Crt;

    Const long_frase = 80; {Máxima longitud permitida para una frase.}

    Type frase = array [1..long_frase] of Char;

    Var Frase1, frase2: frase; {Arrays donde se almacenarán las frases.}

    iguales: boolean;

    index: integer;

    Procedure leerfrase(var arraychar: frase);

    {Lee desde teclado una frase, y la almacena en un array de caracteres.}

    var letra: Char;

    index: integer;

    begin

    index := 0;

    repeat

    letra := readkey;

    inc(index);

    write(letra);

    arraychar[index] := letra;

    until (index >= long_frase) or (letra = #13);

    {La frase termina con INTRO }

    writeln

    end;

    Begin

    ClrScr;

    Writeln('Escribe la primera frase, y termina con INTRO.');

    leerfrase(frase1);

    {Leer la primera frase}

    Writeln('Escribe la segunda frase, y termina con INTRO.');

    leerfrase(frase2);

    {Leer la segunda frase}

    index := 1;

    iguales := (frase1[index] = frase2[index]);

    {Se inicializa "iguales" a true o false según el primer carácter de

    "frase1" sea igual al primer carácter de "frase2" }

    while iguales and (index <= long_frase) and (frase1[index] <> #13) do

    {Mientras que iguales sea true y no se alcance el final de la frase,

    que puede ser porque se detecte un INTRO o porque se llegue a la

    longitud máxima de frase "long_frase".}

    begin

    inc(index);

    iguales := (frase1[index] = frase2[index])

    end;

    if iguales then writeln('Las dos frases son idénticas.')

    else begin

    writeln('Las frases NO son idénticas.');

    writeln('Difieren a partir del carácter nº', index)

    end;

    readkey

    end.

    6. Mostrar una frase en el orden inverso en que se escribió. La frase termina con un punto.

    Program t7e6(Input, Output);

    Uses Crt;

    Const long_frase = 80;

    Type frase = array [1..long_frase] of Char;

    Var Frase1: frase;

    iguales: boolean;

    index, max: integer;

    Procedure leerfrase(var arraychar: frase; var index: integer);

    {Lee una frase desde teclado, y la almacena en un array.

    Además, devuelve en una variable entera la longitud de la frase.}

    var letra: Char;

    begin

    index := 0;

    repeat

    letra := readkey;

    inc(index);

    write(letra);

    arraychar[index] := letra;

    until (index >= long_frase) or (letra = '.');

    writeln

    end;

    Begin

    ClrScr;

    writeln('Visualizar una frase al revés.');

    Writeln('Escribe la frase, y termina con un punto:');

    leerfrase(frase1,max);

    for index := max downto 1 do write(frase1[index]);

    {Para visualizar la frase al revés, se recorre el array que la contiene

    empezando desde el final, que se ha guardado en la variable "max".}

    writeln;

    readkey

    end.

    8. Imprimir la media de los elementos que se encuentran en las posiciones pares y la media de los elementos que se encuentran en las posiciones impares de un vector numérica.

    Program t7e8(Input, Output);

    uses Crt;

    Const maxnum = 5;

    Type listadenumeros = array [1..maxnum] of real;

    Var lista: listadenumeros;

    pares, impares, index: integer;

    imedia, pmedia, isuma, psuma: real;

    Begin

    ClrScr;

    writeln('Dada una lista de números, calcular la media de los que ocupan ');

    writeln('posiciones pares, y la de los que ocupan posiciones impares.');

    writeln;

    writeln('Introduce los ',maxnum,' números de la lista:');

    isuma := 0; {acumulador de impares}

    psuma := 0; {acumulador de pares}

    pares := 0; {contador de pares}

    impares := 0; {contador de impares}

    for index := 1 to maxnum do

    begin

    write('Elemento ',index,': ');

    readln(lista[index]); {leer elemento de la lista.}

    if odd(index) then

    {si ocupa posición impar:}

    begin

    inc(impares);

    {incrementar contador de números impares,}

    isuma := isuma + lista[index]

    {sumar al acumulador de impares}

    end

    else begin

    {si no ocupa posición impar:}

    inc(pares);

    {incrementar contador de números pares,}

    psuma := psuma + lista[index]

    {sumar al acumulador de pares}

    end

    end;

    imedia := isuma / impares; {calcular la media de impares}

    pmedia := psuma / pares; {calcular la media de pares}

    writeln;

    writeln(impares,' elementos impares y ',pares,' elementos pares.');

    writeln;

    writeln('Media de los elementos impares: ',imedia:10:5);

    writeln('Media de los elementos pares..: ',pmedia:10:5);

    readkey

    end.

    10. Realizar un algoritmo que dada una oración de tamaño máximo N y terminada en punto, determine si es un palíndromo o no. Un palíndromo es una oración que, atendiendo sólo a sus letras e ignorando los espacios, acentos, signos de puntuación y tipo de letra (mayúscula o minúscula) expresa lo mismo leída de izquierda a derecha que de derecha a izquierda. “dábale arroz a la zorra el abad”.

    Program t7e10(Input, Output);

    uses Crt;

    Const long_frase = 80;

    Type frase = array [1..long_frase] of Char;

    Var frase1, palin: frase;

    conta, cont2, palindex: integer;

    letra: Char;

    palíndromo: boolean;

    Procedure leerfrase(var arraychar: frase; var index: integer);

    var letra: Char;

    begin

    writeln('La frase acaba con INTRO.');

    index := 0;

    repeat

    letra := readkey;

    inc(index);

    write(letra);

    arraychar[index] := letra;

    until (index >= long_frase) or (letra = #13);

    if letra = #13 then dec(index);

    {Porque la marca de fin de frase no forma parte de ella.}

    writeln

    end;

    Begin

    ClrScr;

    Writeln('Escribe una frase para comprobar si es un palíndromo:');

    leerfrase(frase1,conta);

    palindex := 0;

    for cont2 := 1 to conta do

    begin

    letra := upcase(frase1[cont2]); {pasar a mayúsculas.}

    inc(palindex);

    case letra of {no tener en cuenta los acentos.}

    'A'..'Z',

    '0'..'9': palin[palindex] := letra;

    ' ': palin[palindex] := 'A';

    ' ': palin[palindex] := 'E';

    '¡': palin[palindex] := 'I';

    '¢': palin[palindex] := 'O';

    '£': palin[palindex] := 'U'

    else dec(palindex)

    {Si no es ni un carácter o un número, no incluirlo en "palin",

    para ello se decrementa el ¡índice del array para que no quede

    ningún hueco.}

    end

    end;

    palíndromo := true;

    for cont2 := 1 to (palindex div 2) do

    {Desde el primer elemento hasta el que ocupe la posición intermedia:}

    begin

    {"palíndromo" ser  true mientras que los caracteres sean simétricos

    respecto al punto medio de la frase.}

    palíndromo := palíndromo and (palin[cont2] = palin[palindex-cont2 + 1]);

    gotoxy (palindex-cont2+1,5);

    {Las posiciones "cont2" y "palindex-cont2 + 1" son simétricas

    respecto al punto medio de la frase.}

    write(palin[palindex-cont2 + 1]);

    gotoxy (cont2,5);

    write(palin[cont2]);

    delay(500)

    end;

    if odd(palindex) then write(palin[(palindex div 2) + 1]);

    writeln;

    writeln;

    if palíndromo then writeln('La frase es un palíndromo.')

    else writeln('La frase NO es un palíndromo.');

    writeln;

    readkey

    end.

    12. Dado un vector que contiene un texto de tamaño N como máximo, eliminar los espacios que existen delante del carácter salto de carro. El texto no tiene porqué ocupar todo el vector. El final de texto se marca con el carácter *.

    Program t7e12(Input, Output);

    uses Crt;

    Const long_frase = 80;

    Type frase = array [1..long_frase] of Char;

    Var frase1: frase;

    numblancos, conta, cont2, long: integer;

    letra: Char;

    Procedure leerfrase(var arraychar: frase; var pos_intro, index: integer);

    {Lee una frase y devuelve además la posición de la frase en la que

    se pulsó el primer INTRO, y la longitud total de la frase.}

    var letra: Char;

    pulsado: boolean;

    begin

    writeln('La frase acaba con un *');

    pulsado := false;

    index := 0;

    repeat

    letra := readkey;

    inc(index);

    if letra <> #13 then

    begin

    write(letra);

    arraychar[index] := letra

    end

    else begin

    if not pulsado then

    begin

    pulsado := true;

    write('<enter>');

    arraychar[index] := letra;

    pos_intro := index

    end

    else dec(index)

    end

    until (index >= long_frase) or (letra = '*');

    if letra = '*' then dec(index);

    writeln

    end;

    Begin

    ClrScr;

    Writeln('Escribe una frase con blancos y un INTRO en medio.');

    leerfrase(frase1,conta,long);

    cont2 := conta - 1; {Posición anterior a la del INTRO}

    numblancos := 0;

    while (frase1[cont2] = ' ') and (cont2 >= 1) do

    {mientras que el carácter sea un blanco, y no se llegue al principio:}

    begin

    inc(numblancos);

    {incrementar el contador de blancos}

    dec(cont2)

    {decrementar la posición del array para ser comprobada.}

    end;

    {Para eliminar los blancos, se copian los caracteres que ocupan las

    posiciones siguientes a las del INTRO, encima de las que ocupan los blancos

    hasta el final de la frase.}

    for cont2 := (conta-numblancos) to (long-numblancos)

    do frase1[cont2] := frase1[cont2+numblancos];

    writeln;

    writeln('La frase sin blancos antes del INTRO:');

    writeln;

    for cont2 := 1 to (long-numblancos) do

    if frase1[cont2] <> #13 then write(frase1[cont2])

    else write('<enter>');

    writeln;

    readkey

    end.

    14. Escribir un programa que cuente el número de palabras en un texto, que tengan al menos cuatro vocales diferentes.

    Program t7e14(Input, Output);

    Uses Crt;

    Const long_frase = 80;

    maxppf = 30;

    vocales: Set of Char = (['A','E','I','O','U',' ',' ','¡','¢','£']);

    puntsigns: Set of Char

    = ([' ','.',',',':',';','(',')','?','¨','­','!']);

    Type frase = array [1..long_frase] of Char;

    lista = array [1..maxppf, 0..1] of integer;

    Var texto: frase;

    palabras: lista;

    letra: Char;

    vocs: Set of Char;

    longtexto, numpal, pal4voc, index, index2, numvoc: integer;

    Procedure leerfrase(var arraychar: frase; var index: integer);

    var letra: Char;

    begin

    writeln('El texto acaba con un punto.');

    writeln('Introducir texto: ');

    index := 0;

    repeat

    letra := readkey;

    if not(letra in [#13, #27]) then

    begin

    inc(index);

    write(letra);

    arraychar[index] := letra

    end

    until (index >= long_frase) or (letra = '.');

    writeln

    end;

    Procedure contarpalabras(var texto: frase; longtexto: integer;

    var pal: lista; var npal: integer);

    {Cuenta las palabras que hay en el texto (una palabra es una sucesión

    de caracteres seguidos), y almacena la posición de cada comienzo y

    final de palabra, en la tabla "pal", con 2 columnas (una para la

    posición de comienzo, y otra para la posición de final).}

    var cont: integer;

    enpal, anterior: boolean;

    begin

    npal := 0;

    anterior := false;

    for cont := 1 to longtexto do

    begin

    enpal := not(texto[cont] in puntsigns);

    if enpal then {Estamos sobre una palabra}

    begin

    if not(anterior)

    {Si en el paso anterior era "enpal" = false}

    then begin

    inc(npal); {Se trata de una palabra nueva.}

    {se guarda la posición en donde empieza}

    pal[npal,0] := cont

    end

    end

    else if anterior then pal[npal,1] := cont;

    {si ya no estamos sobre una palabra, se guarda

    la posición donde termina.}

    anterior := enpal

    end

    end;

    Begin

    ClrScr;

    leerfrase(texto, longtexto);

    contarpalabras(texto, longtexto, palabras, numpal);

    {En "palabras", tenemos almacenadas las posiciones que ocupan en el texto

    los comienzos y finales de las palabras que lo componen, y en "numpal" el

    número de palabras que componen el texto.}

    pal4voc := 0;

    {Puesta a cero del contador de palabras con al menos 4 vocales.}

    for index := 1 to numpal do

    {Se repite el siguiente proceso para cada palabra:}

    begin

    vocs := vocales; {El conjunto "vocs" contiene ahora todas las vocales.}

    numvoc := 0;

    for index2 := palabras[index,0] to palabras[index,1] do

    {"index2" toma valores desde la posición de comienzo de la palabra

    "palabras[index,0]", hasta la posición de final de palabra [index,1]}

    begin

    if upcase(texto[index2]) in vocs then

    begin

    inc(numvoc);

    vocs := vocs - [upcase(texto[index2])]

    {Si el carácter es una vocal:}

    {Se incrementa el contador de vocales, y se elimina la vocal

    correspondiente del conjunto "vocs"}

    end

    end;

    if numvoc >= 4 then inc(pal4voc)

    {Si la palabra tenía m s de 4 vocales, se incrementa el contador de

    palabras con 4 vocales.}

    end;

    writeln('longitud de texto: ',longtexto);

    writeln('palabras en texto: ',numpal);

    writeln('Palabras con al menos 4 vocales: ',pal4voc);

    readkey

    end.

    16. Escribir un programa que lea una tabla de números reales (dos dimensiones), calcule la suma por filas y por columnas y muestre por pantalla la tabla y las sumas.

    Si los datos de entrada son:

    2.5

    -6.3

    14.7

    4.0

    10.8

    12.4

    -8.2

    5.5

    -7.2

    3.1

    17.7

    -9.1

    Los datos de salida son:

    2.5

    -6.3

    14.7

    4.0

    14.9

    10.8

    12.4

    -8.2

    5.5

    20.5

    -7.2

    3.1

    17.7

    -9.1

    4.5

    6.1

    9.2

    24.2

    0.4

    0.0

    Program t7e16(Input, Output);

    Uses Crt;

    Const maxN = 6; {Máximo número de líneas y de columnas de la matriz}

    Type matriz = array [1..maxN, 1..maxN] of real;

    vector = array [1..maxN] of real;

    Var col, afila, fN, cN: integer;

    sumF, sumC: vector; {Almacenarán las sumas por filas y columnas.}

    mat1: matriz; {Es la matriz que introduce el usuario.}

    Begin

    ClrScr;

    write('Dime n§ de columnas (m x = 6): ');

    repeat cN := ord(readkey) - ord('0') until (cN<=6) and (cN>=2);

    writeln(cN);

    write('Dime n§ de filas (m x = 6): ');

    repeat fN := ord(readkey) - ord('0') until (fN<=6) and (fN>=2);

    writeln(fN);

    writeln('Introducir elementos de la matriz:');

    for mfila := 1 to fN do { para cada fila, y }

    for col := 1 to cN do { para cada columna:}

    begin

    gotoxy(1,5);

    write('Fila:',mfila:2,' Columna:',mcol:2);

    gotoxy(7*mcol,mfila+7);

    read(mat1[mfila, col]);

    {Se lee el elemento [ mfila, col ] }

    gotoxy(7*mcol,mfila+7);

    if mat1[mfila, col] < 0 then textcolor(9)

    else textcolor(7);

    write(mat1[mfila, col]:6:1)

    end;

    for mfila := 1 to fN do sumf[mfila] := 0;

    for col := 1 to cN do sumc[col] := 0;

    {Se inicializan la fila y la columna de sumas. }

    for mfila := 1 to fN do

    for col := 1 to cN do

    begin {Se acumulan las sumas de los elementos por filas y cols.}

    sumf[mfila] := sumf[mfila] + mat1[mfila, col];

    sumc[col] := sumc[col] + mat1[mfila, col]

    end;

    textcolor(12);

    for mfila := 1 to fN do

    begin {Se escriben las sumas por filas}

    gotoxy(7*(cN+1),mfila+7); {La columna donde se escribe es fija.}

    write(sumf[mfila]:6:1); {A la derecha de la última.}

    end;

    for col := 1 to cN do

    begin {Se escriben las sumas por columnas}

    gotoxy(7*mcol,(fN+8)); {La fila donde se escribe es debajo de la última.}

    write(sumc[col]:6:1);

    end;

    writeln;

    readkey

    end.

    18. Dada una matriz A de orden NxN, girarla 90º en el sentido de las agujas del reloj y guardar el resultado en la matriz B.

    1

    2

    3

    4

    13

    9

    5

    1

    5

    6

    7

    8

    14

    10

    6

    2

    9

    10

    11

    12

    15

    11

    7

    3

    13

    14

    15

    16

    16

    12

    8

    4

    Program t7e18(Input, Output);

    Uses Crt;

    Const N = 4;

    mat1: array [1..N, 1..N] of integer { Matriz de entrada.}

    = ( ( 1, 2, 3, 4),

    ( 5, 6, 7, 8),

    ( 9,10,11,12),

    (13,14,15,16) );

    Type matriz = array [1..N, 1..N] of integer;

    Var col, mfila: integer;

    mat2: matriz; {Matriz de salida}

    Begin

    ClrScr;

    writeln;

    writeln(' Se procede a girar la matriz 90 grados');

    writeln(' en el sentido de las agujas del reloj:');

    for mfila := 1 to N do

    for col := 1 to N do

    begin

    gotoxy(4*mcol,mfila+4);

    write(mat1[mfila,mcol]:2)

    end;

    gotoxy(22,6);

    write('--->');

    for mfila := 1 to N do

    for col := 1 to N do

    begin

    mat2[mfila,mcol] := mat1[N-(mcol-1),mfila];

    {lo que eran filas, ahora pasan a ser columnas, y además

    al revés, o sea, la primera fila ser  la última columna ...}

    gotoxy(4*mcol+25,mfila+4);

    write(mat2[mfila,mcol]:2)

    end;

    writeln;

    readkey

    end.

    20. Dado un array de NxN, sumar los elementos situados por encima de la diagonal principal. Es decir:

    Program t7e20(Input, Output);

    Uses Crt;

    Const N = 4;

    mat1: array [1..N, 1..N] of integer

    = ( ( 1, 2, 3, 4),

    ( 5, 6, 7, 8),

    ( 9,10,11,12),

    (13,14,15,16) );

    Type matriz = array [1..N, 1..N] of integer;

    Var col, mfila: integer;

    suma: integer; {Ir  acumulando la suma de los elementos deseados.}

    Begin

    ClrScr;

    writeln;

    writeln(' Se procede a sumar los elementos de la matriz');

    writeln(' que se encuentren por encima de la diagonal: ');

    for mfila := 1 to N do

    for col := 1 to N do

    {Todos los elementos por encima de la diagonal, cumplen la propiedad

    de ser su ¡índice de columna mayor que su ¡índice de fila}

    begin

    if col > mfila then textcolor(12)

    else textcolor(7);

    {se escribir n en rojo los elementos a sumar.}

    gotoxy(4*mcol+18,mfila+4);

    write(mat1[mfila,mcol]:2)

    end;

    suma := 0;

    for mfila := 1 to N do

    for col := mfila+1 to N do

    suma := suma + mat1[mfila,mcol];

    writeln;

    writeln;

    writeln(' La suma de los elementos');

    write(' por encima de la diagonal es: ');

    textcolor(12);

    writeln(suma);

    textcolor(7);

    readkey

    end.

    23.- Implementar un subprograma que reciba como dato una frase (tira de longitud máx 80 caracteres) ya leída, y la procese de forma que a través de una ventana (array de 20 caracteres), aparezca dicha frase moviéndose de derecha a izquierda. Cuando por la ventana pase el último carácter de la frase, ésta volverá a desfilar de nuevo desde el principio. Así un número de veces. Dicho número debe ser facilitado al subprograma. También se le facilitará la longitud de la frase. Como salida para la visualización del array ventana, se hará simplemente invocando al procedimiento VISUALIZAR (sin argumentos) que se supondrá ya declarado.

    Program t7e23(Input, Output);

    Uses Crt;

    Const Long_frase = 80;

    Long_ventana = 20;

    LetBuenas: Set of Char = (['a'..'z','A'..'Z','0'..'9',

    ' ','.',',',':',';','(',')','-','¨',' ',' ','¡','¢','£',

    '£','?','­','!','"','%','/','<','>']);

    Type frase = array [1..long_frase] of Char;

    Var texto: frase;

    veces, long_texto, rapido: integer;

    Procedure leerfrase(var arraychar: frase; var index: integer);

    {Lee una frase desde el teclado, sin permitir que se introduzcan

    caracteres especiales, como <esc>, <ctrl+> ...Devuelve la longitud.}

    var letra: Char;

    begin

    write('Introduce la frase: ');

    writeln('La frase acaba con INTRO.');

    index := 0;

    {Se inicializa el ¡índice del array a llenar.}

    repeat

    {Se leen caracteres desde teclado hasta leer un INTRO}

    letra := readkey;

    if letra in letbuenas then

    {Si el carácter leído no es de control:}

    begin

    inc(index);

    {se incrementa el índice del array.}

    write(letra);

    arraychar[index] := letra

    {Se guarda en el array.}

    end

    until (index >= long_frase) or (letra = #13);

    repeat

    {Si el texto leído tiene menor longitud que la ventana,}

    inc(index);

    arraychar[index] := ' '

    until index >= long_ventana;

    {se rellena hasta completar.}

    writeln

    end;

    Procedure win(var texto: frase; textlenght, rep: integer);

    {Visualiza "rep" veces una frase, a través de una ventana de texto.}

    Type ventana = array [1..long_ventana] of Char;

    var win1: ventana; {Esta es la porción de texto a visualizar}

    index, ini, dentro: integer;

    Procedure visualizar(var winx: ventana);

    {visualiza un array de caracteres (tipo ventana)}

    Const posY = 12; {Coordenada de fila.}

    posX = 30; {Coordenada de columna.}

    var index: integer;

    begin

    textbackground(4); {La ventana ser  de fondo de color rojo}

    for index := 0 to long_ventana-1 do

    begin

    {Visualizar el array en pantalla.}

    gotoxy(posX+index,posY);

    write(winx[index+1])

    end;

    delay(20*rapido);

    {Pausa entre "frames" para hacer que el mensaje aparezca más o

    menos rápido en la ventana}

    textbackground(0) {Devolver el fondo a color negro.}

    end;

    begin

    repeat

    {Repetir el número de veces que haya introducido el usuario.}

    gotoxy(30,15);

    write('Quedan ',rep-1,' repeticiones.');

    for ini := 1 to long_ventana-1 do

    {La frase comienza a entrar en la ventana por la derecha.}

    begin

    dentro := 0;

    {controla el nº de caracteres del texto que entran en la ventana.}

    for index := 1 to long_ventana-ini do

    begin

    win1[index] := ' ';

    {La ventana comienza a llenarse con blancos por la izquierda.}

    inc(dentro);

    { n§ de blancos que hay a la izquierda del texto}

    end;

    for index := dentro to long_ventana do

    win1[index] := texto[index-dentro+1];

    {El resto de caracteres pertenecen al texto.}

    visualizar(win1) {Se visualiza la ventana.}

    end;

    for ini := 1 to textlenght do

    {Toda la ventana es llenada por caracteres del texto.}

    begin

    for index := 1 to long_ventana

    do win1[index] := texto[ini+index-1];

    visualizar(win1) {Se visualiza la ventana.}

    end;

    dec(rep)

    {Se decrementa el contador de repeticiones.}

    until (rep <= 0)

    end;

    Begin

    ClrScr;

    writeln('Visualizar una frase en una ventana de texto.');

    leerfrase(texto,long_texto);

    writeln;

    write('Introduce el número de repeticiones [1..9]: ');

    repeat

    veces := ord(readkey) - ord('0')

    until veces in [1..9];

    writeln(veces);

    write('Velocidad [Rápido = 1 .... 9 = lento]: ');

    repeat

    rapido := ord(readkey) - ord('0')

    until veces in [1..9];

    ClrScr;

    gotoxy(34,11);

    write('V E N T A N A');

    win(texto,long_texto,veces);

    gotoxy(30,18);

    write('That`s All Folks ...');

    readkey

    end.


    Ejercicios tema 8

    2. Leer los nombres y notas de parcial y final de N alumnos de una clase. Hacer un listado con cada una de las notas, la nota media de los dos exámenes y poner APTO si han aprobado y NO APTO si han suspendido. Utilizar un array de registros.

    Program t8e2(Input, Output);

    Uses Crt;

    Const numalumnos = 5;

    Type tiponotas = record

    nombre: String;

    parcial, final: real

    end;

    notasclase = array [1..Numalumnos] of tiponotas;

    Var I3: notasclase;

    nota1, nota2: real;

    alumno: String;

    index: integer;

    Begin

    ClrScr;

    for index := 1 to numalumnos do

    begin

    write('Nombre de alumno(',index,'): ');

    readln(alumno);

    write('Nota del examen parcial: ');

    readln(nota1);

    write('Nota del examen final: ');

    readln(nota2);

    writeln;

    with i3[index] do

    begin

    nombre := alumno;

    parcial := nota1;

    final := nota2

    end

    end;

    ClrScr;

    writeln('NOMBRE ':30,'Parcial':10,'Final':10,'Media':10,' CALIFICACION');

    for index := 1 to 75 do write('-');

    writeln;

    for index := 1 to numalumnos do

    with i3[index] do

    begin

    {Escribir la lista con los resultados.}

    nota1 := (parcial+final)/2;

    {Se calcula la media.}

    write(nombre:30,parcial:10:2,final:10:2);

    write(nota1:10:2);

    {Si la nota media es superior a 5, el alumno est  aprobado:}

    if nota1 >= 5 then writeln(' *** APTO *** ')

    else writeln(' NO APTO')

    end;

    readkey

    end.4. Un array de registros contiene la descripción de personas a efectos estadísticos. Cada registro tiene los campos: nombre, edad, sexo, altura, color de pelo, color de piel, color de ojos, nacionalidad y región. Escribir un programa que lea y almacene los datos en este array y visualice después su contenido.

    Program t8e4(Input, Output);

    Uses Crt;

    Const totalmuestreo = 5;

    Type datos = record

    nombre: String[25];

    nacion, region: String[11];

    edad: integer;

    altura: real;

    sexo, ColOjos, colPelo, colPiel: Char

    end;

    estadistica = array [1..totalmuestreo] of datos;

    Var Grupo1: Estadistica;

    nom: String[25];

    cont, index: integer;

    Begin

    ClrScr;

    index := 1;

    repeat

    {Repetir hasta que se introduzca un nombre en blanco:}

    with grupo1[index] do

    begin

    write('Nombre (',index,'): ');

    readln(nom);

    {Leer el nombre.}

    if not(nom = '') then

    {Si no se introdujo un nombre vacío, entonces leer el resto de datos.}

    begin

    nombre := nom;

    write('País de origen: ');

    readln(nacion);

    write('región: ');

    readln(region);

    write('Sexo [V/M]: ');

    repeat

    sexo := upcase(readkey)

    until sexo in ['V','M'];

    {restringe la entrada a "V" o "M".}

    writeln(sexo);

    write('Altura [x.xx metros]: ');

    readln(altura);

    write('Color de ojos [V, A, M, N, G]: ');

    repeat

    colojos := upcase(readkey)

    until colojos in ['V','A','M','N','G'];

    writeln(colojos);

    write('Color de piel [N, B, A, R]: ');

    repeat

    colpiel := upcase(readkey)

    until colpiel in ['N','B','A','R'];

    writeln(colpiel);

    write('Color de pelo [N, B, C, R, P]: ');

    repeat

    colpelo := upcase(readkey)

    until colpelo in ['N','B','C','R','P'];

    writeln(colpelo);

    writeln;

    index := index + 1

    {Se incrementa el número de muestras.}

    end

    end

    until (index >= totalmuestreo) or (nom = '');

    ClrScr;

    write('NOMBRE':25,'NACION':12,'REGION':12,' EDAD',' SEXO',' ALT.');

    writeln(' OJOS',' PIEL',' PELO');

    for cont := 1 to 79 do write('Í');

    writeln;

    for cont := 1 to index do

    {Presentar los resultados por pantalla.}

    with grupo1[cont] do

    {Cada elemento del array es un registro.}

    begin

    write(nombre:25,nacion:12,region:12,edad:5,sexo:5,altura:5:2);

    writeln(colojos:4,colpiel:5,colpelo:5)

    end;

    readkey

    end.

    6. Se dispone de un array con la hora de finalización de un determinado experimento en cada uno de los días del año. Escribir las estructuras de datos necesarias. Implementar un subprograma que modifique la hora de un día en concreto.

    Program t8e6(Input, Output);

    Uses Crt;

    Const diasmes: array [1..12] of integer =

    (31,28,31,30,31,30,31,31,30,31,30,31);

    Type experimento = record

    dia, mes: integer;

    hora, minuto, segundo: integer

    end;

    Var exp: array [1..365] of experimento; {Cada día un registro experimento}

    index: integer;

    control, correcto: Char;

    nomascorrec: boolean;

    Procedure llenararray;

    {Para inicializar aleatoriamente los registros de cada día del año.}

    var diadelmes, numdemes: integer;

    begin

    randomize;

    diadelmes := 1; {Los meses tienen longitud distinta.}

    numdemes := 1;

    for index := 1 to 365 do

    with exp[index] do

    begin

    mes := numdemes;

    dia := diadelmes;

    hora := random(24); {Valor de 0 a 23.}

    minuto := random(60); {Valor de 0 a 59.}

    segundo := random(60);

    if diadelmes < diasmes[numdemes] then inc(diadelmes)

    else begin {Si ya se ha completado un mes:}

    diadelmes := 1; {El siguiente mes empieza en día 1}

    numdemes := numdemes + 1 {Incrementar número del mes.}

    end

    end

    end;

    Procedure verarray;

    {Visualiza los registros de experimento de todos los días.}

    begin

    for index := 1 to 365 do

    with exp[index] do

    begin

    write(dia:2,'/',mes:2,' .......... Hora: ');

    writeln(hora:2,':',minuto:2,':',segundo:2);

    if (index mod 24) = 0 then readkey

    end

    end;

    Function numdia(dia, mes: integer): integer;

    {Calcula el número de día del año que corresponde a un día de un mes.}

    var i, sum: integer;

    begin

    sum := 0;

    for i := 1 to mes - 1 do sum := sum + diasmes[i];

    {Todos los meses anteriores están completos.}

    numdia := sum + dia

    {Al número de día del mes, hay que sumarle el número de días de los

    meses anteriores.}

    end;

    Procedure editarfecha;

    var exp_erroneo: experimento;

    begin

    repeat

    writeln('Introducir la fecha del experimento erróneo:');

    with exp_erroneo do

    begin

    repeat

    repeat

    write('Mes: ');

    readln(mes)

    until (mes > 0) and (mes <= 12);

    {El número de mes ha de estar entre 1 y 12.}

    repeat

    write('Día: ');

    readln(dia)

    until (dia > 0) and (dia <= diasmes[mes]);

    {El número de día ha de estar entre 1 y el nº de días que

    tenga el mes.}

    index := numdia(dia, mes);

    write('Hora a cambiar: ',exp[index].hora:2,':');

    writeln(exp[index].minuto:2,':',exp[index].segundo);

    write('¨Es este el experimento a modificar? [S/N]: ');

    repeat

    correcto := upcase(readkey)

    until correcto in ['S','N'];

    writeln(correcto);

    until correcto = 'S';

    writeln('Nueva hora: ');

    write('Hora: ');

    readln(hora);

    write('Minuto: ');

    readln(minuto);

    write('Segundo: ');

    readln(segundo);

    end;

    write('¨Todo correcto? [S/N]: ');

    repeat control := upcase(readkey) until control in ['S','N'];

    writeln(control)

    until control = 'S';

    with exp[index] do

    begin

    hora := exp_erroneo.hora;

    minuto := exp_erroneo.minuto;

    segundo := exp_erroneo.segundo

    end;

    writeln('Corrección guardada.')

    end;

    Begin

    ClrScr;

    llenararray;

    repeat

    verarray;

    editarfecha;

    write('¨Más cambios? [S/N]: ');

    repeat control := upcase(readkey) until control in ['S','N'];

    writeln(control);

    nomascorrec := (control = 'N')

    until nomascorrec;

    writeln;

    writeln('That`s All Folks ...');

    readkey

    end.

    12. Se plantea subir el sueldo de los empleados de una empresa en un 20% si tienen una antigüedad mayor que 40 años y casados. Un 10% a los no casados y con igual antigüedad. Un 5% al resto. Escribir el programa con los tipos de datos mas apropiados.

    Program t8e12(Input, Output);

    uses Crt;

    Const MaxEmpl = 5;

    {Suficiente para contemplar todas las combinaciones de actualización.}

    Type Empleado = record

    nombre: String[25];

    casado: Boolean;

    Antiguedad: integer;

    salario: longint

    end;

    Var nomina: array [1..MaxEmpl] of empleado;

    Procedure hazplantilla;

    {Lee desde teclado los datos referentes a los empleados.}

    var numempleado: integer;

    est_civil: Char;

    begin

    for numempleado := 1 to MaxEmpl do

    with nomina[numempleado] do

    begin

    write('Nombre empleado(',numempleado,'): ');

    readln(nombre);

    write('Antigüedad [en años]: ');

    readln(antiguedad);

    write('Estado civil [S/C]: ');

    repeat

    est_civil:= upcase(readkey)

    until est_civil in ['S','C'];

    {Solo acepta como entradas S, o C}

    writeln(est_civil);

    casado := (est_civil = 'C');

    write('Salario base: ');

    readln(salario);

    writeln;

    end

    end;

    Procedure Subirsueldo;

    {Actualiza los sueldos, y muestra por pantalla el listado de

    los datos de los empleados.}

    var numempleado: integer;

    Procedure actualizar(var trabajador: empleado);

    {Actualiza el salario de un trabajador.}

    var incremento: integer;

    Function porcentaje(antig: integer; estciv: boolean): integer;

    {Devuelve el porcentaje de aumento en función de la

    antigüedad y del estado civil del empleado.}

    begin

    if (antig >= 40)

    then if estciv

    then porcentaje := 20

    else porcentaje := 10

    else porcentaje := 5

    end;

    begin

    with trabajador do

    begin

    incremento := porcentaje(antiguedad, casado);

    {Guarda el porcentaje de aumento para el empleado.}

    salario := salario + ((salario * incremento) div 100)

    {Calcula el nuevo salario y lo guarda en su registro.}

    end

    end;

    begin

    ClrScr;

    writeln('NOMBRE':25,'Ant':5,' E.civ',' Salario',' Actualizado');

    for numempleado := 1 to MaxEmpl do

    {Para cada empleado, hacer:}

    with nomina[numempleado] do

    {Con el registro de datos del empleado:}

    begin

    write(nombre:25,antiguedad:5);

    if casado then write(' C ')

    else write(' S ');

    write(salario:8);

    {Escribir los datos personales y el salario antiguo.}

    actualizar(nomina[numempleado]);

    {Actualizar el salario, y escribir el salario actualizado.}

    writeln(salario:12)

    end

    end;

    Begin

    ClrScr;

    hazplantilla;

    subirsueldo;

    readkey

    end.


    Ejercicios tema 9

    2. Contar el número de vocales (cada una) que aparecen en un fichero de texto.

    Program t9e2(Input, Output);

    uses Crt;

    Type vocales = (a,e,i,o,u);

    Var acumulador: array [a..u] of integer;

    fichero: Text;

    letra: Char;

    index: vocales;

    archivo: String;

    control: boolean;

    contador: integer;

    Begin

    ClrScr;

    for index := a to u do acumulador[index] := 0;

    {Inicializa los elementos del acumulador a cero.}

    contador := 0;

    {Contar  el n§ de veces que se intente abrir un archivo de texto.}

    repeat

    write('Nombre de archivo: ');

    readln(archivo);

    inc(contador);

    if archivo = '' then archivo := 'c:\tp\bin\temas\tema9\t9e2dat.txt';

    {Si el usuario no introduce el nombre, se aplica uno por defecto. }

    assign(fichero, archivo);

    {Se asigna el nombre del archivo a la variable fichero de texto.}

    {$I-}

    reset(fichero);

    {Antes de intentar abrir el archivo, se desactiva el control de errores

    mediante la directiva del compilador $I- que ha de ir entre llaves.

    Después se intenta abrir el archivo, y se vuelve a activar el control.}

    {$I+}

    control := (ioresult = 0);

    if not control then writeln('Error en apertura de fichero.!!');

    {Si se produjo un error en la apertura del archivo porque el archivo

    no existe o cualquier otra causa, la variable "ioresult" contendrá un

    valor distinto de cero, y si no se produjo ningún error y el archivo

    pudo ser abierto, contendrá  el valor cero. }

    writeln

    until control or (contador >= 3);

    if (contador >= 3) and not(control) then Halt(1);

    {Si no se pudo abrir el archivo parar la ejecución del programa.}

    while not eof(fichero) do

    {Repetir el siguiente proceso hasta que se detecte la marca

    de final de fichero.}

    begin

    while not eoln(fichero) do

    {Para cada línea de texto se repite el siguiente proceso:}

    begin

    read(fichero, letra);

    {Leer un carácter del archivo.}

    write(letra);

    {Escribir el carácter por pantalla.}

    letra := upcase(letra);

    {convertir el carácter a mayúsculas.}

    case letra of

    {Si el carácter es una vocal o una vocal acentuada,

    se incrementa el acumulador correspondiente a dicha vocal.}

    'A','á': inc(acumulador[a]);

    'E','é': inc(acumulador[e]);

    'I','í': inc(acumulador[i]);

    'O','ó': inc(acumulador[o]);

    'U','ú','ü': inc(acumulador[u])

    end

    end;

    if not eof(fichero) then

    {Se ha alcanzado una marca de final de línea, y si no es final de

    archivo, hay que leer otro carácter, porque la marca de final de línea

    se compone de dos: Avance de línea (#10) y retorno de carro (#13).}

    begin

    read(fichero, letra);

    write(letra)

    end

    end;

    close(fichero);

    {Una vez se ha leído todo el archivo, hay que cerrarlo}

    writeln;

    for index := a to u do

    {Presentar por pantalla los valores de los acumuladores:}

    begin

    case index of

    a: write(' A: ');

    e: write(' E: ');

    i: write(' I: ');

    o: write(' O: ');

    u: write(' U: ')

    end;

    writeln(acumulador[index]:3,' veces.')

    end;

    readkey

    end.

    5. Escribir un programa que cuente el número de palabras de un texto. Las palabras terminan cuando hay un espacio en blanco, o un `.', `,', `;' o termina la línea o el fichero.

    Program t9e5(Input, Output);

    uses Crt;

    Var fichero: Text;

    letra: Char;

    contador: integer;

    palabra: String;

    control: boolean;

    Begin

    ClrScr;

    contador := 0;

    {Contar  el nº de veces que se intente abrir un archivo de texto.}

    repeat

    write('Nombre de archivo: ');

    readln(palabra);

    inc(contador);

    if palabra = '' then palabra := 'c:\tp\bin\temas\tema9\t9e2dat.txt';

    {Si el usuario no introduce el nombre, se aplica uno por defecto. }

    assign(fichero, palabra);

    {Se asigna el nombre del archivo a la variable fichero de texto.}

    {$I-}

    reset(fichero);

    {Antes de intentar abrir el archivo, se desactiva el control de errores

    mediante la directiva del compilador $I- que ha de ir entre llaves.

    Después se intenta abrir el archivo, y se vuelve a activar el control.}

    {$I+}

    control := (ioresult = 0);

    if not control then writeln('Error en apertura de fichero.!!');

    {Si se produjo un error en la apertura del archivo porque el archivo

    no existe o cualquier otra causa, la variable "ioresult" contendrá un

    valor distinto de cero, y si no se produjo ningún error y el archivo

    pudo ser abierto, contendrá  el valor cero. }

    writeln

    until control or (contador >= 3);

    if (contador >= 3) and not(control) then Halt(1);

    {Si no se pudo abrir el archivo parar la ejecución del programa.}

    contador := 0;

    palabra := '';

    control := false;

    while not eof(fichero) do

    {Mientras que no se encuentre el final de archivo:}

    begin

    while not eoln(fichero) do

    {Para cada línea de texto hacer:}

    begin

    read(fichero, letra);

    {Leer un carácter del archivo.}

    if not(letra in [' ', ',', '.', ';', ':', #13, #10])

    {Si el carácter no es un signo de puntuación o un blanco:}

    then begin

    if not control then inc(contador);

    {"Control" vale true cuando el anterior carácter no era

    un signo de puntuación, o sea, que la palabra ya había

    empezado, y false si la palabra empieza en este carácter.}

    control := true;

    palabra := palabra + letra

    {Se añade el carácter a la palabra.}

    end

    else begin

    {El carácter leído es un signo de puntuación o un blanco,

    por lo que la palabra ha terminado.}

    control := false;

    writeln('Palabra(',contador,'): ',palabra);

    {Se escribe la palabra en pantalla.}

    palabra := '';

    {Se borra la palabra para empezar con la siguiente.}

    if (contador mod 24) = 0 then readkey;

    {Pausa para ver una pantalla (24 líneas)}

    while ((letra in [' ', ',', '.', ';', ':', #13, #10])

    or eoln(fichero)) and not(eof(fichero)) do

    {Mientras que el carácter leído siga siendo un signo,

    o un blanco, o una marca de final de línea o de fichero,

    que son los que separan las palabras, hay que seguir leyendo

    caracteres sin aumentar el n§ de palabras:}

    begin

    read(fichero, letra);

    if not(letra in [' ', ',', '.', ';', ':', #13, #10])

    {Se ha encontrado el comienzo de una nueva palabra.}

    then begin

    inc(contador);

    palabra := palabra+letra;

    {Se añade el carácter a la nueva palabra.}

    control := true

    {Se activa el control de palabra.}

    end

    end

    end

    end;

    if not eof(fichero) then

    {Se alcanzó el final de línea.}

    begin

    {Hay que leer el segundo carácter de la marca.}

    read(fichero, letra);

    write(letra)

    end

    end;

    close(fichero);

    {Una vez terminada la lectura del archivo, hay que cerrarlo.}

    writeln;

    writeln('Total: ',contador,' palabras.');

    readkey

    end.

    6. Realizar un programa que lea un fichero de texto (entrada) y que escriba un fichero de texto (salida) que contenga solamente las palabras leídas que tengan un número impar de letras y además la del medio sea vocal. El fichero de entrada sólo contendrá caracteres alfabéticos, espacios en blanco y saltos de línea. Se supone que la longitud de las palabras no excede en ningún caso de 33 caracteres.

    Program t9e6(Input, Output);

    uses Crt;

    Const vocales: Set of Char = (['A','E','I','O','U']);

    Var fichero, ficsalida: Text;

    letra: Char;

    contletras, contpal, escritas: integer;

    palabra: String;

    control: boolean;

    Begin

    ClrScr;

    contpal := 0;

    repeat

    write('Nombre de archivo: ');

    readln(palabra);

    inc(contpal);

    if palabra = '' then palabra := 'c:\tp\bin\temas\tema9\t9e2dat.txt';

    {Si el usuario no introduce el nombre, se aplica uno por defecto. }

    assign(fichero, palabra);

    {Se asigna el nombre del archivo a la variable fichero de texto.}

    {$I-}

    reset(fichero);

    {Antes de intentar abrir el archivo, se desactiva el control de errores

    mediante la directiva del compilador $I- que ha de ir entre llaves.

    Después se intenta abrir el archivo, y se vuelve a activar el control.}

    {$I+}

    control := (ioresult = 0);

    if not control then writeln('Error en apertura de fichero.!!');

    {Si se produjo un error en la apertura del archivo porque el archivo

    no existe o cualquier otra causa, la variable "ioresult" contendrá un

    valor distinto de cero, y si no se produjo ningún error y el archivo

    pudo ser abierto, contendrá  el valor cero. }

    writeln

    until control or (contpal >= 3);

    if (contpal >= 3) and not(control) then Halt(1);

    {Si no se pudo abrir el archivo parar la ejecución del programa.}

    write('Nombre de archivo de salida: ');

    readln(palabra);

    if palabra = '' then

    {Si el usuario no introduce el nombre, se aplica uno por defecto. }

    begin

    palabra := 't9e6out.txt';

    writeln;

    writeln('El archivo de salida es T9E6OUT.TXT');

    readkey;

    writeln

    end;

    assign(ficsalida, palabra);

    {Se asigna el fichero de salida.}

    rewrite(ficsalida);

    {Se abre el fichero de salida. No hace falta controlar si ha habido un

    error en la apertura, porque "rewrite" crea un nuevo archivo.}

    palabra := '';

    control := false;

    contpal := 0;

    contletras := 0;

    escritas := 0;

    while not eof(fichero) do

    begin

    while not eoln(fichero) do

    begin

    read(fichero, letra);

    if not(letra in [' ', ',', '.', ';', ':', #13, #10])

    then begin

    if not control then inc(contpal);

    control := true;

    inc(contletras);

    palabra := palabra + letra

    end

    else begin

    control := false;

    write('Palabra (',contpal,'): ',palabra);

    if odd(contletras)

    {Una vez separada la palabra del archivo, se comprueba

    si la letra central es una vocal. Para ello, lo primero es

    saber si existe una letra central comprobando si la palabra

    tiene un número impar de letras.}

    then begin

    if (upcase(palabra[(contletras div 2)+1]) in vocales)

    {Si hay una letra central, se comprueba si es una vocal.}

    then begin

    {En caso de serlo, se incrementa el n§ de palabras

    que se escriben el fichero de salida, y se escribe

    la palabra en el archivo.}

    inc(escritas);

    writeln(' ....... **** Escrita en fichero. **** ');

    writeln(ficsalida,palabra)

    end

    else writeln

    end

    else writeln;

    palabra := '';

    {Se comienza el proceso con una nueva palabra.}

    contletras := 0;

    if (contpal mod 24) = 0 then readkey; {Pausa}

    while ((letra in [' ', ',', '.', ';', ':', #13, #10])

    or eoln(fichero)) and not(eof(fichero)) do

    begin

    read(fichero, letra);

    if not(letra in [' ', ',', '.', ';', ':', #13, #10])

    then begin

    inc(contpal);

    inc(contletras);

    palabra := palabra+letra;

    control := true

    end

    end

    end

    end;

    if not eof(fichero) then

    begin

    read(fichero, letra);

    write(letra)

    end

    end;

    close(fichero);

    close(ficsalida);

    {Se cierran los dos ficheros, el de lectura y el de escritura.}

    writeln;

    writeln('Total: ',contpal,' palabras.');

    writeln;

    writeln(escritas,' palabras escritas en el archivo de salida.');

    readkey

    end.

    7. Escribir un programa que cuente el número de palabras en un texto, que tengan al menos cuatro vocales diferentes. Se supone que las palabras no están cortadas al final de las líneas.

    Program t9e7(Input, Output);

    uses Crt;

    Const vocales: Set of Char = (['A','E','I','O','U',' ',' ','¡','¢','£','£']);

    separadores: Set of Char = ([' ', ',', '.', ';', ':', #13, #10,

    '(',')','?','¨','­','!','"','-','+','[','''',']']);

    Var fichero: Text;

    vocenpal: Set of Char;

    letra: Char;

    contador, index, contletras, contpal, pal4voc, numvoc: integer;

    palabra, archivo: String;

    control: boolean;

    Begin

    ClrScr;

    contador := 0;

    {Contar  el nº de veces que se intente abrir un archivo de texto.}

    repeat

    write('Nombre de archivo: ');

    readln(archivo);

    inc(contador);

    if archivo = '' then archivo := 'c:\tp\bin\temas\tema9\t9e7dat.txt';

    {Si el usuario no introduce el nombre, se aplica uno por defecto. }

    assign(fichero, archivo);

    {Se asigna el nombre del archivo a la variable fichero de texto.}

    {$I-}

    reset(fichero);

    {Antes de intentar abrir el archivo, se desactiva el control de errores

    mediante la directiva del compilador $I- que ha de ir entre llaves.

    Después se intenta abrir el archivo, y se vuelve a activar el control.}

    {$I+}

    control := (ioresult = 0);

    if not control then writeln('Error en apertura de fichero.!!');

    {Si se produjo un error en la apertura del archivo porque el archivo

    no existe o cualquier otra causa, la variable "ioresult" contendrá un

    valor distinto de cero, y si no se produjo ningún error y el archivo

    pudo ser abierto, contendrá  el valor cero. }

    writeln

    until control or (contador >= 3);

    if (contador >= 3) and not(control) then Halt(1);

    {Si no se pudo abrir el archivo, parar la ejecución del programa.}

    palabra := '';

    control := false;

    contpal := 0;

    contletras := 0;

    pal4voc := 0;

    while not eof(fichero) do

    begin

    while not eoln(fichero) do

    begin

    read(fichero, letra);

    if not(letra in separadores)

    {Si el carácter leído no es un signo:}

    then begin

    if not control then inc(contpal);

    control := true;

    inc(contletras);

    palabra := palabra + letra

    end

    else begin

    control := false;

    write('Palabra (',contpal,'): ',palabra);

    numvoc := 0;

    vocenpal := vocales;

    {El conjunto vocenpal contiene ahora las 5 vocales}

    for index := 1 to contletras do

    {Hay que comprobar si la palabra contiene al menos

    cuatro vocales distintas, para ello se recorren todos

    los caracteres que componen la palabra.}

    if (upcase(palabra[index]) in vocenpal)

    {Si el carácter de la palabra est  en el conjunto,}

    then begin

    inc(numvoc);

    {Se incrementa el contador de vocales,}

    vocenpal := vocenpal - [upcase(palabra[index])]

    {Se elimina la vocal del conjunto.}

    end;

    if numvoc >= 4

    {Si se han contado al menos 4 vocales,}

    then begin

    inc(pal4voc);

    {Se incrementa el contador de palabras con 4 vocales}

    writeln(' ....... **** Palabra con 4 vocales ****')

    end

    else writeln;

    palabra := '';

    contletras := 0;

    if (contpal mod 24) = 0 then readkey; {Pausa}

    while ((letra in separadores)

    or eoln(fichero)) and not(eof(fichero)) do

    begin

    read(fichero,letra);

    if not(letra in separadores)

    then begin

    inc(contpal);

    inc(contletras);

    palabra := palabra+letra;

    control := true

    end

    end

    end

    end;

    if not eof(fichero) then

    begin

    read(fichero,letra);

    write(letra)

    end

    end;

    close(fichero);

    {Se cierra el fichero.}

    writeln;

    writeln('Total: ',contpal,' palabras.');

    writeln;

    writeln('Palabras con al menos 4 vocales distintas: ',pal4voc,' palabras.');

    readkey

    end.

    9. Se dispone de dos archivos de enteros, cada uno en una línea. Se desea sumar los valores de los números que ocupan la misma línea y llenar con ellos un archivo. Los archivos pueden tener longitudes distintas.

    Program t9e9(Input, Output);

    Uses Crt;

    Type intfic = file of integer;

    Var fic1, fic2, outfic: intfic;

    int1, int2, suma, contador: integer;

    Extension: String;

    Begin

    ClrScr;

    writeln('Se trata de crear un archivo de números enteros ');

    writeln('que son la suma de los que hay en otros dos archivos:');

    writeln('Los números se suman por filas, y si los dos archivos');

    writeln('no contienen el mismo número de filas, cuando se acabe');

    writeln('el contenido de uno, se escribirá sólo lo que quede de el otro.');

    writeln;

    writeln('Pulsa una tecla para continuar ...');

    readkey;

    ClrScr;

    extension := '\tp\bin\temas\tema9\';

    assign(fic1, extension + 't9e9dat1.txt');

    assign(fic2, extension + 't9e9dat2.txt');

    assign(outfic, extension + 't9e9out.txt');

    rewrite(fic1);

    rewrite(fic2);

    for contador := 1 to 15 do write(fic1,contador);

    for contador := 20 to 30 do write(fic2,contador);

    reset(fic1);

    reset(fic2);

    rewrite(outfic);

    contador := 0;

    {Cuenta la línea de archivo leída.}

    while not(eof(fic1)) and not(eof(fic2)) do

    {Mientras que no se llegue al final en alguno de los dos archivos:}

    begin

    inc(contador);

    read(fic1,int1);

    read(fic2,int2);

    suma := int1+int2;

    writeln('Línea ',contador:3,': ',int1:3,' + ',int2:3,' = ',suma:4);

    write(outfic,suma)

    end;

    {Si uno de los archivos aun no ha llegado al final, hay que añadir

    al archivo de salida los números que queden en el.}

    if eof(fic1) then

    begin

    while not(eof(fic2)) do

    begin

    inc(contador);

    read(fic2,int2);

    writeln('Añadiendo de fichero 2 línea ',contador,': ',int2);

    write(outfic,int2)

    end

    end

    else while not(eof(fic1)) do

    begin

    inc(contador);

    read(fic1,int1);

    writeln('Añadiendo de fichero 1 línea ',contador,': ',int1);

    write(outfic,int1)

    end;

    writeln;

    writeln('Ficheros procesados.');

    close(fic1);

    close(fic2);

    close(outfic);

    readkey

    end.

    11. Se dispone de tres ficheros de alumnos, uno para cada grupo I1, I2, I3. Se quiere obtener un nuevo fichero con los alumnos no presentados en la convocatoria. Un alumno no presentado tiene como nota final un 0.

    Program t9e11(Input, Output);

    Uses Crt;

    Const ficI1 = 'I1.dat';

    ficI2 = 'I2.dat';

    ficI3 = 'I3.dat';

    Type alumno = record

    nombre: String[25];

    nota_exam, nota_final: real

    end;

    ficalumnos = file of alumno;

    Var I1, I2, I3, NoPres: ficalumnos;

    ficha: alumno;

    Datosnuevos: Char;

    Procedure llenarfic(archivo: String);

    {Crea un archivo con los datos de los alumnos de un grupo.}

    var fic: file of alumno;

    ficha: alumno;

    fin: boolean;

    entrada: Char;

    begin

    writeln('Llenando archivo .... ',archivo);

    assign(fic,archivo);

    rewrite(fic);

    repeat

    with ficha do

    begin

    writeln;

    writeln('*** Alumno Nuevo ***');

    write('Nombre: ');

    readln(nombre);

    write('Nota de examen: ');

    read(nota_exam);

    write(' Nota final: ');

    readln(nota_final)

    end;

    writeln;

    write('¨Introducir otro alumno? [S/N]: ');

    repeat

    entrada := upcase(readkey)

    until entrada in ['S','N'];

    writeln(entrada);

    fin := (entrada = 'N');

    write(fic,ficha)

    {Escribir el registro en el archivo.}

    until fin;

    close(fic)

    end;

    Procedure AddNoP(var fic, NoP: ficalumnos);

    {Añade los alumnos de un grupo que sean no presentados

    al archivo de no presentados.}

    var ficha: Alumno;

    begin

    while not(eof(fic)) do

    {mientras que no se llegue al final del fichero de alumnos del grupo:}

    begin

    read(fic,ficha);

    {Lee los datos de un alumno, y los almacena en el registro "ficha"}

    with ficha do

    {Presenta por pantalla los datos del alumno.}

    begin

    write('Alumno: ',nombre);

    write(' --- Nota final: ',nota_final:5:2)

    end;

    if ficha.nota_final = 0 then

    {Si la nota final es cero, se considera como no presentado.}

    begin

    writeln(' *** NO PRESENTADO ***');

    write(NoP,ficha)

    end

    else writeln

    end;

    writeln;

    end;

    Begin

    ClrScr;

    write('¨ Crear los archivos de los grupos ? [S/N]: ');

    repeat

    datosnuevos := upcase(readkey)

    until datosnuevos in ['S','N'];

    ClrScr;

    if datosnuevos = 'S' then

    begin

    llenarfic(ficI1);

    llenarfic(ficI2);

    llenarfic(ficI3)

    end;

    assign(I1,ficI1);

    assign(I2,ficI2);

    assign(I3,ficI3);

    reset(I1);

    reset(I2);

    reset(I3);

    Assign(Nopres,'No_pres.dat');

    rewrite(Nopres);

    {Se abre para escritura el archivo de no presentados.}

    writeln('Grupo I1:');

    AddNoP(I1,Nopres);

    writeln('Grupo I2:');

    AddNoP(I2,Nopres);

    writeln('Grupo I3:');

    AddNoP(I3,Nopres);

    close(I1);

    close(I2);

    close(I3);

    {Se cierran los archivos de los grupos.}

    reset(Nopres);

    {Se abre para lectura el archivo de no presentados.}

    writeln;

    writeln('*** ALUMNOS NO PRESENTADOS ***');

    while not(eof(Nopres)) do

    begin

    read(Nopres,ficha);

    writeln(' -> ',ficha.nombre)

    end;

    close(Nopres);

    {Se cierra el archivo de no presentados.}

    readkey

    end.


    Ejercicios tema 10

    2. Crear una lista enlazada con los datos de los alumnos de una clase. Los datos son: nombre, nota parcial, nota final, nota de trabajos y un campo booleano que indique si está suspendido o aprobado. Los datos los introduce el usuario. No se sabe el número de alumnos de la clase. Cada vez que el usuario introduzca los datos de un alumno el programa preguntará si quiere seguir introduciendo datos. Considerar primero que cada nuevo alumno que se inserta es el primero de la lista y después que es el ultimo de la lista. Al finalizar la inserción de datos, recorrer la lista mostrando el orden en el que han quedado los alumnos.

    Program t10e2(Input, Output);

    Uses Crt;

    Type alumno = record

    nombre: String[34];

    parcial, final, trabajos: real;

    apto: boolean

    end;

    Pnodo = ^nodo;

    nodo = record

    info: alumno;

    enlace: Pnodo

    {Listas simplemente enlazadas.}

    end;

    Var cabeza1, cabeza2, cola2: Pnodo;

    Procedure iniciar1(var lista: Pnodo);

    {Inicializa una lista poniendo a NIL su puntero cabeza.}

    begin

    lista := nil

    end;

    Procedure iniciar2(var lista,cola: Pnodo);

    {Inicializa una lista poniendo a NIL sus punteros cabeza y cola.}

    begin

    lista := nil;

    cola := nil

    end;

    Procedure introdatos;

    {Lee los datos de los alumnos desde el teclado y los enlaza

    en una lista}

    var ficha: alumno;

    nombrefic: String;

    fic: file of alumno;

    puntaux: Pnodo;

    desdearchivo, terminar, correcto: boolean;

    entrada: Char;

    redondeo: integer;

    notamedia: real;

    Function si_no(pregunta: String): Char;

    {Devuelve un carácter, que es la respuesta a una pregunta

    del tipo SI - NO. Se le pasa como par metro un String que

    contenga la pregunta a realizar al usuario.}

    var oSioNo: Char;

    begin

    pregunta := pregunta + ' [S/N]: ';

    {Se añade a la pregunta, las respuestas posibles, para

    que el usuario las vea en pantalla.}

    write(pregunta);

    repeat

    osiono := upcase(readkey)

    until osiono in ['S','N'];

    {La respuesta del usuario podrá  ser sólo S o N.}

    writeln(osiono);

    si_no := oSioNo

    end;

    Function creanodo(nuevaficha: alumno): Pnodo;

    {A partir de un registro de tipo alumno, crea una variable

    din mica de tipo nodo.}

    var aux: Pnodo;

    begin

    new(aux);

    {Se reserva memoria din mica para un nodo.}

    aux^.info := nuevaficha;

    {Se inicializa el campo info del nodo con el registro de

    los datos del alumno.}

    aux^.enlace := nil;

    {Se inicializa el enlace del nodo a NIL}

    creanodo := aux

    end;

    Procedure inscabeza(var lista: Pnodo; nuevo: Pnodo);

    {Inserta un nodo en la cabeza de una lista.}

    var aux: Pnodo;

    begin

    if lista = nil then lista := nuevo

    {Si la lista estaba vacía, se asigna al puntero cabeza

    para que apunte al nuevo nodo. No hace falta modificar el nodo

    porque su campo enlace ya apunta a NIL.}

    else begin

    {La lista no estaba vacía.}

    aux := lista;

    {Se guarda en un puntero auxiliar la dirección del

    primer nodo de la lista, que es el que apunta la cabeza.}

    lista := nuevo;

    {Se hace que la cabeza de la lista sea el nuevo nodo.}

    nuevo^.enlace := aux

    {Se hace que el puntero enlace del nodo insertado, apunte

    al nodo que antes era la cabeza de la lista. De esta manera

    la lista vuelve a quedar enlazada.}

    end

    end;

    Procedure inscola(var lista, coladelista: Pnodo; nuevo: Pnodo);

    {Inserta un nodo en el final de una lista.}

    var aux: Pnodo;

    begin

    if lista = nil

    {Si la lista estaba vacía:}

    then begin

    lista := nuevo;

    coladelista := nuevo

    {Se asigna tanto al puntero cabeza como al de cola, para

    que apunten al nuevo nodo, ya que como es el único nodo en

    la lista, es a la vez cabeza y cola de la lista.}

    end

    else begin

    {La lista no estaba vacía, entonces:}

    aux := coladelista;

    {Se almacena en un puntero auxiliar, a donde apunta el

    puntero de cola de la lista.}

    coladelista := nuevo;

    {Se asigna al puntero de cola, para que apunte al nuevo nodo.}

    aux^.enlace := nuevo

    {Se hace que el puntero enlace del nodo que antes era

    la cola de la lista, apunte al nodo que se inserta, de esta

    forma la lista vuelve a estar enlazada.}

    end

    end;

    Procedure leerteclado;

    {Si no se leen los datos desde un archivo, hay que leerlos

    desde el teclado, y guardarlos en un archivo para que pueda

    accederse a ellos posteriormente.}

    begin

    writeln('****** Nuevo alumno ******');

    writeln;

    repeat

    with ficha do

    begin

    write('Nombre: ');

    readln(nombre);

    if nombre <> '' then

    begin

    write('Examen parcial (20%): ');

    readln(parcial);

    write('Examen final (60%): ');

    readln(final);

    write('Trabajos (20%): ');

    readln(trabajos);

    notamedia := (20*parcial+60*final+20*trabajos)/100;

    {Se calcula la nota media según los pesos de cada nota.}

    redondeo := round(notamedia);

    {Se redondea la nota media.}

    apto := redondeo >= 5;

    {Se considera apto al alumno que como mínimo saque un 5.}

    writeln('Nota media obtenida: ',notamedia:5:2);

    write('Nota después del redondeo: ',redondeo);

    if apto then writeln(' APROBADO')

    else writeln(' SUSPENSO')

    end

    end;

    entrada := si_no('¨Los datos son correctos?');

    {Llamada a la función si_no, que devolverá la respuesta.}

    correcto := (entrada = 'S');

    writeln

    until correcto;

    write(fic,ficha);

    {Se escribe la ficha en el archivo.}

    writeln

    end;

    begin

    terminar := false;

    Entrada := si_no('¨Introducir datos desde archivo?');

    desdearchivo := (entrada = 'S');

    if desdearchivo

    then write('Nombre del archivo de datos:')

    else write('Escribir los datos en el archivo:');

    readln(nombrefic);

    if nombrefic = '' then nombrefic := 't10e2.dat';

    writeln('Introduciendo datos de alumnos ...');

    writeln;

    assign(fic,nombrefic);

    if desdearchivo

    then begin

    {$I-}

    reset(fic);

    {$I+}

    if ioresult <> 0 then

    begin

    writeln('Error en la apertura del archivo ',nombrefic);

    halt(1)

    end

    end

    else rewrite(fic);

    repeat

    if not(desdearchivo) then Leerteclado

    else begin

    if not(eof(fic))

    then read(fic,ficha)

    else terminar := TRUE

    end;

    if not(terminar) then

    begin

    if ficha.nombre <> '' then

    begin

    puntaux := creanodo(ficha);

    {El puntero auxiliar "puntaux", apunta ahora al nuevo nodo

    creado por la función "creanodo" con los datos introducidos

    por el usuario desde el teclado, que se guardan en "ficha".}

    inscabeza(cabeza1,puntaux);

    {Se inserta el nodo en cabeza de la lista 1 ("cabeza1" apunta

    al nodo cabeza de la lista 1)}

    puntaux := creanodo(ficha);

    {Se crea otro nodo con los mismos datos, para insertarlo en

    la cola de la segunda lista.}

    inscola(cabeza2,cola2,puntaux)

    {Se inserta el nodo en la cola de la lista 2. }

    end

    end;

    if not(desdearchivo) then

    begin

    entrada := si_no('¨Introducir m s alumnos?');

    writeln;

    terminar := (entrada = 'N')

    end

    until terminar;

    close(fic)

    end;

    Procedure Verlistas(lis1, lis2: Pnodo);

    {Visualiza por pantalla las dos listas, mostrando cómo el orden

    en que quedan las fichas de los alumnos insertando en la cabeza

    de la lista, es al revés de como quedan insertando en la cola.

    Los par metros "lis1" y "lis2" son los punteros cabeza de las listas.}

    var orden: integer;

    begin

    ClrScr;

    if lis1 = nil then writeln('No hay ningún alumno en la lista.')

    {Si la lista 1 est  vacía, la otra también.

    Como las dos listas tienen el mismo número de nodos, no es necesario

    controlar m s que una de ellas.}

    else begin

    {Si las listas no est n vacías, entonces:}

    write('INSERTANDO EN CABEZA':27);

    writeln('INSERTANDO EN COLA':34);

    for orden := 1 to 79 do write('Í');

    writeln;

    orden := 0;

    while (lis1 <> nil) do

    {Mientras que el puntero "lis1" no apunte a NIL, cosa que ocurrir 

    cuando se alcance el último nodo de la lista.}

    begin

    inc(orden);

    write(orden:3,' ');

    write(lis1^.info.nombre,' ':36-length(lis1^.info.nombre));

    {Escribir en pantalla el campo nombre del registro info

    del nodo al que apunta el puntero "lis1".}

    lis1 := lis1^.enlace;

    {Asignar al puntero para que apunte al siguiente nodo

    de la lista. Si el enlace del actual nodo al que apunta

    "lis1", est  apuntando a NIL, entonces se ha llegado al

    final de la lista 1.}

    writeln(lis2^.info.nombre);

    lis2 := lis2^.enlace

    {Se sigue el mismo proceso que con la lista 1.}

    end;

    writeln;

    writeln('Total: ',orden,' alumnos en las listas.');

    readkey

    end

    end;

    Procedure resetMem;

    {Libera la memoria din mica reservada para los nodos de las listas.}

    var aux: Pnodo;

    cont: integer;

    begin

    ClrScr;

    cont := 0;

    while cabeza1 <> nil do

    {Las dos listas tienen el mismo número de nodos, por lo que sólo es

    necesario controlar el final de lista en una de ellas.

    Mientras que el puntero cabeza sea distinto de NIL:}

    begin

    inc(cont);

    writeln('Liberando nodo n§ ',cont);

    aux := cabeza1;

    {El puntero cabeza est  apuntando a un nodo. Se hace que el

    puntero auxiliar "aux" apunte al mismo nodo, para que éste

    no quede perdido cuando se avance en la lista.}

    cabeza1 := cabeza1^.enlace;

    {Se asigna al puntero cabeza el siguiente nodo de la lista.

    El que antes era el nodo cabecera de la lista, no se ha

    perdido, porque queda apuntado por el puntero auxiliar "aux".}

    dispose(aux);

    {Se libera la memoria reservada para el nodo al que apunta "aux"}

    aux := cabeza2;

    {Se repite el mismo proceso para la segunda lista.}

    cabeza2 := cabeza2^.enlace;

    dispose(aux)

    end

    end;

    Begin

    ClrScr;

    iniciar1(cabeza1);

    {En la lista 1 se va a insertar en la cabeza de la lista, por lo que no

    hace falta inicializar la cola de la lista.}

    iniciar2(cabeza2,cola2);

    {Para insertar en cola, es aconsejable contar con un puntero que apunte

    al último nodo de la lista, por ello se inicializan dos punteros para

    la segunda lista: Uno de cabeza y otro de cola.}

    introdatos;

    {Introducir datos de los alumnos desde teclado.}

    verlistas(cabeza1,cabeza2);

    {Ver cómo han quedado las listas utilizando distinto tipo de inserción

    en cada una de ellas.}

    resetMem;

    {Liberar la memoria din mica reservada.}

    writeln;

    writeln('That`s All Folks ...');

    readkey

    end.

    4. Dada una lista de alumnos de una clase, doblemente enlazada, ordenada alfabéticamente, mostrar la lista en orden inverso. Cabeza es un puntero al primer elemento de la lista y cola un puntero al ultimo. La lista está declarada como se indica a continuación:

    TYPE puntero = ^nodo;

    nodo = record

    nombre : String;

    parcial, final, trabajos : real;

    aprobado : booleano;

    prox, ant : puntero

    end;

    VAR cabeza, cola : puntero;

    Program t10e4(Input, Output);

    Uses Crt;

    Type alumno = record

    nombre: String[34];

    parcial, final, trabajos: real;

    apto: boolean

    end;

    Pnodo = ^nodo;

    nodo = record

    info: alumno;

    prox, ant: Pnodo

    {Lista doblemente enlazada.}

    end;

    Var cabeza, cola: Pnodo;

    Procedure iniciar(var lista, cola: Pnodo);

    {Inicializa a nil los punteros de cabeza y de cola de una lista.}

    begin

    lista := nil;

    cola := nil

    end;

    Procedure crealista;

    {Crea una lista doblemente enlazada a partir de los datos

    guardados en un archivo. La lista ser  doblemente enlazada

    para poder recorrerla en sentido inverso: Cada nodo tendrá 

    un puntero enlace hacia el nodo anterior en la lista.}

    var ficha: alumno;

    nombrefic: String;

    fic: file of alumno;

    puntaux: Pnodo;

    terminar: boolean;

    Function creanodo(nuevaficha: alumno): Pnodo;

    {Reserva memoria din mica para un nodo, inicializa su campo de

    información con los datos del nuevo alumno y devuelve un puntero

    apuntando al nodo.}

    var aux: Pnodo;

    begin

    new(aux);

    {Reserva la memoria, y hace que el puntero apunte a la variable

    din mica (nodo de la lista).}

    aux^.info := nuevaficha;

    {Inicializa el campo de información con los datos.}

    aux^.prox := nil;

    aux^.ant := nil;

    {Inicializa a NIL los punteros de enlace del nodo con el nodo

    siguiente y con el nodo anterior.}

    creanodo := aux

    end;

    Procedure inscola(var lista, coladelista: Pnodo; nuevo: Pnodo);

    {Inserta un nodo en la cola de una lista doblemente enlazada.}

    var aux: Pnodo;

    begin

    if lista = nil then

    {Si la lista est  vacía, }

    begin

    lista := nuevo;

    coladelista := nuevo

    {Hace que los punteros de cabeza y cola de la lista apunten

    al nuevo nodo.}

    end

    else begin

    {Si la lista no estaba vacía:}

    aux := coladelista;

    {El puntero auxiliar apunta ahora hacia el último nodo de

    la lista, para no perder la referencia de este nodo.}

    nuevo^.ant := aux;

    {Se inicializa el enlace del nodo que se va a insertar hacia

    el nodo anterior en la lista, que es el que antes era la cola.}

    coladelista := nuevo;

    {La cola de la lista es ahora el nodo insertado, y se hace

    que el puntero de cola apunte a este nodo.}

    aux^.prox := nuevo

    {El enlace del que antes era el último nodo de la lista,

    hacia el próximo nodo, se hace que apunte hacia el nodo

    insertado, que es ahora el último, quedando as¡ la lista

    de nuevo enlazada.}

    end

    end;

    begin

    terminar := false;

    nombrefic := 't10e2.dat';

    {Se utiliza el mismo archivo que para el ejercicio 2}

    assign(fic,nombrefic);

    reset(fic);

    while not(eof(fic)) do

    {Mientras que no se alcance el final de fichero:}

    begin

    read(fic,ficha);

    {Se lee un registro del archivo.}

    writeln('Leyendo ... ',ficha.nombre);

    puntaux := creanodo(ficha);

    {Puntaux apunta ahora al nodo creado por la función creanodo

    con los datos del registro leído del archivo.}

    inscola(cabeza,cola,puntaux)

    {Se inserta el nodo en la lista.}

    end;

    close(fic);

    {Se cierra el fichero.}

    writeln;

    writeln('Finalizada lectura de archivo ',nombrefic);

    writeln;

    writeln('Pulsa una tecla para continuar ...');

    readkey

    end;

    Procedure Veralreves(findelista: Pnodo);

    {Visualiza una lista en orden inverso. Hay que pasarle como

    par metro el puntero que apunta al final de la lista.}

    begin

    ClrScr;

    if findelista = nil then writeln('No hay ningún alumno en la lista.')

    else begin

    {Si la lista no est  vacía:}

    writeln('La lista visualizada al revés:');

    writeln;

    while (findelista <> nil) do

    {Mientras que el puntero que recorre la lista no apunte a NIL:}

    begin

    writeln(' ':6,findelista^.info.nombre);

    {Escribir el nombre del alumno que almacena el nodo.}

    findelista := findelista^.ant

    {Hacer que el puntero que recorre la lista apunte al nodo

    anterior, que est  apuntado por el enlace del nodo hacia

    el nodo anterior en la lista. Si el nodo al que apuntaba

    era ya el primero de la lista, su enlace al anterior

    apuntar  a NIL, y el recorrido de la lista habrá  terminado.}

    end;

    writeln;

    writeln('Pulsa una tecla para terminar ...');

    readkey

    end

    end;

    Procedure resetMem;

    {Libera la memoria din mica reservada para los nodos de la lista.}

    var aux: Pnodo;

    cont: integer;

    begin

    ClrScr;

    cont := 0;

    writeln('Liberando la memoria din mica:');

    while cabeza <> nil do

    begin

    inc(cont);

    writeln('Eliminando nodo n§ ',cont);

    aux := cabeza;

    cabeza := cabeza^.prox;

    dispose(aux)

    end

    end;

    Begin

    ClrScr;

    iniciar(cabeza,cola);

    {Inicializar los punteros de cabeza y cola de la lista.}

    crealista;

    {Leer los datos del archivo y crear la lista enlazada.}

    veralreves(cola);

    {Visualizar la lista en orden inverso, desde la cola hasta la cabeza.}

    resetMem;

    {Liberar la memoria reservada.}

    writeln;

    writeln('That`s All Folks ...');

    readkey

    end.

    5. Dada la misma lista de alumnos, crear una nueva lista en orden inverso, pero esta vez simplemente enlazada.

    Program t10e5(Input, Output);

    Uses Crt;

    Type alumno = record

    nombre: String[34];

    parcial, final, trabajos: real;

    apto: boolean

    end;

    Pnodo = ^nodo;

    nodo = record

    info: alumno;

    prox, ant: Pnodo

    end;

    Var cabeza, cola: Pnodo;

    Procedure iniciar(var lista, cola: Pnodo);

    begin

    lista := nil;

    cola := nil

    end;

    Procedure crealista;

    var ficha: alumno;

    nombrefic: String;

    fic: file of alumno;

    puntaux: Pnodo;

    terminar: boolean;

    Function creanodo(nuevaficha: alumno): Pnodo;

    var aux: Pnodo;

    begin

    new(aux);

    aux^.info := nuevaficha;

    aux^.prox := nil;

    aux^.ant := nil;

    creanodo := aux

    end;

    Procedure inscola(var lista, coladelista: Pnodo; nuevo: Pnodo);

    var aux: Pnodo;

    begin

    if lista = nil then

    begin

    lista := nuevo;

    coladelista := nuevo

    end

    else begin

    aux := coladelista;

    nuevo^.ant := aux;

    coladelista := nuevo;

    aux^.prox := nuevo

    end

    end;

    begin

    terminar := false;

    nombrefic := 't10e2.dat';

    assign(fic,nombrefic);

    reset(fic);

    while not(eof(fic)) do

    begin

    read(fic,ficha);

    writeln('Leyendo ... ',ficha.nombre);

    puntaux := creanodo(ficha);

    inscola(cabeza,cola,puntaux)

    end;

    readkey;

    close(fic)

    end;

    PROCEDURE hazlistasimple(lis1: Pnodo);

    {Crea una lista simplemente enlazada a partir de la lista

    doblemente enlazada del ejercicio 4}

    Type

    Puntero = ^nodosimple;

    nodosimple = record

    info: alumno;

    enlace: Puntero

    {Lista simplemente enlazada.}

    end;

    var listasimple, colasimple, punteroaux: puntero;

    Procedure inisimple(var lista: Puntero);

    begin

    lista := nil

    end;

    Function haznodosimple(nuevaficha: alumno): Puntero;

    {Crea un nodo para lista simplemente enlazada.}

    var aux: Puntero;

    begin

    new(aux);

    aux^.info := nuevaficha;

    aux^.enlace := nil;

    haznodosimple := aux

    end;

    Procedure insnodo(var lista, cola: Puntero; nuevo: Puntero);

    {Inserta un nodo en la cola de una lista simplemente enlazada.}

    var aux: Puntero;

    begin

    if lista = nil then

    begin

    lista := nuevo;

    cola := nuevo

    end

    else begin

    aux := cola;

    cola := nuevo;

    aux^.enlace := nuevo

    end

    end;

    Procedure SimpleResetMem;

    {Libera la memoria din mica reservada para los nodos de

    una lista simplemente enlazada.}

    var aux: Puntero;

    cont: integer;

    begin

    ClrScr;

    cont := 0;

    writeln('Liberando la memoria din mica (lista simple):');

    while listasimple <> nil do

    begin

    inc(cont);

    writeln('Eliminando nodo n§ ',cont);

    aux := listasimple;

    listasimple := listasimple^.enlace;

    dispose(aux)

    end

    end;

    begin

    ClrScr;

    inisimple(listasimple);

    {Inicializar el puntero de cabeza de la lista.}

    if lis1 = nil then writeln('No hay ningún alumno en la lista.')

    else begin

    {Si la lista doblemente enlazada, a partir de la cual se va

    a construir la lista simplemente enlazada, no est  vacía:}

    writeln('Fabricando la nueva lista:');

    writeln;

    while (lis1 <> nil) do

    {Mientras que no se alcance el final de la lista doble:}

    begin

    punteroaux := haznodosimple(lis1^.info);

    {Se crea el nodo de lista simple, y se apunta por el

    puntero auxiliar "punteroaux".}

    insnodo(listasimple, colasimple, punteroaux);

    {Se inserta e nodo en la cola de la lista.}

    lis1 := lis1^.ant

    {La lista doblemente enlazada se recorre en orden inverso

    de manera que la lista simple que se va creando queda

    ya ordenada al revés que la doble.}

    end;

    punteroaux := listasimple;

    {Se asigna al puntero auxiliar, la cabeza de la lista simple,

    para que sirva de puntero de recorrido a través de la lista.}

    writeln('As¡ queda la lista simple:');

    writeln;

    while punteroaux <> nil do

    {Mientras que no se llegue al final de la lista simple:}

    begin

    writeln(' ':6,punteroaux^.info.nombre);

    {Escribir el nombre del alumno.}

    punteroaux := punteroaux^.enlace

    {Recorrer la lista: "Punteroaux" va apuntando uno por uno

    a todos los nodos de la lista, hasta llegar al último,

    cuyo enlace apunta a NIL.}

    end;

    writeln;

    writeln('Pulsa una tecla para continuar ...');

    readkey

    end;

    SimpleResetMem;

    {Liberar la memoria reservada para los nodos de la lista simple.}

    writeln;

    end;

    Procedure resetMem;

    {Libera la memoria reservada para los nodos de la lista doble.}

    var aux: Pnodo;

    cont: integer;

    begin

    cont := 0;

    writeln('Liberando la memoria din mica:');

    while cabeza <> nil do

    begin

    inc(cont);

    writeln('Eliminando nodo n§ ',cont);

    aux := cabeza;

    cabeza := cabeza^.prox;

    dispose(aux)

    end

    end;

    Begin

    ClrScr;

    iniciar(cabeza,cola);

    crealista;

    {Crear la misma lista que la del ejercicio 4 (es doblemente enlazada).}

    hazlistasimple(cola);

    {Fabricar la lista simplemente enlazada a partir de la doble.}

    resetMem;

    {Liberar la memoria.}

    writeln;

    writeln('That`s All Folks ...');

    readkey

    end.

    6. Dada una lista de libros, que contiene titulo, editorial, año de publicación. Mostrar todas las películas anteriores a un año determinado.

    Program t10e6(Input, Output);

    Uses Crt;

    Type libro = record

    titulo: String[35];

    editorial: String[25];

    ano: integer

    end;

    Pnodo = ^nodo;

    nodo = record

    info: libro;

    enlace: Pnodo

    {Lista simplemente enlazada.}

    end;

    Var cabeza: Pnodo;

    Procedure iniciar(var lista: Pnodo);

    begin

    lista := nil

    end;

    Procedure introdatos;

    var ficha: libro;

    nombrefic: String;

    fic: file of libro;

    puntaux: Pnodo;

    desdearchivo, terminar, correcto: boolean;

    entrada: Char;

    Function si_no(pregunta: String): Char;

    var oSioNo: Char;

    begin

    pregunta := pregunta + ' [S/N]: ';

    write(pregunta);

    repeat

    osiono := upcase(readkey)

    until osiono in ['S','N'];

    writeln(osiono);

    si_no := oSioNo

    end;

    Function creanodo(nuevaficha: libro): Pnodo;

    var aux: Pnodo;

    begin

    new(aux);

    aux^.info := nuevaficha;

    aux^.enlace := nil;

    creanodo := aux

    end;

    Procedure inscabeza(var lista: Pnodo; nuevo: Pnodo);

    var aux: Pnodo;

    begin

    if lista = nil then lista := nuevo

    else begin

    aux := lista;

    lista := nuevo;

    nuevo^.enlace := aux

    end

    end;

    Procedure leerteclado;

    begin

    writeln;

    writeln(' ****** Nuevo libro ******');

    writeln;

    repeat

    with ficha do

    begin

    write('Título: ');

    readln(titulo);

    write('editorial: ');

    readln(editorial);

    write('Año de publicación: ');

    readln(ano);

    end;

    entrada := si_no('¨Los datos son correctos?');

    correcto := (entrada = 'S');

    writeln;

    until correcto;

    write(fic,ficha);

    writeln

    end;

    begin

    terminar := false;

    Entrada := si_no('¨Introducir datos desde archivo?');

    desdearchivo := (entrada = 'S');

    if desdearchivo

    then write('Nombre del archivo de datos:')

    else write('Escribir los datos en el archivo:');

    readln(nombrefic);

    if nombrefic = '' then nombrefic := 't10e6.dat';

    writeln('Introduciendo datos de publicaciones ...');

    writeln;

    assign(fic,nombrefic);

    if desdearchivo

    then reset(fic)

    else rewrite(fic);

    repeat

    if not(desdearchivo) then Leerteclado

    else begin

    if not(eof(fic))

    then read(fic,ficha)

    else terminar := TRUE

    end; if not(terminar) then

    begin

    puntaux := creanodo(ficha);

    inscabeza(cabeza,puntaux)

    end;

    if not(desdearchivo) then

    begin

    entrada := si_no('¨Introducir m s libros?');

    writeln;

    terminar := (entrada = 'N')

    end

    until terminar;

    close(fic)

    end;

    Procedure buscaren(lis1: Pnodo);

    {Muestra por pantalla los libros de la lista cuya fecha de publicación

    sea anterior a una determinada fecha.}

    var cont, fecha: integer;

    begin

    ClrScr;

    if lis1 = nil then writeln('No hay ningún libro en la lista.')

    else begin

    {Si la lista no est  vacía:}

    write('Mostrar todos los libros anteriores al año: ');

    readln(fecha);

    writeln('T¡tulo','Editorial':41,'A¤o pub.':27);

    for cont := 1 to 75 do write('Í');

    writeln;

    while (lis1 <> nil) do

    {Mientras que no se llegue al final de la lista:}

    begin

    if lis1^.info.ano <= fecha then

    {Si el año de publicación es inferior a la fecha introducida:}

    begin

    write(lis1^.info.titulo,' ':38-length(lis1^.info.titulo));

    write(lis1^.info.editorial,' ':30-length(lis1^.info.editorial));

    writeln(lis1^.info.ano:6)

    {Escribir todos los datos referentes al libro, que est n

    almacenados en el campo información del nodo.}

    end;

    lis1 := lis1^.enlace

    {Apuntar con el puntero de recorrido al siguiente nodo de la lista.}

    end;

    writeln;

    writeln('Pulsa una tecla para terminar ...');

    readkey

    end

    end;

    Procedure resetMem;

    {Liberar la memoria reservada.}

    var aux: Pnodo;

    cont: integer;

    begin

    ClrScr;

    cont := 0;

    writeln('Liberando la memoria din mica:');

    while cabeza <> nil do

    begin

    inc(cont);

    writeln('Nodo n§ ',cont);

    aux := cabeza;

    cabeza := cabeza^.enlace;

    dispose(aux)

    end

    end;

    Begin

    ClrScr;

    iniciar(cabeza);

    introdatos;

    {Fabricar la lista}

    Buscaren(cabeza);

    {Mostrar los libros anteriores a la fecha que el usuario introduzca.}

    resetMem;

    {Liberar la memoria.}

    writeln;

    writeln('That`s All Folks ...');

    readkey

    end.

    8. Escribir un programa que cree una lista enlazada de número enteros ordenados de forma creciente. Los números los va introduciendo el usuario. Cuando introduzca el 0 significa que ha finalizado la introducción de datos. Visualizar el contenido de la lista.

    Program t10e8(Input, Output);

    Uses Crt;

    Type Pnodo = ^nodo;

    nodo = record

    info: integer;

    prox, ant: Pnodo

    {Lista doblemente enlazada.}

    end;

    Var cabeza, cola, encontrado, nuevo: Pnodo;

    numero: integer;

    terminar: boolean;

    Procedure iniciar(var lista, coladelista: Pnodo);

    begin

    lista := nil;

    coladelista := nil

    end;

    Function creanodo(nuevonumero: integer): Pnodo;

    var aux: Pnodo;

    begin

    new(aux);

    aux^.info := nuevonumero;

    aux^.prox := nil;

    aux^.ant := nil;

    creanodo := aux

    end;

    Procedure insantes(insertpoint, nuevonodo: Pnodo);

    {Inserta un nodo en la posición anterior al nodo al que apunte

    el puntero "insertpoint".}

    var aux: Pnodo;

    begin

    aux := insertpoint^.ant;

    {Se guarda en el puntero auxiliar el enlace hacia el nodo anterior

    al que se va a insertar.}

    if aux <> nil then aux^.prox := nuevonodo;

    {Si la posición en la que se va a insertar no es la cabeza de

    la lista, se hace que el enlace hacia el siguiente del nodo anterior

    apunte hacia el nodo a insertar }

    if insertpoint^.ant = nil then cabeza := nuevonodo;

    {Si el enlace del nodo donde se va a insertar hacia el anterior, est 

    apuntando a NIL, significa que se va a insertar en la cabeza de la

    lista, por lo que hay que modificar el puntero de cabeza de lista

    para que apunte al nodo que se va a insertar.

    "cabeza" es la variable global.}

    nuevonodo^.ant := insertpoint^.ant;

    {El enlace hacia el anterior del nodo a insertar debe apuntar a donde

    apuntaba el del nodo donde se inserta.}

    nuevonodo^.prox := insertpoint;

    {El enlace hacia el siguiente del nodo a insertar debe apuntar hacia

    el nodo en donde se va a insertar.}

    insertpoint^.ant := nuevonodo

    {Por último el enlace del nodo donde se va a insertar hacia el

    anterior, debe apuntar hacia el nodo que se inserta.}

    end;

    Procedure insencola(nuevonodo: Pnodo);

    {Insertar en la cola de la lista.}

    var aux: Pnodo;

    begin

    aux := cola;

    {Se guarda el puntero hacia el nodo que actualmente el

    último de la lista.}

    cola := nuevonodo;

    {El puntero de cola de la lista debe apuntar al nodo que

    se inserta. "cola" es la variable global.}

    nuevonodo^.ant := aux;

    {El enlace hacia el anterior del nodo a insertar debe apuntar

    al que antes era el nodo de cola de la lista, y que est  apuntado

    por el puntero auxiliar.}

    aux^.prox := nuevonodo

    {Por último el que antes era el nodo de cola, debe enlazar al

    nodo siguiente, que es el nodo que se inserta en la lista.}

    end;

    Function buscar(lis1: Pnodo; num: integer): Pnodo;

    {Devuelve un puntero apuntando al primer nodo de la lista que

    almacene un número mayor que el que se desee buscar.

    Si no hay ningún número en la lista que sea mayor que el que

    se desea buscar, devuelve NIL.}

    var puntaux: Pnodo;

    begin

    puntaux := lis1;

    {El puntero auxiliar, hará  de puntero de recorrido.}

    if lis1 <> nil then

    {Si la lista no est  vacía:}

    while (puntaux^.info <= num) and (puntaux <> nil)

    {Mientras que el número almacenado en el nodo sea menor o igual

    que el que se busca, y no se acabe la lista:}

    do puntaux := puntaux^.prox;

    {Se salta al siguiente nodo de la lista.}

    buscar := puntaux;

    end;

    Procedure verlista(lista: Pnodo);

    {Visualiza la lista de números.}

    begin

    ClrScr;

    if lista = nil

    then writeln('No hay ningún número en la lista.')

    else while lista <> nil do

    {Si la lista no est  vacía, mientras que no se llegue al final:}

    begin

    writeln('Elemento de lista: ',lista^.info);

    {Se escribe el número almacenado en el nodo.}

    lista := lista^.prox

    {Se salta al próximo nodo.}

    end;

    writeln;

    writeln('Pulsa una tecla para continuar ...');

    readkey

    end;

    Procedure resetMem(lista: Pnodo);

    {Liberar la memoria reservada para la lista.}

    var aux: Pnodo;

    cont: integer;

    begin

    ClrScr;

    cont := 0;

    writeln('Liberando la memoria din mica:');

    while lista <> nil do

    begin

    inc(cont);

    writeln(' Nodo n§ ',cont);

    aux := lista;

    lista := lista^.prox;

    dispose(aux)

    end

    end;

    Begin

    ClrScr;

    iniciar(cabeza,cola);

    repeat

    write('Introducir número: ');

    readln(numero);

    {Se introduce un número:}

    if numero <> 0 then

    {Si el número es distinto de cero:}

    begin

    encontrado := Buscar(cabeza, numero);

    {Se busca el número en la lista, y se guarda el resultado de la

    búsqueda en el puntero "encontrado".}

    nuevo := creanodo(numero);

    {Se crea el nuevo nodo con el número introducido.}

    if cabeza <> nil

    {Si la lista no est  vacía:}

    then begin

    if encontrado = nil

    {Si la búsqueda fue fallida:}

    then insencola(nuevo)

    {Entonces no hay en la lista ningún número mayor que

    el que ha sido introducido, y habrá  que insertar el

    nuevo nodo en la cola de la lista: El último.}

    else insantes(encontrado, nuevo)

    {Si la búsqueda no fue fallida, "encontrado" apuntar 

    al nodo que almacena el primer número de la lista que

    es mayor que el número introducido, y entonces para que

    la lista est ordenada habrá  que insertar el nuevo

    nodo justo antes que el nodo apuntado por "encontrado". }

    end

    else begin

    {Si la lista estaba vacía, se inicializan cabeza y cola para que

    apunten al nuevo nodo, porque no hay nada que ordenar.}

    cabeza := nuevo;

    cola := nuevo

    end

    end

    else terminar := true

    {Si el número introducido es el cero, se finaliza la introducción

    de números.}

    until terminar;

    writeln;

    writeln('Finalizó la introducción de números.');

    writeln;

    writeln('Pulsa una tecla para continuar ...');

    readkey;

    ClrScr;

    verlista(cabeza);

    {Se visualiza la lista de números para comprobar que est  ordenada.}

    resetMem(cabeza);

    {Se libera la memoria reservada para la lista.}

    writeln;

    writeln('That`s All Folks ...');

    readkey

    end.

    10. Una lista contiene la información de los alumnos de una clase. Hacer un programa que presente un menú:

    1. Nuevo alumno

    2. Borrar alumno

    3. Modificar alumno

    Para cada alumno se mantiene la siguiente información: número, nombre y nota. Los alumnos en la lista están ordenados por número. Si se elige la opción 1 se piden los datos del alumno y se insertan en la posición adecuada. Si se borra un alumno se pide el número de alumno y se elimina de la lista. Modificar un alumno es cambiar el nombre de un número determinado.

    Program t10e10(Input, Output);

    Uses Crt;

    Type alumno = record

    numero: integer;

    nombre: String[35];

    nota: real

    end;

    Pnodo = ^Nodo;

    Nodo = record

    info: alumno;

    prox, ant: Pnodo

    {Lista doblemente enlazada.}

    end;

    Var cabeza, cola: Pnodo;

    salir: boolean;

    Procedure iniciarlista;

    begin

    cabeza := nil;

    cola := nil

    end;

    Function si_no(pregunta: String): Char;

    var oSioNo: Char;

    begin

    pregunta := pregunta + ' [S/N]: ';

    write(pregunta);

    repeat

    osiono := upcase(readkey)

    until osiono in ['S','N'];

    writeln(osiono);

    si_no := oSioNo

    end;

    Function menu: Char;

    {Presenta por pantalla el menú con las opciones disponibles

    y devuelve la opción seleccionada por el usuario.}

    var opcion: Char;

    begin

    ClrScr;

    writeln(' ***** M E N U *****');

    writeln;

    writeln(' 1. Nuevo alumno');

    writeln(' 2. Borrar alumno');

    writeln(' 3. Modificar alumno');

    writeln(' 4. Listado de alumnos');

    writeln;

    writeln(' T. Terminar');

    writeln;

    write (' Selecciona opción: ');

    repeat

    opcion := upcase(readkey)

    until opcion in ['1','2','3','4','T'];

    writeln(opcion);

    menu := opcion

    end;

    Procedure nuevo;

    {Añade una ficha nueva a la lista de alumnos.}

    var ficha: alumno;

    puntaux, encontrado: Pnodo;

    numlibre, correcto: boolean;

    entrada: Char;

    codigo: integer;

    Function creanodo(nuevaficha: alumno): Pnodo;

    var aux: Pnodo;

    begin

    new(aux);

    aux^.info := nuevaficha;

    aux^.prox := nil;

    aux^.ant := nil;

    creanodo := aux

    end;

    Procedure insantes(insertpoint, nuevonodo: Pnodo);

    var aux: Pnodo;

    begin

    aux := insertpoint^.ant;

    if aux <> nil then aux^.prox := nuevonodo;

    if insertpoint^.ant = nil then cabeza := nuevonodo;

    nuevonodo^.ant := insertpoint^.ant;

    nuevonodo^.prox := insertpoint;

    insertpoint^.ant := nuevonodo

    end;

    Procedure insencola(nuevonodo: Pnodo);

    var aux: Pnodo;

    begin

    aux := cola;

    cola := nuevonodo;

    nuevonodo^.ant := aux;

    aux^.prox := nuevonodo

    end;

    Function buscar (lis1:Pnodo;

    num:integer;

    var libre: boolean): Pnodo;

    {Devuelve un puntero apuntando al primer número mayor que

    el buscado en la lista, y de no haber ninguno mayor, apuntar 

    a NIL. Ademá s devuelve en el par metro "libre" de tipo booleano

    TRUE: si el número de alumno no est  siendo utilizado ya,

    y FALSE si el número ya est  ocupado.}

    var puntaux, AUX: Pnodo;

    begin

    puntaux := lis1;

    if lis1 <> nil then

    {Si la lista no est  vacía:}

    begin

    while (puntaux^.info.numero < num) and (puntaux <> nil)

    do puntaux := puntaux^.prox

    {Va saltando de nodo en nodo mientras que el número

    buscado sea mayor que el almacenado en el nodo, o se

    llegue al final de la lista.}

    end;

    if puntaux <> nil

    {Si no se llegó al final de la lista:}

    then begin

    if puntaux^.ant <> nil

    {Si el primer número que ya no es menor que el buscado

    no es el primero de la lista:}

    then begin

    aux := puntaux^.ant;

    {Se guarda un puntero apuntando al nodo anterior.}

    if aux^.info.numero = num then libre := false

    else libre := true

    {Si este nodo (el anterior) contiene el número

    buscado, se asigna FALSE a "libre", y si no

    contiene al número (contendrá  uno menor) entonces

    se asigna TRUE a "libre".}

    end

    else begin

    {Si el primer número de la lista ya no es menor

    que el buscado:}

    if puntaux^.info.numero <> num then libre := true

    {Si no es el número buscado (ser  mayor), entonces

    el número buscado est  libre.}

    end

    end

    else libre := true;

    {Si la lista est  vacía, el número est  libre.}

    buscar := puntaux

    end;

    begin

    ClrScr;

    writeln('****** Nuevo alumno ******');

    writeln;

    repeat

    with ficha do

    begin

    write('Número de ficha: ');

    readln(codigo);

    {Se lee el número de alumno que se desea añadir.}

    encontrado := buscar(cabeza, codigo, numlibre);

    {Se busca el número en la lista.}

    if numlibre then

    {Si el número est  libre:}

    begin

    numero := codigo;

    write('Nombre: ');

    readln(nombre);

    write('Nota: ');

    readln(nota);

    {Se leen los datos correspondientes al alumno.}

    entrada := si_no('¨Los datos son correctos?');

    correcto := (entrada = 'S')

    end

    else begin

    {Si el número est  ocupado:}

    writeln('­ El número ',codigo,' ya est  ocupado: !');

    write('Utilice la OPCION 3 del MENU PRINCIPAL ');

    writeln('si quiere modificar la ficha número ',codigo);

    writeln;

    entrada := si_no('¨Probar con otro número?');

    correcto := (entrada = 'N')

    end;

    writeln

    end

    until correcto;

    writeln;

    if numlibre then

    {Si el número estaba libre:}

    begin

    puntaux := creanodo(ficha);

    {Se crea el nodo con los datos del alumno.}

    if cabeza <> nil

    {Si la lista no est  vacía:}

    then begin

    if encontrado = nil

    {Si la función buscar devuelve NIL, significa que el

    número que se desea introducir es el mayor de los que

    hay ya en la lista:}

    then insencola(puntaux)

    {Entonces se inserta el nuevo nodo al final de la lista.}

    else insantes(encontrado, puntaux)

    {Si la función buscar no devuelve NIL, entonces se

    inserta el nodo en la posición anterior al nodo

    al que apunta el resultado de la búsqueda.}

    end

    else begin

    {Si la lista estaba vacía:}

    cabeza := puntaux;

    cola := puntaux

    {Se asignan los punteros de cabeza y cola de lista apuntando

    al nuevo nodo, ya que el primero no hace falta ordenarlo.}

    end

    end

    end;

    Function buscar(lista: Pnodo; num: integer; var error: boolean): Pnodo;

    {Devuelve un puntero al primer nodo de la lista que contenga

    un número de alumno que no sea menor que el buscado. Si además este

    nodo almacena el número buscado, entonces se devuelve en el

    par metro por referencia el valor FALSE (no ha habido error),

    y si el nodo almacena un número mayor que el buscado, devuelve

    TRUE (si ha habido un error en la búsqueda). }

    var puntaux, AUX: Pnodo;

    begin

    error := true;

    puntaux := lista;

    if lista <> nil

    {Si la lista no est  vacía:}

    then begin

    while (puntaux^.info.numero < num) and (puntaux <> nil)

    do puntaux := puntaux^.prox;

    {Mientras que el nodo almacene un número menor que el

    buscado, va saltando de nodo en nodo a través de la lista,

    hasta que se llegue al final.}

    if puntaux <> nil then

    {Si no se llegó al final de la lista:}

    if puntaux^.info.numero = num

    then error := false

    {Si el número almacenado en el nodo encontrado coincide

    con el número buscado entonces no habrá  habido error.}

    else error := true;

    {Si por el contrario el número no coincide (ser  mayor que

    el número buscado), habrá  habido un error en la búsqueda.}

    end

    else begin

    {Si la lista est  vacía:}

    writeln('No hay ninguna ficha en la lista.');

    error := true

    {Entonces est  claro que el número no est  en la lista

    y habrá  ocurrido un error en la lista.}

    end;

    buscar := puntaux;

    end;

    Procedure borrar;

    {Elimina un alumno de la lista.}

    var codigo: integer;

    seekerror: boolean;

    encontrado: Pnodo;

    Entrada: Char;

    Procedure borrarnodo(punt: Pnodo);

    {Elimina de la lista el nodo al que apunte el puntero par metro.}

    var puntaux: Pnodo;

    begin

    write('Eliminando ... ');

    if punt <> cabeza then

    {Si el nodo a eliminar no es el de cabeza de la lista:}

    begin

    puntaux := punt^.ant;

    puntaux^.prox := punt^.prox

    {Hay que enlazar el nodo anterior con el posterior

    al nodo a eliminar.}

    end

    else cabeza := punt^.prox;

    {Si el nodo a eliminar es el nodo cabeza, el puntero cabeza

    debe apuntar al siguiente nodo en la lista.}

    if punt <> cola then

    {Si el nodo a eliminar no es el último de la lista.}

    begin

    puntaux := punt^.prox;

    puntaux^.ant := punt^.ant

    {Hay que enlazar el nodo posterior con el anterior

    al nodo que se va a eliminar.}

    end

    else cola := punt^.ant;

    {Si el nodo a eliminar es el último de la lista, el puntero

    de cola de la lista ha de apuntar al nodo anterior.}

    dispose(punt);

    {La lista ya est  de nuevo enlazada, y el nodo est  fuera de

    ella, as¡ que se libera la memoria que tenía reservada.}

    writeln;

    writeln('Ficha eliminada!');

    readkey

    end;

    begin

    ClrScr;

    write('Introduce el número de la ficha a eliminar: ');

    readln(codigo);

    writeln;

    encontrado := buscar(cabeza, codigo, seekerror);

    {Buscar el nodo a eliminar.}

    if seekerror then

    {Si el número de ficha buscada no est  en la lista:}

    begin

    writeln('No existe ninguna ficha con el número ',codigo);

    readkey

    end

    else begin

    {Si la ficha buscada ha sido encontrada:}

    writeln('Se ha encontrado la siguiente ficha:');

    writeln;

    writeln('Número: ',encontrado^.info.numero);

    writeln('Nombre: ',encontrado^.info.nombre);

    writeln(' Nota: ',encontrado^.info.nota:5:2);

    writeln;

    entrada := si_no('¨Es esta la ficha buscada?');

    if entrada = 'S' then borrarnodo(encontrado)

    {Si el usuario confirma la eliminación, entonces se

    elimina el nodo.}

    end

    end;

    Procedure modificar;

    {Permite modificar los datos referentes a un alumno cuya ficha

    est en la lista.}

    var codigo: integer;

    ficha: alumno;

    seekerror, correcto: boolean;

    encontrado: Pnodo;

    Entrada: Char;

    begin

    ClrScr;

    write('Introduce el número de la ficha a modificar: ');

    readln(codigo);

    writeln;

    encontrado := buscar(cabeza, codigo, seekerror);

    {Se busca el número de la ficha que se desea modificar.}

    if seekerror then

    begin

    writeln('No existe ninguna ficha con el número ',codigo);

    readkey

    end

    else begin

    {Si se encontró el número buscado en la lista:}

    writeln('Se ha encontrado la siguiente ficha:');

    writeln;

    writeln('Número: ',encontrado^.info.numero);

    writeln('Nombre: ',encontrado^.info.nombre);

    writeln(' Nota: ',encontrado^.info.nota:5:2);

    writeln;

    entrada := si_no('¨Es esta la ficha buscada?');

    writeln;

    if entrada = 'S' then

    {Si el usuario confirma que era la ficha buscada:}

    begin

    repeat

    with ficha do

    begin

    numero := encontrado^.info.numero;

    writeln('Sustituir por:');

    writeln;

    write('Nuevo nombre: ');

    readln(nombre);

    write('Nota: ');

    readln(nota);

    {Se modifican los datos.}

    entrada := si_no('¨Confirma los cambios?');

    correcto := (entrada = 'S')

    end

    until correcto;

    encontrado^.info := ficha;

    {Se sustituyen en la lista los datos modificados

    por los antiguos.}

    writeln;

    writeln('Ficha modificada.');

    readkey;

    end

    end

    end;

    Procedure listar(lista: Pnodo);

    {Visualiza por pantalla el contenido de la lista de alumnos.}

    var cont: integer;

    begin

    ClrScr;

    writeln('******* L I S T A D O D E A L U M N O S *******');

    writeln;

    writeln('Número', 'N O M B R E':25,'Nota':22);

    for cont := 1 to 53 do write('Ä');

    writeln;

    if lista = nil

    then writeln('No hay ningún alumno en la lista.')

    else while lista <> nil do

    {Si la lista no est  vacía, mientras que no se llegue al final:}

    begin

    write(lista^.info.numero:6,' ',lista^.info.nombre);

    write(' ':38-length(lista^.info.nombre));

    writeln(' ':2,lista^.info.nota:5:2);

    {Se muestran los datos del alumno.}

    lista := lista^.prox

    {Se salta al próximo nodo.}

    end;

    writeln;

    write('Pulsa una tecla para regresar al MENU ...');

    readkey;

    writeln

    end;

    Procedure resetMem(lista: Pnodo);

    {Liberar la memoria reservada para la lista.}

    var aux: Pnodo;

    cont: integer;

    begin

    ClrScr;

    cont := 0;

    if lista <> nil then writeln('Liberando la memoria din mica:');

    while lista <> nil do

    begin

    inc(cont);

    writeln(' Nodo n§ ',cont);

    aux := lista;

    lista := lista^.prox;

    dispose(aux)

    end

    end;

    Begin

    ClrScr;

    iniciarlista;

    repeat

    case menu of

    {Llamada a la función menú, y selección en función del

    valor que devuelva.}

    '1': nuevo;

    '2': borrar;

    '3': modificar;

    '4': listar(cabeza);

    'T': salir := true

    end

    until salir;

    writeln;

    resetmem(cabeza);

    {Liberar la memoria reservada para la lista.}

    writeln('That`s All Folks ...');

    readkey

    end.

    12. Generar una lista encadenada con todas las palabras de tres caracteres que aparecen en un fichero de tipo texto. Imprimir dicha lista.

    Program t10e12(Input, Output);

    Uses Crt;

    Const letpal = 3;

    separadores: Set of Char =([' ', ',', '.', ';','(',')', ':',

    '''','?','¨','­','!','[',']','{','}',#13, #10]);

    Type

    Puntero = ^nodo;

    nodo = record

    info: String[letpal];

    enlace: Puntero

    {Lista simplemente enlazada.}

    end;

    Var fichero: Text;

    letra: Char;

    contletras, contpal: integer;

    nombrefic, palabra: String;

    control: boolean;

    cabeza, cola, puntaux: Puntero;

    Procedure iniciar(var lista, cola: Puntero);

    begin

    lista := nil;

    cola := nil

    end;

    Function haznodo(nuevapal: String): Puntero;

    var aux: Puntero;

    begin

    new(aux);

    aux^.info := nuevapal;

    aux^.enlace := nil;

    haznodo := aux

    end;

    Procedure insertar(var lista, cola: Puntero; nuevo: Puntero);

    var aux: Puntero;

    begin

    if lista = nil then

    begin

    lista := nuevo;

    cola := nuevo

    end

    else begin

    aux := cola;

    cola := nuevo;

    aux^.enlace := nuevo

    end

    end;

    Procedure verlista(lista: Puntero);

    {Visualiza la lista de palabras con 3 letras por pantalla.}

    var cont: integer;

    begin

    writeln('As¡ queda la lista:');

    cont := 0;

    while lista <> nil do

    begin

    inc(cont);

    writeln(cont:6,' ',lista^.info);

    if (cont mod 24) = 0 then readkey;

    lista := lista^.enlace

    end;

    writeln;

    readkey

    end;

    Procedure ResetMem(lista: puntero);

    var aux: Puntero;

    cont: integer;

    begin

    ClrScr;

    cont := 0;

    writeln('Liberando la memoria din mica:');

    while lista <> nil do

    begin

    inc(cont);

    writeln('Eliminando nodo n§ ',cont);

    aux := lista;

    lista := lista^.enlace;

    dispose(aux)

    end

    end;

    Begin

    ClrScr;

    contpal := 0;

    contletras := 0;

    write('Nombre del fichero de entrada: ');

    readln(nombrefic);

    if nombrefic = '' then nombrefic := 'c:\tp\bin\temas\tema10\t10dat.txt';

    assign(fichero,nombrefic);

    {$I-}

    reset(fichero);

    {$I+}

    if ioresult <> 0 then

    begin

    writeln('Error en apertura de fichero.!!');

    halt(1)

    end;

    iniciar(cabeza, cola);

    palabra := '';

    control := false;

    while not eof(fichero) do

    begin

    while not eoln(fichero) do

    begin

    read(fichero,letra);

    if not(letra in separadores)

    then begin

    if not control then inc(contpal);

    control := true;

    inc(contletras);

    palabra := palabra + letra

    end

    else begin

    control := false;

    if contletras = letpal then

    {Si la palabra tiene 3 letras: }

    begin

    puntaux := haznodo(palabra);

    {Se crea un nodo que contiene la palabra.}

    insertar(cabeza, cola, puntaux)

    {Se inserta el nodo en la lista.}

    end;

    palabra := '';

    contletras := 0;

    while ((letra in separadores)

    or eoln(fichero)) and not(eof(fichero)) do

    begin

    read(fichero,letra);

    if not(letra in separadores)

    then begin

    inc(contpal);

    inc(contletras);

    palabra := palabra+letra;

    control := true

    end

    end

    end

    end;

    if not eof(fichero) then

    begin

    read(fichero,letra)

    end

    end;

    close(fichero);

    writeln;

    writeln('Total: ',contpal,' palabras.');

    writeln;

    verlista(cabeza);

    resetmem(cabeza);

    writeln;

    writeln('That`s All Folks ...');

    readkey

    end.

    14. Escribir un programa que lea un texto de longitud indeterminada y que produzca como resultado la lista de todas las palabras diferentes contenida en el texto, así como su frecuencia de aparición.

    Program t10e12(Input, Output);

    Uses Crt;

    Const lenpal = 25;

    separadores: Set of Char =([' ', ',', '.', ';','(',')', ':'

    ,'"','&','=','?','¨','­','!','{','}','[',']','''','+','-', #13, #10]);

    Type

    histograma = record

    pal: String[lenpal];

    frec: integer

    end;

    Puntero = ^nodo;

    nodo = record

    info: histograma;

    enlace: Puntero

    {Lista simplemente enlazada.}

    end;

    Var fichero: Text;

    letra: Char;

    contletras, contpal: integer;

    nombrefic, palabra: String;

    control, errorcode: boolean;

    cabeza, cola, puntaux: Puntero;

    Procedure iniciar(var lista, cola: Puntero);

    begin

    lista := nil;

    cola := nil

    end;

    Function haznodo(nuevapal: String): Puntero;

    {Crea un nuevo nodo para almacenar otra palabra y su frecuencia}

    var aux: Puntero;

    begin

    new(aux);

    aux^.info.pal := nuevapal;

    {Guarda la palabra.}

    aux^.info.frec := 1;

    {Como la palabra es nueva, solo ha aparecido una vez.}

    aux^.enlace := nil;

    haznodo := aux

    end;

    Procedure insertar(var lista, cola: Puntero; nuevo: Puntero);

    var aux: Puntero;

    begin

    if lista = nil then

    begin

    lista := nuevo;

    cola := nuevo

    end

    else begin

    aux := cola;

    cola := nuevo;

    aux^.enlace := nuevo

    end

    end;

    Function buscar(lista: Puntero; palabra: String;

    var error: boolean): Puntero;

    {Busca una palabra en la lista, y devuelve un puntero apuntando

    al nodo que contiene la palabra. Si la palabra buscada no se

    encuentra en la lista, devuelve el puntero apuntando a NIL, y un

    valor TRUE en el par metro de control de error.}

    var puntaux: Puntero;

    begin

    error := true;

    {Si la lista est  vacía, siempre ocurrir  un error de búsqueda.}

    puntaux := lista;

    if lista <> nil

    {Si la lista no est  vacía:}

    then begin

    while (puntaux^.info.pal <> palabra) and (puntaux <> nil)

    do puntaux := puntaux^.enlace;

    {Mientras que el nodo no contenga la palabra buscada, y no

    se llegue al final de la lista, se va saltando de nodo en nodo.}

    if puntaux <> nil then

    if puntaux^.info.pal = palabra

    {Si no se llegó al final de la lista, y la palabra

    almacenada en el nodo encontrado coincide con la palabra

    buscada:}

    then error := false

    {Entonces no ha ocurrido un error de búsqueda.}

    else error := true;

    {Si las palabras no coinciden, entonces ha ocurrido

    un error en la búsqueda.}

    end;

    buscar := puntaux;

    end;

    Procedure verlista(lista: Puntero);

    {Visualiza el histograma con las palabras de la lista y

    la frecuencia de aparición de cada una de ellas.}

    var cont, aux: integer;

    begin

    cont := 0;

    {Cuenta el n§ de nodos.}

    ClrScr;

    while lista <> nil do

    {Mientras que no se llegue al final de la lista:}

    begin

    inc(cont);

    {Se incrementa el contador de nodos.}

    write(' ',cont:4,' ',lista^.info.pal,' ');

    {Se escribe la palabra.}

    for aux := 1 to 26-length(lista^.info.pal) do write('.');

    case lista^.info.frec of

    {Dependiendo de la frecuencia de aparición de la palabra

    se selecciona un color distinto.}

    1..4: textcolor(9);

    5..9: textcolor(10);

    10..14: textcolor(11);

    14..19: textcolor(12)

    else textcolor(14)

    end;

    write(lista^.info.frec:3);

    {Se escribe el n§ de veces que aparece la palabra.}

    textcolor(7);

    writeln(' veces.');

    if (cont mod 24) = 0 then readkey; {pausa }

    lista := lista^.enlace

    {Se salta al siguiente nodo.}

    end;

    writeln;

    write('Pulsa una tecla para terminar ...');

    readkey

    end;

    Procedure ResetMem(lista: puntero);

    {Libera la memoria din mica reservada para la lista.}

    var aux: Puntero;

    cont: integer;

    begin

    ClrScr;

    cont := 0;

    writeln('Liberando la memoria din mica:');

    writeln;

    write('Eliminando nodos: (');

    textcolor(9);

    write('#');

    textcolor(7);

    writeln(' = 1 Nodo)');

    writeln;

    textcolor(9);

    while lista <> nil do

    begin

    inc(cont);

    delay(50);

    {aunque tarde un poco más, queda más vistoso}

    write('#');

    if (cont mod 10) = 0 then

    {Los símbolos que representan un nodo, se mostrar n

    en grupos de 10.}

    if (cont mod 50) = 0

    {Cada cinco grupos de 10 nodos, se salta de línea.}

    then writeln

    else begin

    {Los grupos se separan con un guión de color rojo.}

    textcolor(12);

    write('-');

    textcolor(9)

    end;

    aux := lista;

    {Se apunta el nodo con un puntero auxiliar para que no

    quede perdido, sin enlace.}

    lista := lista^.enlace;

    {Se salta al siguiente nodo.}

    dispose(aux)

    {Se libera la memoria reservada para el nodo que ha

    quedado atrás.}

    end;

    textcolor(7);

    writeln;

    writeln(cont,' nodos eliminados.');

    writeln;

    writeln('Memoria liberada.')

    end;

    Begin

    ClrScr;

    contpal := 0;

    contletras := 0;

    writeln('Listar todas las palabras de un archivo de texto');

    writeln('y contar el número de veces que aparece cada una.');

    writeln;

    write('Nombre del fichero de entrada: ');

    readln(nombrefic);

    if nombrefic = '' then nombrefic := 'c:\tp\bin\temas\tema10\t10dat.txt';

    assign(fichero,nombrefic);

    {$I-}

    reset(fichero);

    {$I+}

    if ioresult <> 0 then

    begin

    writeln('Error en apertura de fichero.!!');

    readkey;

    halt(1)

    end;

    iniciar(cabeza, cola);

    palabra := '';

    control := false;

    while not eof(fichero) do

    begin

    while not eoln(fichero) do

    begin

    read(fichero,letra);

    if not(letra in separadores)

    then begin

    if not control then inc(contpal);

    control := true;

    inc(contletras);

    palabra := palabra + letra

    end

    else begin

    {La palabra ha finalizado porque se encontró un separador.}

    control := false;

    puntaux := buscar(cabeza, palabra, errorcode);

    {Se busca la palabra en la lista.}

    if not(errorcode) then

    {Si no ocurrió un error en la búsqueda, quiere decir que

    que la palabra ya est  en la lista:}

    begin

    inc(puntaux^.info.frec)

    {Entonces sólo hay que incrementar el número de veces

    que ha aparecido la palabra.}

    end

    else begin

    {Si ocurre un error en la búsqueda, quiere decir que

    la palabra no estaba en la lista, y habrá  que meterla.}

    puntaux := haznodo(palabra);

    {Se crea el nodo con la palabra.}

    insertar(cabeza, cola, puntaux)

    {Y se inserta en la lista.}

    end;

    palabra := '';

    contletras := 0;

    while ((letra in separadores)

    or eoln(fichero)) and not(eof(fichero)) do

    begin

    read(fichero,letra);

    if not(letra in separadores)

    then begin

    inc(contpal);

    inc(contletras);

    palabra := palabra+letra;

    control := true

    end

    end

    end

    end;

    if not eof(fichero) then

    begin

    read(fichero,letra)

    end

    end;

    close(fichero);

    writeln;

    writeln('Fichero procesado.');

    writeln;

    writeln('Total: ',contpal,' palabras.');

    writeln;

    write('Pulsa una tecla para ver el histograma ...');

    readkey;

    verlista(cabeza);

    {Visualiza el histograma.}

    resetmem(cabeza);

    {Libera la memoria din mica.}

    writeln;

    writeln('That`s All Folks ...');

    readkey

    end.


    Ejercicios tema 11

    2. Hacer un programa con un procedimiento recursivo que tome un string como entrada y lo visualice en orden inverso.

    Program t11e2(Input, Output);

    Uses Crt;

    Var frase: String;

    Procedure verinver(pal: String);

    begin

    if length(pal) >= 1 then

    {Si la longitud de la frase no es cero }

    begin

    write(pal[length(pal)]);

    {Se escribe el último carácter de la frase.}

    delete(pal, length(pal),1);

    {Se elimina de la frase el último carácter.

    El procedimiento delete es propio de Turbo-Pascal.}

    verinver(pal)

    {Se hace la llamada recursiva con la nueva frase

    que ahora tiene un carácter menos de longitud.}

    end

    end;

    Begin

    ClrScr;

    write('Introduce una frase: ');

    readln(frase);

    {Se lee la frase.}

    verinver(frase);

    {Se llama a la función que visualiza la frase en orden inverso.}

    writeln;

    writeln;

    write('Pulsa una tecla para terminar ...');

    readkey

    end.

    4. Comprobar si un String introducido por teclado es un palíndromo (capicúa).

    Program t11e4(Input, Output);

    Uses Crt;

    Var frase: String;

    i: integer;

    Function capicua(pal: String): boolean;

    {Devuelve TRUE si la frase es capicúa y false si no lo es.

    Hay que tener en cuenta que la función distingue entre

    mayúsculas y minúsculas, y no elimina los espacios en blanco

    ni los signos de puntuación, etc. ..., por lo que habrá  que

    controlarlo todo antes de llamar a la función.}

    var aux: boolean;

    begin

    aux := true;

    if length(pal) >= 1 then

    {Si la frase no tiene longitud cero:}

    begin

    if pal[1] = pal[length(pal)]

    {Si la primera letra es igual a la última de la frase:}

    then begin

    delete(pal,1,1);

    delete(pal, length(pal),1);

    {Se eliminan de la frase la primera y la última letra.}

    aux := aux and capicua(pal)

    {Se hace la llamada recursiva con la nueva frase.}

    end

    else aux := false

    {Si la primera y última letra no son iguales, la función

    devuelve FALSE.}

    end;

    capicua := aux

    end;

    Begin

    ClrScr;

    writeln('Introduce una palabra (sin acentos): ');

    write('Por ejemplo: 1331, o 1k11k1, o 0-1-2-1-0 ...:');

    readln(frase);

    for i := 1 to length(frase) do frase[i] := upcase(frase[i]);

    {Pasa todo a mayúsculas.}

    writeln;

    if capicua(frase)

    then writeln('Resultado: CAPICUA.')

    else writeln('Resultado: NO es capicúa.');

    readkey

    end.

    6. Escribir dos funciones, una recursiva y otra no, que dado un valor x entero positivo, retorne true si x es una potencia de 2.

    Program t11e4(Input, Output);

    Uses Crt;

    Var numero, maxiter: integer;

    Function DosalaN(num: integer; var iter: integer): boolean;

    {Función iterativa que devuelve true si el número el potencia

    de 2, y además cuenta el número de iteraciones hasta llegar

    al resultado.}

    var control: boolean;

    begin

    control := true;

    iter := 0;

    while (num > 2) and control do

    {Mientras que el número sea mayor que 2 y divisible por 2: }

    begin

    inc(iter);

    {Se incrementa el número de iteraciones (n§ de veces que

    se ejecuta el bucle).}

    control := control and ((num mod 2) = 0);

    {Ser  true si el número es divisible por 2.}

    num := num div 2

    {Se divide el número por 2.}

    end;

    DosalaN := control

    end;

    Function RecDosalaN(num: integer; var iter: integer): boolean;

    {Función recursiva que devuelve true si el número es potencia de 2.}

    var aux: boolean;

    begin

    aux := true;

    inc(iter);

    {El número de iteraciones en la función recursiva, se cuenta por

    el n§ de veces que es llamada la función, por lo que se incrementa

    cada vez que se ejecute la función.}

    if (num > 2) and (num mod 2 = 0)

    {Si el número es mayor que 2, y divisible por 2:}

    then begin

    num := num div 2;

    {se divide el número por 2.}

    aux := aux and RecDosalaN(num, iter)

    {Se hace la llamada recursiva con el nuevo número.}

    end

    else if num > 2 then aux := false;

    {Si el número no es divisible por dos, la función devuelve FALSE}

    RecDosalaN := aux

    end;

    Begin

    ClrScr;

    write('Introduce un número entero: ');

    readln(numero);

    writeln;

    writeln('-----------------------------------------');

    writeln;

    writeln('Cálculo mediante la función recursiva:');

    maxiter := 0;

    if RecDosalaN(numero, maxiter)

    then write('Resultado: SI')

    else write('Resultado: NO');

    writeln(' es potencia de 2');

    writeln;

    writeln(numero,' = 2 elevado a ',maxiter);

    writeln;

    writeln('Calculado en ',maxiter,' iteraciones.');

    writeln;

    writeln('-----------------------------------------');

    writeln;

    writeln('Cálculo mediante la función NO recursiva:');

    if DosalaN(numero, maxiter)

    then write('Resultado: SI')

    else write('Resultado: NO');

    writeln(' es potencia de 2');

    writeln;

    writeln(numero,' = 2 elevado a ',maxiter + 1);

    writeln;

    writeln('Calculado en ',maxiter,' iteraciones.');

    readkey

    end.

    8. Hacer un programa que calcule la suma de los n primeros números pares y la suma de los n primeros números impares. El número n lo introduce el usuario. Crear dos subprogramas que calculen recursivamente los números pares e impares.

    Program t11e4(Input, Output);

    Uses Crt;

    Var numero: integer;

    Function sumaP(num: integer): longint;

    {Calcula la suma de los n primeros números pares.}

    var sumaparcial: longint;

    begin

    if num > 0

    {Si el número es mayor que cero:}

    then sumaparcial := 2*num + sumaP(num - 1)

    {La suma de los primeros n números pares, ser :

    El número (2*n), que es el n-simo número par, m s

    la suma de los primeros (n-1) números pares.}

    else sumaparcial := 0;

    {La suma de los primeros "cero" números pares, es cero.}

    sumaP := sumaparcial

    end;

    Function sumaI(num: integer): longint;

    {Calcula la suma de los n primeros números impares.}

    var sumaparcial: longint;

    begin

    if num > 0

    {Si el número es mayor que cero:}

    then sumaparcial := (2*num-1) + sumaI(num - 1)

    {La suma de los primeros n números impares, ser :

    El número (2*n-1), que es el n-simo número impar, m s

    la suma de los primeros (n-1) números impares.}

    else sumaparcial := 0;

    {La suma de los primeros "cero" números impares, es cero.}

    sumaI := sumaparcial

    end;

    Begin

    ClrScr;

    write('Introduce un número entero: ');

    readln(numero);

    writeln;

    write('Suma de los primeros ',numero,' números impares: ');

    writeln(sumaI(numero));

    writeln;

    write('Suma de los primeros ',numero,' números pares .: ');

    writeln(sumaP(numero));

    readkey

    end.


    CONCLUSIONES

    Con el presente trabajo se han conseguido los objetivos propuestos, en cuanto que se ha obtenido un nivel de conocimientos sobre técnicas y metodología de programación, superior al exigido por la asignatura, se han desarrollado aspectos de la programación que quedan fuera del alcance específico de ésta, y se han adquirido conocimientos valiosos sobre la herramienta de programación en Pascal de Borland ®, sobre funciones, procedimientos, constantes y variables implementadas en sus unidades, sobre el uso e unidades, sobre el uso del debugger etc...


    BIBLIOGRAFÍA

    • Luis Joyanes Aguilar, Programación en TURBO PASCAL 5.5, 6.0 y 7.0 Madrid, McGraw Hill, 1993.

    • Arthur M. Keller, Programación en Pascal.

    Madrid, McGraw Hill, 1983.

    • Byron S. Gottfried, Programación en Pascal.

    Madrid, McGraw Hill, 1986.

    • M. Alpuente [ y otros ], Fundamentos de programación.

    Valencia, Universidad Politécnica de Valencia, 1986.

    • Stephen K. O'Brien, Steve Nameroff, Turbo Pascal 7, Manual de referencia. Madrid, McGraw Hill, 1993.

    Programación en Turbo Pascal Metodología y técnicas de programación

    Página 82




    Descargar
    Enviado por:Karlitox
    Idioma: castellano
    País: España

    Te va a interesar