Taller de Programación (Pascal)

Glosario TI-Basic Basic Fortran C Prolog Delphi Visual Basic Java JavaScript

Introducción a la computación

Organización básica de una computadora

Definición de computadora

Es un aparato al cual se le proporcionan datos, los computa y nos da un resultado.

Tipos de datos elementales: bits, nibbles, bytes, words

Las computadoras digitales representan los fenómenos a base de dígitos binarios. Dígito binario = binary digit = bit. Puede tomar solo uno de dos valores posibles: 0, 1. A los dígitos binarios se les aplica el álgebra booleana.

La computadora usa voltajes para representar cada bit:

Con un código binario (números binarios) se pueden representar una serie de valores:

	0	0	falso		Dom
	1	1	verdadero		Lun
	2	10			Mar
	3	11			Mie
	4	100			Jue
	5	101			Vie
	6	110			Sab
	7	111
	8	1000
El código ASCCI (American Standar for Information Interchange) es un código binario que representa todos los caracteres, numerales y códigos de control. Usa 8 bits (0 a 255).

	Nibble			4 bits		1/2 Byte
	Palabra de 8 bits		8 bits		1 Byte
	Word (palabra)		16 bits		2 Bytes
	LongWord			32 bits		4 Bytes (DoubleWord)
	QuadWord			64 bits		8 Bytes
Cuando el procesador de una computadora es de n bits, se dice que la computadora maneja datos de n bits.

	PC 386		16 bits
	VAX		32 bits
Complemento de 2 (sistema Nibble):

	bs	b2	b1	b0	Decimal
	0	0	0	0	   0
	0	0	0	1	   1		bs es el bit más significativo
	0	0	1	0	   2		representa el signo.
	0	0	1	1	   3
	0	1	0	0	   4		Por definición -1 equivale
	0	1	0	1	   5		a todos los bits "prendidos"
	0	1	1	0	   6		en cualquier notación.
	0	1	1	1	   7
	1	0	0	0	  -8
	1	0	0	1	  -7		Nibble complemento a 2: [-8,7]
	1	0	1	0	  -6
	1	0	1	1	  -5
	1	1	0	0	  -4
	1	1	0	1	  -3
	1	1	1	0	  -2
	1	1	1	1	  -1
Complemento de 10 (sistema de 4 dígitos):

El complemento 10 de 3564 es:
				9999
			       - 3564
				----
				6435 + 1 = 6436
Así se pueden realizar:

		8642		8642
	       - 3564	==     + 6435
		----		----
		5078	        15078 El primer 1 se pierde porque estamos trabajando en
				     un sistema de 4 dígitos.

Si se suman dos cantidades del mismo signo y el resultado es de signo contrario, se dice que ha ocurrido un sobre flujo (overflow).

Complemento de 2 (sistema Nibble):

	Número 6 en base 10 = Número 110 en base 2

				1111
			       - 0110
				----
				1001 + 1 = 1010

	Número -6 en base 10 = Número 1010 en complemento 2 Nibble
Valores máximos que se pueden representar según los diversos tipos de procesadores:

	Tamaño				Binario		Complemento 2
	4 bits		Nibble		0..15		-8..7
	8 bits		Byte		0..255		-128..127
	16 bits		Word		0..65535		-32768..32767
	32 bits		LongWord		0..2^32-1		-2^31..2^31-1
	64 bits		QuadWord		0..2^64-1		-2^63..2^63-1
	n bits				0..2^n-1		-2^(n-1)..2^(n-1)-1

Componentes de una computadora

Procesador: Funciones y categorías

Unidad central de procesamiento (CPU). Lee, controla y ejecuta las instrucciones que están en memoria.

Memoria: Organización; conceptos de localidad y contenido

Almacén de datos e instrucciones. Su configuración es como un arreglo de localidades, cada celda de memoria es una localidad que almacena un contenido de n dígitos binarios (n es el número de bits que puede manejar el procesador). Una memoria de 64 kilobytes tiene 65536 bytes o 65536 localidades de memoria cada una con n bits.

Un procesador de 16 bits puede direccionar 2^(16-1) = 32768 localidades de memoria, cada una con 16 bits, o sea un total de 524288 bits o 65536 bytes o 64 kb.

Entrada y salida

Es la parte de la computadora que es la interfase entre ella y los dispositivos periféricos.

Dispositivos periféricos

Conceptos básicos para el desarrollo de programas

Programación

Procesos y algoritmos

Proceso: Programa en ejecución, secuencia de acciones ejecutadas por la computadora de acuerdo a las especificaciones dadas por un programa.

Algoritmo: Conjunto finito de reglas las cuales dan una secuencia de operaciones para resolver un problema:

Programa: Secuencia de instrucciones que indican a la computadora qué hacer.

Ejemplos de algoritmos
Calentar una hamburguesa en horno de microondas:
Algoritmo de transformación de base 10 a base 2:

Programas y lenguajes de programación

Programa; Es un texto, secuencia de caracteres, que indica una forma precisa y detallada de lo que se va a hacer. Su significado se indica mediante un formulismo que se conoce como lenguaje.

Lenguaje de programación: Reglas que indican cómo se deben construir los programas. Existen dos categorías: Lenguajes de bajo nivel (de máquina y ensamblador) y lenguajes de alto nivel.

El lenguaje de máquina baja directamente los códigos de máquina de la memoria al CPU, es particular a cada procesador, es difícil de programar para el programador, solo hay portabilidad entre miembros de la misma familia:

El lenguaje ensamblador es una equivalencia directa de cada instrucción de máquina, pero en lugar de usar dígitos binarios usa números nemónicos, no hay congruencia entre los diversos ensambladores. Para cada procesador se necesita su ensamblador, no hay portabilidad, el programador necesita conocer algunas características del procesador.

El lenguaje de alto nivel es un formalismo que definen las reglas para escribir un programa en términos más aproximados a un lenguaje escrito, sin depender de una computadora específica. Sus programas son fáciles de escribir y mantener, no pueden ser traducidos y ejecutados por la máquina directamente, deben ser traducidos a código de máquina mediante un compilador o un intérprete.

No se tiene control del como se compila, los programas son más largos que el código de máquina equivalente. Algunos ejemplos: Fortran, Cobol, Basic, Pascal, Modula 2, C, Ada, etc.

Programación estructurada

Es una técnica de escritura de programas que usa estructuras de datos y estructuras de control. Las estructuras de datos son una representación aproximada de la realidad. Las estructuras de control son secuencias de operaciones con una sola entrada y una sola salida.

Ventajas y desventajas
Ventajas:

Desventajas:

Hardware y Software

Definición de hardware y software

Hardware: Componentes físicos que forman a la computadora. Se suele referir como arquitectura a la estructura interna de la computadora.

Software: Programas que hacen funcional a la computadora.

Firmware: Software en chips tipo ROM.

En el núcleo se encuentra el Hardware de la computadora, alrededor está la arquitectura de la misma (combinación de Firmware y Hardware). En seguida se encuentra el sistema operativo, es un Software que aísla los componentes de la computadora del resto de los programas. Por último se encuentran los programas de aplicación, son el Software con el que se interactúa normalmente.

Clasificación del software

Software del sistema, la computadora virtual
Son funciones esenciales para usar el sistema de cómputo; administra la memoria, fija secuencias de corridas de los programas, transferencias de entrada y salida; Se encuentra el BIOS en esta capa (Basic Input Output System) junto con el sistema operativo. Son una interfase entre el Hardware y el Software de aplicación, hace parecer a la computadora como más poderosa.

Algunos sistemas operativos:

Aplicaciones y utilerías
El software de aplicación son los programas que normalmente usa el usuario: editores, hojas de cálculo, etc.

El software de utilerías son programas de extensión del sistema operativo.

Ciclo de vida del software

La ejecuta y realiza la ingeniería del software:

Herramientas para el desarrollo de programas

Son programas de aplicación, le sirven al programador para la realización de los programas:

Editores, editores orientados a lenguajes
Programas que sirven para la creación o modificación de archivos de texto. Los editores orientados a lenguajes tienen incluida ayuda de sintaxis del lenguaje, inserción abreviada de elementos gramaticales, detección de errores de sintaxis, señalamiento de errores dentro del programa fuente, pueden llamar al compilador, al encadenador, al depurador, etc.

Compiladores y ensambladores
Compilador: Traduce el código de alto nivel al código de máquina, consta de 5 fases:

Intérprete: Programa que lee una instrucción, la traduce y la ejecuta. Se realiza instrucción por instrucción, es fácil de programar.

Ensamblador: Traduce un programa de lenguaje ensamblador a lenguaje de máquina. Genera OBJ o EXE.

Encadenadores
Enlaza un conjunto de módulos compilados o ensamblados separadamente y genera un sólo módulo que puede usar las funciones y los procedimientos de cada módulo, además debe incluir bibliotecas como la del sistema operativo, la de algún lenguaje en particular, las de uso general, y la del usuario.

El cargador es el programa que lee un archivo y lo pone en la memoria para su posterior ejecución, le asigna un espacio en la memoria.

Depuradores (Debugger)
Facilita encontrar errores de lógica de los programas. Da funciones como monitoreo de variables al ejecutar los programas bajo su supervisión.

Todas estas fases se usan en la implantación y mantenimiento de los sistemas.

Aplicación de las herramientas de desarrollo dentro del ciclo de vida del software
		|------>Escribir programa		Editor
		|	fuente
		|		|
		|		|
		|	Traducir a código		compiladores, intérpretes,
		|	de máquina			ensambladores
		|		|
		|		|
		|	Encadenar el archivo		Encadenador
		|	binario
		|		|
		|		|
		|	¿Funciona?----------->Si=Fin	Cargador
		|		|
		|		|
		|	No=Busca errores		Depurador
		|		|
		|------------------

Herramientas para la especificación de sintaxis de lenguajes de programación

La sintaxis son un conjunto de reglas que definen como construir oraciones en un lenguaje. La semántica es el significado de las oraciones.

La semántica se da como una explicación de lo que hace la oración. La sintaxis se especifica mediante dos métodos: EBNF y diagramas de sintaxis.

Notación EBNF Extended Backus Naur Form
Existen dos tipos de símbolos:

Los símbolos se separan con limitadores:

	( ) : Agrupar con fines de clarificación
	[ ] : Parte opcional
	 |  : Seleccionar una opción
	{ } : Repetir 0 o más veces
	 .  : Fin de definición
	 =  : Definición
Regla EBNF: símbolo no terminal = definición.

Ejemplos:

Oración = Sujeto Predicado.
Sujeto = nombre_propio | (artículo sustantivo).
Predicado = Verbo Complemento.
nombre_propio = "Pedro" | "Juan" | "María" | "Rosa".
artículo = "El" | "La".
Verbo = "corre " | "hace" | "ladra" | "come".
Sustantivo = "atleta" | "costurera" | "perro" | "jirafa".
Complemento = "velozmente" | "vestidos finos" | "a los rateros" |
		"hojas de los árboles".
Se pueden crear las siguientes oraciones válidas:

Juan corre velozmente
María come velozmente
el perro hace a los rateros
la jirafa ladra vestidos finos
Todas son sintácticamente correctas, aún cuando no tengan significado semántico. Los errores sintácticos los detecta el compilador. Los errores semánticos son de lógica y se necesita un depurador para encontrarlos.

Otras definiciones:

numero = [signo] entero.
signo = "+" | "-".
entero = digito {digito}.
digito = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9".
real = [signo] entero "." entero.
Diagramas de sintaxis

Ejemplos:

Breve historia de la Vax

PDP-11: Máquina de 16 bits creada por DEC para aplicaciones específicas.
VAX-11: Módulo de expansión de 32 bits para la PDP-11 (VAX=Virtual Address Extension).
VAX: De la VAX-11 evolucionó la VAX que ya no es compatible con la PDP-11, es capaz de direccionar 2^31 direcciones de memoria. Fue la primera en usar el esquema de memoria virtual, es decir, en usar una parte de disco como memoria RAM sin que el CPU se de cuenta. Mientras mas memoria tenga el sistema (memoria física RAM, no virtual en disco) será mas rápido.

Utiliza un sistema operativo especial VMS (Virtual Memory System) que es el encargado de asignar la memoria al disco:

VAX/VMS: Sólo corre en VAX.
OPEN VMS: Corre en VAX y en ALPHA.

ALPHA: Sustituirá a la VAX ya que es capaz de correr múltiples sistemas operativos: OPEN VMS, Windows NT y OSF/1 (Unix estándar).

Características del VMS

Cada módulo es un nodo, los servidores son nodos y las terminales no.

Los "terminal service" también son servidores cuya única función es la de conectar a los nodos:

UserName> Pide el nombre de usuario del "terminal service", usualmente con dar enter es suficiente.
Local> Indicativo de que ya estamos "loggeados" en el "terminal service".

Para conectar a un nodo desde el "terminal service":
Local>connect nodo

Ejemplo: Local>connect UIMXC

Pide UserName y Password. Si falla 3 veces te regresa a Local>. Si te equivocas 4 veces seguidas en una cuenta cancela el password de la cuenta.

Si es exitosa responde con UIMX1>> o UIMX2>> (están en clúster por lo que cualquiera puede contestar).

Nombre de dispositivo

nodo::dispositivo:[directorio.subdir.subdir]archivo.extension;version

Ejemplos:
UIMX1::Disco2:[batman.villanos]gatubela.crimenes;65
UIMX2::Disco0:
IME01::sys$sysdevice:

El último ejemplo corresponde al disco que contiene el sistema operativo.

El nodo tiene un máximo de 6 caracteres. El dispositivo tiene un máximo de 32.

Normalmente sys$login es el directorio que se asigna como directorio "home" de una cuenta. El archivo Login.com es el equivalente al autoexec.bat del MS-DOS.

Comandos

F-5: Salir al modo local, es mejor usar Logout.
Ctrl-Z o F-10: Salir de un programa.
Ctrl-C: Cancela la ejecución de un programa.
Ctrl-Y o F-6: Aborta la ejecución de un programa.

$ es el nodo en el que nos encontramos.

Para mostrar el contenido de un archivo:
$Type archivo.lis

Para salir a modo local (Terminal service)
$Logout

Despliega los archivos del directorio:
$Directory
$Dir /size
$Dir *.pas

Despliega el nombre del directorio actual:
$Show default

Cambia al directorio especificado:
$Set default dispositivo:[directorio.subdirectorio...]

Cambia al directorio "raíz":
$Set default sys%login

Cambia al subdirectorio que esté debajo del directorio en uso:
$Set default [.subdirectorio]

Mueve al directorio superior:
$Set default [-]

Copia un archivo:
$Copy origen destino

Borra un archivo:
$Delete archivo;version

Borra pidiendo confirmación:
$Delete /query *.*;*

Borra y despliega los nombres de los archivos borrados:
$Delete *.*;* /log

Borra las versiones antiguas de los archivos:
$Purge

Borra y despliega los nombres de las versiones antiguas de los archivos
$Purge /log

Borra todas excepto las últimas 2 versiones:
$Purge /keep=2

Para llamar al editor:
$eve archivo.pas
La ayuda se invoca con "PGF 2", para salir usar Ctrl-Z

Comandos dentro del Editor:

Para llamar al compilador:
$Pascal archivo.pas
Se generará un archivo .obj

Para encadenar:
$Link archivo.obj
Se generará un archivo .exe

Para correrlo:
$RUN archivo.exe

Para el debugger:
$Pascal /nooptimize /debug archivo.pas
$Link /debug archivo.obj
$Run archivo.exe

Pascal

Tesis de doctorado de Nicklaus Wirth, diseñado para aplicaciones didácticas.

Dos versiones principales: ANSI (American National Standars Institute) e ISO (International Standar Organization).

En lo sucesivo se manejará el Extended Pascal compatible con ANSI y con ISO usando el compilador VAX-Pascal.

Conceptos básicos de programación estructurada

Notación y conceptos fundamentales

El vocabulario del lenguaje

Consiste en palabras, oraciones y signos de puntuación conformados por números, letras y caracteres especiales. No reconoce diferencias entre mayúsculas y minúsculas.

Palabras (26 letras y dígitos)
Cantidades (dígitos)
Signos de puntuación (símbolos especiales)

Símbolo especial = "+" | "-" | "*" | "/" | "=" | "<>" | "<" | ">" | "<=" | ">=" | "(" | ")" | "[" | "]" | ":=" | "." | "," | ":" | ";" | ".." | "'" | "^".

Palabras reservadas = "DIV" | "MOD" | "NIL" | "IN" | "OR" | "OR_ELSE" | "AND" | "AND_THEN" | "NOT" | "IF" | "THEN" | "ELSE" | "CASE" | "OF" | "OTHERWISE" | "REPEAT" | "UNTIL" | "WHILE" | "DO" | "FOR" | "TO" | "DOWNTO" | "BEGIN" | "END" | "WITH" | "GOTO" | "CONST" | "VAR" | "VALUE" | "TYPE" | "ARRAY" | "RECORD" | "SET" | "FILE" | "FUNCTION" | "PROCEDURE" | "LABEL" | "PACKED" | "PROGRAM" | "MODULE".

Las palabras reservadas no se pueden redefinir.

Palabras predefinidas: Funciones y procedimientos predefinidas en el lenguaje: ReadLn, WriteLn, Sin, Card; no se pueden redefinir.

Palabras de usuario: Funciones y procedimientos definidas por el programador.

Identificadores

Cadenas y comentarios

Cadena: Cualquier secuencia de caracteres encerrados entre apóstrofes.

String=Cadena = "'" {Cualquier_caracter_excepto_apóstrofo | "''"}"'".

cadena vacía = ''.

McDonald's = 'McDonald''s'.

Comentario: Cualquier texto libre encerrado entre llaves.

{Cálculo del impuesto} o (*Total de ventas del año*).
Dentro del comentario no puede haber más signos de comentario. Puede tener saltos de línea.

Estructura básica de un programa

Un ejemplo de programa:

PROGRAM NoHaceNada(Input, Output);
.
Otro ejemplo:

PROGRAM InutilPeroMasLargo(Input,Output);
BEGIN
;
;;
END.

Representación de valores simples

Tipos simples: operadores y funciones estándar

Enteros

Integer: va de -MaxInt a MaxInt. En la VAX MaxInt=2^31-1.

Operador	Operación
   +		Suma
   -		Resta
   *		Multiplicación
   DIV		División entera
   MOD		Módulo o residuo
El módulo entre un número positivo y otro negativo no está definido.

Funciones:

Abs	Valor absoluto
Sqr	Cuadrado
Succ	Sucesor
Pred	Predecesor

Reales

Reales válidos: 3.75 -11.64 0.74 5.0 7.14E24
Reales inválidos: 5. .743

Operador	Operación
   +		Suma
   -		Resta
   *		Multiplicación
   /		División real
Funciones:
Abs	Valor absoluto
Sqr	Cuadrado
Ln	Logaritmo
Sin	Seno
Cos	Coseno
Arctan	Arcotangente
Funciones de conversión
Trunc(X)	Trunca a la parte entera
Round(X)	Redondea al entero

Caracteres

Se usará el ASCII de 8 bits con 255 caracteres (no todos son visibles).

Tipo Char 'a' 'b' '5'
Dobles comillas representan el caracter comilla: '''' = '

Operador	Operación
   +		Concatenación
'H' + 'O' + 'L' + 'A' = 'HOLA' Char+Char+Char+Char=String

Funciones:

Chr(n)	Convierte un entero a caracter
Ord(c)	Convierte un caracter a entero
Pred(c)	Predecesor del caracter c
Succ(c)	Sucesor del caracter c
Chr(Ord('M')-Ord('A')+Ord('a'))='m'

Boléanos

Operador	Operación
   =		Igualdad
   <>		Distinto
   <		Menor
   <=		Menor o igual
   >		Mayor
   >=		Mayor o igual
Funciones:
Ord(False) = 0
Ord(True) = 1
Succ(False) = True
Succ(True) = False
	p	q	p=q	p<=q	p<>q
	F	F	 F	 T	 F
	F	T	 F	 T	 T
	T	F	 F	 F	 T
	T	T	 T	 F	 F

Enumeradores

Subrangos

Declaraciones de datos

Definición de constantes

Definición de tipos

Esquemas y esquemas de subrangos

Definición de esquema
Un esquema es un patrón que sirve como base para definir familias de tipos distintos. Una definición de un tipo de esquema contiene uno o más discriminantes formales, que se ponen en lugar de los límites de un subrango o de los rótulos de los selectores de la parte variante de un registro. Cuando los límites de los índices de un tipo arreglo o de los valores posibles de un tipo conjunto contienen discriminantes, el arreglo o el conjunto se convierten a su vez en esquemas.

Al especificarse valores a los límites o a los rótulos de un tipo basado en un esquema, se construye un tipo válido; a estos valores se les conoce como discriminantes reales.

Un esquema se define como sigue:

esquema = identificador-de-esquema "(" lista-de-discriminantes-formales ")" "=" tipo.
lista-de-discriminantes-formales = discriminante-formal {"," discriminante-formal}.
discriminante-formal = lista-de-identificadores ":" tipo-ordinal.
El tipo puede ser subrango, arreglo, registro o conjunto, mientras que el tipo-ordinal puede ser entero, carácter, booleano, enumerado o subrango.

Ejemplos:

TYPE
	diasDeLaSemana = (lunes, martes, miercoles, jueves, viernes, sabado, domingo);
	rangoDeDias = lunes..domingo;
	arregloDeDias (supD: Integer) = ARRAY [1..supD] OF diasDeLaSemana;
	arregloDeHorasEnteras (infE, supE: rangoDeDias) = 
		ARRAY [infE..supE] OF Integer;
	matrizDeReales (maxCol, maxRen: Integer) =
		ARRAY [1..maxRen, 1..maxCol] OF Real;
	conjuntoDeCaracteres (minCar, maxCar: Char) = SET OF
		(minCar..maxCar);
Comentarios sobre los ejemplos:

Las definiciones anteriores no son tipos válidos hasta que no se especifiquen los discriminantes reales que delimiten los índices de los subrangos. A estos esquemas se les conoce como esquemas indiscriminados, ya que sólo contienen discriminantes formales, y no se les ha determinado su tamaño real. Un esquema indiscriminado sólo puede definirse en una parte de definiciones de tipos, y ser referido por un puntero que apunte al esquema, aunque no esté discriminado, o como parámetro formal de un procedimiento o función.

Discriminantes formales y reales
Restricciones de VAX Pascal
El estándar permite que un tipo esquema discriminado ordinal sea subsecuentemente utilizado como el tipo de un discriminante formal de otro esquema. Por ejemplo:

TYPE
	subrango(inf,sup: Integer) = inf..sup;
	subDiscriminado = subrango(-maxInt - 1, maxInt);
	esquema1(discr: SubDiscriminado) = ARRAY[1..discr] OF Integer;
	esquema2(discr: subDiscriminado) = RECORD
						CASE discr OF
						1 : (num:Integer);
						2 : (letra:Char)
					END;
VAX Pascal no soporta este tipo de construcción.

El Pascal extendido permite que un archivo tenga componentes esquemáticos indiscriminados. VAX Pascal requiere que el tamaño de los componentes se conozca al tiempo de compilación.

Pascal extendido permite que un discriminante formal se utilice para dar valor inicial a una de las componentes del esquema. Por ejemplo:

TYPE
	registro(discr: Integer) = RECORD
					num:Integer VALUE discr;
				END;
	arreglo(discr: Integer) = ARRAY [1..dicr] OF Integer
					VALUE [OTHERWISE discr];
VAX Pascal no soporta estos tipos de construcción y requiere que todas las inicializaciones de valor se conozcan al tiempo de compilación.

Familias de esquemas
Los esquemas indiscriminados no tienen mayor utilidad que la de servir de patrón en la definición de tipos, constantes, variables y parámetros, y para esto, los esquemas deben discriminarse proporcionando valores reales a los discriminantes formales, como en los siguientes ejemplos:

VAR
	algunosDias: arregloDeDias (12);
	horasTrabajadas: arregloDeHorasEnteras (lunes, viernes);
	horasDeEntretenimiento: arregloDeHorasEnteras (sabado, domingo);
	matriz4x5: matrizDeReales (4,5);
	matriz5x4: matrizDeReales (5,4);
Comentarios sobre los ejemplos:

Las declaraciones anteriores determinan el tamaño de las variables en función a discriminantes reales, por lo que se conocen como esquemas discriminados. Estos esquemas pueden aparecer en la parte de definición de tipos o en la de declaración de variables. El discriminante real puede evaluarse en tiempo de compilación (como en los ejemplos anteriores), o durante la corrida, a partir de una expresión que haya sido o pueda ser evaluada en el momento en que se encuentra la declaración.

Para obtener el tamaño (en número de elementos, no en bytes) de un esquema discriminado, se puede emplear el discriminante formal en forma semejante a los designadores de los campos de un registro, especificando el nombre de la variable, un punto, y el identificador del discriminante, como sigue:

WriteLn ('Las dimensiones de la matriz son: ', matriz4x5.maxRen:4, matriz5x4.maxCol:4);

Un tipo esquema indiscriminado y los tipos discriminados que de él se derivan se conocen como una familia de esquemas. Dos esquemas discriminados que tienen discriminantes iguales y determinados como expresiones constantes se consideran tipos iguales. No se pueden hacer asignaciones entre tipos desiguales, aunque sean de la misma familia de esquemas. Por ejemplo:

TYPE
	arregloDeEnteros (infE, supE: Integer) = ARRAY [infE..supE] OF Integer;
	arreglo1 = arregloDeEnteros(5,15);
	arreglo2 = arregloDeEnteros(1,10);
	arreglo3 = arregloDeEnteros(5,15);
"arreglo1", "arreglo2" y "arreglo3" son esquemas discriminados que forman una familia junto con el esquema indiscriminado "arregloDeEnteros". "arreglo1" y "arreglo3" son iguales, por lo que se pueden hacer asignaciones entre ellos.

Como se indicó anteriormente, un esquema indiscriminado puede especificarse como tipo de un parámetro formal de un procedimiento o función, por ejemplo:

PROCEDURE sumaDeMatrices ( matrizA, matrizB: matrizDeReales;
	VAR matrizC: matrizDeReales);
VAR
	i,j: Integer;
BEGIN {sumaDeMatrices}
	FOR i:=1 TO matrizA.maxRen DO
		FOR j:=1 TO matrizA.maxCol DO
			matrizC [i,j] := matrizA [i,j] + matrizB [i,j]
END {sumaDeMatrices};
Al procedimiento del ejemplo anterior se le pueden pasar como parámetros cualquier tipo derivado de "matrizDeReales", siempre y cuando las tres matrices sean de las mismas dimensiones. El resultado de una función sólo puede ser un esquema discriminado.

Para poder utilizar un procedimiento como el anterior, es necesario pasarle como parámetros variables discriminadas, por ejemplo:

TYPE
	matriz2x3 = matriz(2,3);
VAR
	matrizA : matriz2x3 VALUE [1: [1:12, 2:3.45, 3:-12.6];
				2: [1:6, 2:0; 3:-3.3]];
	matrizB : matriz2x3 VALUE [OTHERWISE [OTHERWISE 1]]; {matriz llena de 1}
BEGIN
	sumaDeMatrices (matrizA, matrizB, matrizC);
	...
En todos los ejemplos de esquemas anteriores, el discriminante se evalúa a partir de constantes, por lo que el tamaño de las variables es determinado durante el tiempo de compilación. Pascal extendido permite, como se indicó previamente, definir el tamaño de las variables hasta el momento en que se ejecute el programa, lo cual se hace generalmente mediante el uso de funciones. Supóngase que se hacen las siguientes declaraciones:

TYPE
	matrizDeReales (maxRen, maxCol: Integer) = ARRAY [1..maxRen, 1..maxCol] Of Real;

FUNCTION limiteSuperior (limite: PACKED ARRAY [inf..sup: Integer] OF Char): Integer;
VAR
	num: Integer;
BEGIN
	Write ('Número máximo de ', limite, '>> ');
	Readln(num);
	limiteSuperior:=num
END;

VAR
	matrizNxM: matrizDeReales (limiteSuperior('columnas'), limiteSuperior('renglones') );

La función "limiteSuperior" solicita el número máximo de renglones o columnas, dependiendo del parámetro "limite", el cual es una cadena de caracteres, y entrega como resultado el número entero ingresado por el usuario. En la declaración de la "matrizNxM", los discriminadores "maxRen" y "MaxCol" no se determinan en función a constantes, sino a llamadas a la función "limiteSuperior", la cual debe entregar el número máximo de renglones y el de columnas según los determine el usuario al momento de ejecutarse el programa, para cada discriminante. Nótese que el estándar de Pascal extendido permite insertar una definición de función antes de una declaración de variables, lo cual es necesario para poder designar discriminantes reales al momento de iniciarse la ejecución del programa.

El tipo de un esquema puede a su vez ser otro esquema, siempre y cuando éste sea discriminado con valores conocidos en el tiempo de compilación. Esto es, es inválido definir un esquema indiscriminado que tenga como base un esquema indiscriminado al tiempo de compilación.

Cuando un discriminante formal se usa como el rótulo de la parte variante de un registro, es ilegal cambiar la variante una vez que la variable se ha creado. Por ejemplo:

TYPE
	reg(discr:Integer) = RECORD
				CASE discr OF
					1: (num: Integer);
					2: (letras PACKED ARRAY [1..6] OF Char)
				END;
VAR
	miReg: reg(1); {se discrimina con la variante 1}
BEGIN
	miReg.letras:='ilegal'; {ES ilegal, pues cambia variantes de 1 a 2}
END.

Variables

Declaración
Inicialización
El estándar de Pascal extendido (aún en revisión) soporta inicialización de variables (o de todas las variables pertenecientes a un tipo) de la siguiente manera:

TYPE
	diasDeLaSemana = (domingo, lunes, martes, miercoles, jueves, viernes, sabado);
	contador = Integer VALUE 1; {el tipo no se inicializa, sino que
					las variables que se declaren de este
					tipo se inicializan en 1}
VAR
	impuesto: Real VALUE 10;
	diaLaboral: diasDeLaSemana VALUE lunes;
	i, j: contador; {se inicializan en 1}
El compilador VAX Pascal sigue soportando la inicialización con el operador de asignación (i.e., impuesto: Real:=10), pero no se considera estándar.

Para dar un valor estructurado a una constante, se requiere conocer el tipo del valor, antes de definir la constante. Esto significa que debe haber una parte de definición de tipos antes de la de constantes. En consecuencia, el Pascal extendido permite romper el rígido esquema original de la parte de declaraciones, pudiéndose escribir las secciones en cualquier orden. Sin embargo, siempre es conveniente seguir el orden tradicional, y añadir subsecuentes secciones de definiciones de constantes estructuradas después de la de tipos, sólo cuando sea necesario.

Para dar un valor inicial a una constante o variable estructurada, es necesario definir un constructor con todos los valores posibles para el tipo.

Unicidad y orden de las definiciones de identificadores

Enunciados, expresiones y asignaciones, entrada y salida de datos

Enunciados

Expresiones

El enunciado de asignación

Acceso a la aplicación, mecanismos simples de entrada y salida de datos

Flujo de control de datos

Enunciados compuestos

Enunciados de repetición

El enunciado FOR

El enunciado WHILE

El enunciado REPEAT

Enunciados condicionales

El enunciado IF

El enunciado CASE

Procedimientos y funciones

Procedimientos y concepto de abstracción

Estructura de bloque y alcance de variables

Parámetros

Parámetros reales y formales

Parámetros de valor

Parámetros variables

Funciones y efectos colaterales

Conceptos avanzados de programación estructurada

Tipos estructurados de datos

Arreglos

Concepto de arreglo

Operaciones con arreglos

Constructores de arreglos

El constructor de arreglos se define como sigue:

constructor-de-arreglo=[tipo] "["(lista-de-valores ["OTHERWISE" valor]) | ("OTHERWISE" valor) "]".
lista-de-valores=valor-de-componentes{";" valor-de-componentes}.
valor-de-componentes=lista-de-componentes ";" valor.
lista-de-componentes=componente {";" componente}.
componente=indice | (indice ".." indice).
valor=expresion-constante | constructor.
El "tipo" del constructor sólo es necesario en definiciones de constantes (para asignarle un tipo a la constante), y al asignarle a una variable estructurada un constructor dentro de la parte de enunciados. En el caso de dar valor inicial en la declaración de una variable con VALUE, no se debe poner el tipo, dado que ya se proporciona en la misma declaración al designar el tipo de la variable, antes de la palabra VALUE. Cuando se aniden suscriptores (sean de arreglos o de registros), sólo debe ponerse el tipo antes del corchete más externo, pero nunca antes de los descriptores anidados.

El "valor" puede ser una expresión constante o identificador de constante (evaluable en el tiempo de compilación), o si el arreglo es multidimensional o contiene registros o conjuntos, puede ser otro constructor. Si el constructor aparece en la parte de enunciados, el valor puede ser cualquier expresión (evaluable en tiempo de ejecución), siempre y cuando contenga variables que ya tengan un valor asignado.

Los valores pueden darse en cualquier orden, pero deben inicializarse todos. Para ello puede utilizarse la cláusula OTHERWISE (permitida en el estándar de Pascal extendido).

Ejemplos:

CONST
	uno = 1;
	nombreSuperHeroe = 'Batman';
TYPE
	vector = ARRAY [1..5] of Real;
	matriz = ARRAY [1..5, 1..5] of Integer;
	nombre = PACKED ARRAY [1..10] of Char;
	lista = ARRAY ['a'..'d'] of nombre;
CONST {nótese que se permite otra vez}
	primeros5Primos = vector [1:1; 2:2; 3:3; 4:5; 5:7];
	matrizUnitaria = matriz [1: [1: uno; OTHERWISE 0];
					2:[2:uno; OTHERWISE 0];
                                        3:[3:uno; OTHERWISE 0];
                                        4:[4:uno; OTHERWISE 0];
                                        5:[5:uno; OTHERWISE 0]];
VAR
	listaDeNombres: lista VALUE ['a':'Ana';
					'b':'Benito';
					'c': [1: 'C'; 2: 'a'; 3: 'r'; 4:'l';
						5: 'o'; 6: 's'; OTHERWISE ' '];
					'd': nombreSuperHeroe];
	matrizA, matrizB: matriz;
	elemento: Integer VALUE 15;
	vectorA, vectorB: vector;
BEGIN
	vectorA:= primeros5Primos;
	vectorB:= vector[1: elemento; 3: elemento / 3;  5: elemento / 5; OTHERWISE 0];
	matrizA:= matrizUnitaria; {no se requiere tipo, ya que lo tiene el descriptor}
	matrizB:= matriz[1, 3, 5: [1..2:10; 3: 0; 4..5: -10];
				OTHERWISE [OTHERWISE 0]];

Arreglos empacados

Arreglos empacados de caracteres

Esquemas de arreglos

Definición de esquemas de arreglos
Esquemas como parámetros de procedimientos y funciones
Esquemas discriminados al tiempo de ejecución del programa

Cadenas

Definición y propiedades de las cadenas
Una categoría especial de esquemas es "String", la cual está definida como una estructura semejante a la siguiente:

String ( Capacity: Integer ) = RECORD
				length: 0..65535;
				body: PACKED ARRAY[1..Capacity] OF Char
				END;
En el estándar de Pascal extendido, los campos "length" y "body" no son accesibles directamente. Asimismo, "Capacity" es un entero entre 0 y 65,535, que delimita el tamaño máximo de la cadena. Un "String" de capacidad 0 es una cadena vacía ('').

En el caso especial de VAX Pascal, el "String" se define de distinta forma:

String ( Capacity: Integer ) = VARYING [Capacity] of Char;

por lo que es un superconjunto del tipo no estándar VARYING, el cual a su vez es un superconjunto de un PACKED ARRAY OF Char.

La capacidad de un "String" no necesariamente representa el número de caracteres que contiene. A diferencia de un arreglo empacado de caracteres, cuando a un "String" se le asigna una cadena más corta que su capacidad, no se completa con espacios. El identificador predefinido "Capacity" da la longitud máxima que puede tener un "String", y no el número de caracteres que realmente contiene. Para obtener el número real de caracteres que contiene la cadena, puede usarse la función "Length".

Ejemplos:

TYPE
	nombre = String (40);
	nulo = String (0);
VAR
	elNombre: nombre;

BEGIN
	elNombre:='Bruno Diaz';
	WriteLn( elNombre.Capacity ); {Escribe un 40}
	WriteLn( Length( elNombre ) ) {Escribe un 10}
END.
Constructores de cadenas
Operadores y funciones asociadas a las cadenas
El estándar de Pascal extendido define los siguientes operadores y funciones para el tipo "String" (y también para el "VARYING"):

Operadores:

	+	concatenación	'buen' + 'día'		'buen dia'
	=	igualdad	'salida' = 'salida'	True
	<>	desigualdad	'salida' <> 'salida'	False
	<	menor que	'ola' < 'olla'		True
	<=	menor o igual	'ola' <= 'arena'	False
	>	mayor		'libro' > 'libro'	False
	>=	mayor o igual	'libro' >= 'libro'	True
Funciones:

	Eq	igual		Eq('libro','libro ')	False
	NE	no es igual	NE('carta','Carta')	True
	LT	menor que	LT('sal','saco')	False
	LE	menor o igual	LE('sali','saco')	False
	GT	mayor que	GT('sali'.'saco')	True
	GE	mayor o igual	GE('salida','saladas')	True
El operador de concatenación puede tener como términos de la expresión caracteres, arreglos empacados de caracteres, "Varyings" y "Strings", pero solo puede entregar como resultado un "Varying" o un "String".

Los operadores comparativos pueden utilizarse con cualquier tipo de cadena, tal como se utilizan con los arreglos empacados de caracteres. Si se comparan dos cadenas de longitud distinta, se completa con espacios a la derecha la cadena mas corta. Si las cadenas contienen signos de acentuación o eñes, la comparación se hace respecto a su valor en el código de caracteres que se esté empleando. Por lo general, los caracteres acentuados tienen un valor superior al de los caracteres no acentuados. Por ejemplo:

'almacén' < 'almacenes' genera False
'aorta' >= 'año'	genera False
Las funciones de comparación son equivalentes a los operadores, con la diferencia de que son más eficientes al comparar en función de la longitud de la cadena más corta, sin completar con espacios para igualar longitudes. El primer parámetro equivale a la cadena de la izquierda del operador, y el segundo al de la derecha.

Asimismo, si las cadenas contienen signos de acentuación, la comparación se hace respecto a las letras no acentuadas, y si contienen eñes, respecto a su orden en el alfabeto. Por ejemplo:

LT('alamcén','almacenes')	genera True
GE('aorta','año')		genera True
Otras funciones definidas en el estándar extendido son:

	Index(cadena,texto)	Index('buen día','día')		6
Entrega un entero con el índice donde se encuentra un texto en una cadena.

	Length(cadena)		Length('buen día')		8
Entrega un entero con el número de caracteres en la cadena.

	Substr(cadena, inicio, numCaracteres)
				Substr('buen día', 6, 3)	'día'
Entrega una subcadena a partir de la cadena, desde el carácter de inicio y
	con una longitud de numCaracteres.

Registros

Concepto de registro

El enunciado WITH

Constructores de registros

El constructor de registros se define como sigue:

constructor-de-registro = [tipo] "[" (constructor-fijo
	{";" constructor-fijo} [";" constructor-variante])
	| constructor-variante [";" "OTHERWISE Zero"] "]".
constructor-fijo = valor-de-seccion {";" valor-de-seccion}.
valor-de-seccion = lista-de-identificadores ";" valor.
lista-de-identificadores = identificador {";" identificador}.
constructor-variante = "CASE" [identificador-de-rotulo ":"] valor-de-rotulo 
	"OF" "[" valor-de-componentes {";" valor-de-componentes} "]".
El "tipo" del constructor sólo es necesario en definiciones de constantes (para darle un tipo a la constante), y al asignarle a una variable estructurada un constructor dentro de la parte de enunciados. En el caso de dar valor inicial en la declaración de una variable con VALUE, no se debe poner el tipo, dado que ya se proporciona en la misma declaración al designar el tipo de la variable, antes de la palabra VALUE. Cuando se aniden descriptores (sean de arreglos o de registros), sólo debe ponerse el tipo antes del corchete más externo, pero nunca antes de los descriptores anidados.

El valor-de-seccion de la parte fija puede contener identificadores de la parte variante, siempre y cuando no haya duplicidad entre distintas variantes.

El "valor" puede ser una expresión constante o identificador de constante (evaluable en el tiempo de compilación), o si el registro contiene arreglos, conjuntos u otros registros, puede ser otro constructor. Si el constructor aparee en la parte de enunciados, el valor puede ser cualquier expresión (evaluable en tiempo de ejecución), siempre y cuando contenga variables que ya tengan un valor asignado.

El identificador-de-rotulo sólo es necesario si se incluye uno en la definición de la parte variante del tipo.

El valor-de-rotulo indica cuál de las variantes posibles es la que se va a inicializar.

Los valores pueden darse en cualquier orden, pero deben inicializarse todos. Para ello puede utilizarse la cláusula "OTHERWISE Zero" la cual es propia de VAX Pascal, y no forma parte del estándar de Pascal extendido. La función "Zero", que inicializa variables de casi cualquier tipo a un valor nulo, tampoco está definida en el estándar.

TYPE
	mesesDelAno = (enero, febrero, marzo, abril, mayo, junio, julio, agosto, septiembre,
			octubre, noviembre, diciembre);
	fecha = RECORD
			dia: 1..31;
			mes: mesesDelAno;
			ano: Integer;
		END;
	nombreDePersona = PACKED ARRAY [1..30] OF Char;
	sexo = (masculino, femenino);
	calificacionesPorSemestre = PACKED ARRAY [1..12] OF Integer;
	registroDeAlumno = RECORD
				numCuenta: Integer;
				nombre: nombreDePersona;
				edad: Integer;
				suSexo: sexo;
				calificaciones: calificacionesPorSemestre;
				CASE primerIngreso: Boolean OF
					false: (promedioCarrera: Real);
					true: (prepa: PACKED ARRAY [1..20] OF Char;
						promedioPrepa: Real)
				END;
CONST
	descubrimientoDeAmerica = fecha [dia: 12; mes: octubre; ano: 1492];
VAR
	alumno: registroDeAlumno;
BEGIN
	alumno:= registroDeAlumno[
			numCuenta: 54321;
			nombre: 'Trinito Tolueno';
			edad: 22;
			suSexo: masculino;
			calificaciones: [1: 10; 2: 9; 3: 8; 4: 8; 5: 9; 6: 5; OTHERWISE -1];
						{no cursado aún}
			CASE primerIngreso: False OF [promedioCarrera: 8.2]];

Registros empacados

Manipulación del tiempo
Pascal extendido incluye una estructura estándar para la manipulación del tiempo, la cual se define como sigue:

TimeStamp = PACKED RECORD
		DateValid, TimeValid: Boolean;
		Year: Integer;
		Month: 1..12;
		Day: 1..31;
		Hour: 0..23;
		Minute: 0..59;
		Second:	0..59
		END;
VAX Pascal entiende la estructura anterior como sigue:

TimeStamp = PACKED RECORD
		DateValid, TimeValid: Boolean;
		Year: Integer;
		Month: 1..12;
		Day: 1..31;
		Hour: 0..23;
		Minute: 0..59;
		Second:	0..59;
		Hundredth: 0..999;
		Binary_time[Quad] RECORD L1, L2 : Integer END;
			{Tiempo binario VMS de 32 bits}
		Day_Of_Week: 1..7; {1 es lunes. 7 es domingo}
		END;
El procedimiento "GetTimeStamp(TimeStamp)" entrega el tiempo del sistema, como en el siguiente ejemplo:

VAR
	tiempo: TimeStamp;
BEGIN
	GetTimeStamp(tiempo);
	WITH tiempo DO
		WriteLn("La hora es: ", Hour:2, ":":1, Minute:2, ":":1, Second:2)
END.
Pascal extendido también define funciones para la obtención de cadenas que representan el tiempo, y son:

	Date	Da una cadena con la fecha	Date(tiempo)	'23-OCT-1992'
	Time	Da una cadena con la hora	Time(tiempo)	'14:22:32.95'
El formato de la cadena entregada es específico del sistema operativo (en el ejemplo, de VMS).

Registros con variantes

Registros con esquemas

Conjuntos

Concepto de conjunto

Constructores de conjunto

El constructor de conjuntos se define como sigue:

constructor-de-conjunto = "[" lista-de-elementos "]".
lista-de-elementos = elemento { "," elemento }.
elemento = valor | (valor ".." valor).
Ejemplos:

TYPE
	conjLetras = SET OF Char;
CONST
	minusculas = ['a'..'z', 'á'..'ú'];

Manipulación de conjuntos

Esquemas de conjuntos

El estándar de Pascal extendido también permite definir esquemas de conjuntos, como sigue:

TYPE
	conjuntoDeCaracteres (infC, SupC: Char) = SET OF InfC..SupC;
	mayusculas = conjuntoDeCaracteres ('A', 'B');
	minusculas = conjuntoDeCaracteres ('a', 'b');

VAR
	vocalesMinusculas : minusculas VALUE {'a', 'e', 'i', 'o', 'u'};
El nuevo estándar también define la función "Card", la cual da cardinalidad (esto es, el número de elementos) que contiene un conjunto. Por ejemplo:

	Card(vocalesMinusculas)		Entrega un valor de 5

Archivos secuenciales

Concepto de archivo secuencial

Manipulación de archivos

Archivos de texto. El tipo estándar Text

Recursión

Concepto de recursión

Recursión simple

Recursión mutua

Cuando no usar recursión

Punteros

Concepto de puntero

Manipulación de punteros

Estructuras no lineales

Adecuación del almacenamiento en memoria

Procedimientos y funciones como parámetros

Uso de procedimientos y funciones como parámetros

Archivos no secuenciales

Archivos de acceso directo

Concepto de archivo de acceso directo

Manipulación de archivos

Archivos indexados

Concepto de archivo indexado

Manipulación de archivos

Programas

Álgebra Matricial
Animales
Animales 2
Lee Dia
Meses
Mínimos Cuadrados
Pirámide
Raíces
Suma de Matrices
Trapecio
Triángulo
Factorial

Apuntes con programas en Pascal

Apuntes de Preparatoria
Análisis Numérico
Computadoras y Programci¢n
Diseño Lógico
Introducción a la Ingeniería
Programación orientada a objetos
1