Resolución de Problemas y Algoritmos Segundo cuatrimestre 2015 Clase 13: Bloques y entornos Dr. Sergio A. Gómez http://cs.uns.edu.ar/~sag Departamento de Ciencias e Ingeniería de la Computación Universidad Nacional del Sur Bahía Blanca, Argentina (Esta clase está basada en una clase del Dr. Alejandro García) Pascal es estructurado por bloques PROGRAM MIPROGRAMA CONST ........ VAR ......... FUNCTION F(X:real):real; CONST ....... VAR ….. PROCEDURE BEGIN ... END; • En Pascal, un programa está definido por un bloque compuesto por: – constantes y variables – funciones – procedimientos – sentencias PROCEDURE P(…); CONST...... VAR ..... PROCEDURE BEGIN ... END; BEGIN ........................ END. Resolución de Problemas y Algoritmos •Los procedimientos y funciones también están definidos por un bloque con: –parámetros –constantes, variables, –procedim. y funciones –sentencias Dr. Alejandro J. García 2 En Pascal no hay límite en cantidad o anidamiento de bloques PROGRAM PROGRAMA1; PROGRAM PROGRAMA2; PROCEDURE… PROCEDURE … FUNCTION … PROCEDURE… FUNCTION … PROCEDURE … PROCEDURE… FUNCTION … BEGIN ........ END; PROCEDURE… FUNCTION … BEGIN ... END. Resolución de Problemas y Algoritmos BEGIN ....... END; BEGIN... END. Dr. Alejandro J. García 3 El límite es su imaginación • Pascal está estructurado por bloques. • Un programa es un bloque que puede tener bloques internos (procedimientos o funciones) los cuales pueden a su vez tener bloques, y así siguiendo... • En un programa pueden incluirse tantos procedimientos y funciones como se desee. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 4 (P) Bloques e identificadores PROGRAM simple; VAR A, B, C:CHAR; PROCEDURE P1 (A:REAL); VAR B: REAL; BEGIN B:= A; WRITE(B) END; PROCEDURE P2 (A:REAL); VAR B, MIA: REAL; FUNCTION F2 (A:REAL):REAL; VAR B, DE_F2: REAL BEGIN B:= A; F2:= B + 1; END; BEGIN B:= A; WRITE(F2(A)); P1(B) END; BEGIN P1(10); P2(5); Dr. Alejandro J. García END.Resolución de Problemas y Algoritmos 5 Preguntas sobre el programa “simple” • • • • • • • • ¿puede haber dos identificadores IGUALES? ¿puede P2 llamar a P1? ¿puede P2 llamar a F2? ¿puede P1 llamar a F2? ¿puede F2 llamar a P1? ¿puede el programa usar la variable “MIA”? ¿puede P2 o P1 usar la variable “DE_F2”? ¡ HAGA AHORA SUS PREGUNTAS ! (y copie las de sus compañeros) • Todas las respuestas en la teoría que sigue a continuación… Resolución de Problemas y Algoritmos Dr. Alejandro J. García 6 Estructurado por Bloques • Elementos de un BLOQUE: 1. identificadores de constantes 2. identificadores de tipos 3. identificadores de variables 4. identificadores parámetros formales (en proc. y func.) 5. identificadores de procedimientos 6. identificadores de funciones 7. sentencias • Dentro de un mismo bloque no puede haber dos identificadores iguales para distintos elementos. • Dos elementos pueden tener el mismo identificador si pertenecen a diferentes bloques. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 7 (P) Bloques e identificadores PROGRAM MIPROG; {Ejemplo para mostrar identificadores en distintos BLOQUES} VAR NUM: REAL; T:INTEGER; RESU:BOOLEAN; A:CHAR; PROCEDURE TECHO (A:REAL; VAR RESU:INTEGER); {El techo de A es el menor entero mayor que A} VAR NUM, PEPE: INTEGER; FUNCTION PARTE_ENTERA (NUM:REAL):INTEGER; VAR RESU: INTEGER; BEGIN RESU:=TRUNC(NUM); PARTE_ENTERA:=RESU; END; BEGIN NUM:=PARTE_ENTERA(A); IF NUM = A then RESU:= A else RESU:= NUM + 1; END; BEGIN NUM:= 10.12; TECHO( NUM, T); write(Num,T); END. Resolución de Problemas y Algoritmos Dr. Alejandro J. García ELEMENTOS DE CADA BLOQUE PARTE_ENTERA: NUM RESU EN TECHO: A RESU NUM, PEPE PARTE_ENTERA EN MIPROG: NUM T RESU A TECHO 8 Entorno de referencia para un bloque B El entorno de referencia de un bloque B está formado por: • El entorno local: parámetros formales, constantes, tipos y variables definidas dentro de B y el nombre de los procedimientos y funciones definidos dentro del bloque B. • El entorno global: es el entorno del programa principal • El entorno no-local: conjunto de identificadores definidos en los bloques que contienen al bloque B, exceptuando al global • El entorno predefinido: definido por el compilador de Pascal y disponible para todo programa. Definición: Un identificador es visible en una sentencia de un Bloque B si es parte de su entorno de referencia. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 9 Uso de identificadores Es importante distinguir entre: 1. La declaración de un identificador Ej: VAR precio: real; FUNCTION recargo (P:real):real; 2. Una referencia a un identificador (cuando se usa) Ej: precio := round(precio) + recargo(precio); • Cuando se hace referencia a un identificador: 1. primero se busca en su entorno de referencia local, 2. luego en su entorno de referencia no local, 3. luego en su entorno de referencia global, 4. y finalmente en el entorno de referencia predefinido Resolución de Problemas y Algoritmos Dr. Alejandro J. García 10 Uso de identificadores • Por lo anterior, si hay identificadores iguales en diferentes entornos uno oculta al otro. 1. Un identificador de nombre N en un entorno local oculta a todo identificador del mismo nombre N en otro entorno (no-local, global, predefinido) 2. Uno no-local N oculta a otro global de nombre N, 3. Un identificador global N oculta a uno predefinido N Resolución de Problemas y Algoritmos Dr. Alejandro J. García 11 Estructurado por Bloques PROGRAM MIPROG; {Ejemplo para mostrar identificadores en distintos BLOQUES} VAR NUM: REAL; T:INTEGER; RESU:BOOLEAN; A:CHAR; PROCEDURE TECHO (A:REAL; VAR RESU:INTEGER); {El techo de A es el menor entero mayor que A} VAR NUM, PEPE: INTEGER; FUNCTION PARTE_ENTERA (NUM:REAL):INTEGER; VAR RESU: INTEGER; BEGIN RESU:=TRUNC(NUM); PARTE_ENTERA:=RESU; END; BEGIN NUM:=PARTE_ENTERA(A); RESU:= NUM + 1; END; BEGIN NUM:= 10.12; TECHO( NUM, T); END. Resolución de Problemas y Algoritmos Dr. Alejandro J. García Entorno de PARTE_ENTERA LOCAL: NUM RESU GLOBAL: NUM (no) T A (no) RESU (no) TECHO NO LOCAL: (EN TECHO) A RESU (No) NUM (no), PEPE PARTE_ENTERA 12 Alcance de un identificador • Alcance de identificador I: Es el conjunto de sentencias desde el cual I es referenciable. • Esta noción es dual a la de entorno de referencia. • Hay que notar que en algunas sentencias ese identificador I puede estar eclipsado por otro I local. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 13 (1) program prog; (2) Var i : integer; (3) Procedure P; (4) Var i : integer; (5) Begin (6) i := 7; (7) write( i ); (8) End; (9) Begin (10) i := 5; (11) write( i ); (12) End. Ejemplo El alcance de i del programa principal son las sentencias: (10) y (11). (6) y (7) están fuera de su alcance pues ese identificador no es referenciable allí (pues es eclipsado por el “i” local de “P”). Resolución de Problemas y Algoritmos Dr. Alejandro J. García 14 Parámetros actuales (o efectivos) • Parámetros actuales (actual parameters): en la llamada al procedimiento o función. • si el parámetro formal correspondiente es por valor entonces el parámetro real puede ser: – un valor (o literal) – una expresión – una variable con valor • si el parámetro formal es por referencia, entonces debe ser llamado ÚNICAMENTE con una variable NUM:= 3; MULT_FRAC ( NUM, 2+4, 3, NUM * 4, NUM, DENO); Resolución de Problemas y Algoritmos Dr. Alejandro J. García 15 Ejemplos de correspondencia entre parámetros VAR N1,D1,N2,D2,N,D:Integer; PROCEDURE MultiplicarFracciones ( Num1, Den1, Num2, Den2: INTEGER; VAR NumRes,DenRes: INTEGER); BEGIN NumRes := Num1 * Num2; DenRes := Den1 * Den2; END; N1:=1; D1:=2; N2:=1; D2:=2; MultiplicarFracciones (N1,D1,N2,D2, N,D); Writeln(N,’/’,D); MultiplicarFracciones (3,4,2,5,N,D); Writeln(N,’/’,D); MultiplicarFracciones (2*1,2+2,2,4,N,D); Writeln(N,’/’,D); Resolución de Problemas y Algoritmos Dr. Alejandro J. García 16 Parámetros en Funciones y Procedimientos Por valor : <nombre>:<tipo> Formales Por referencia: VAR <nombre>:<tipo> un valor Pará- si corresponde a un parámetro formal por valor, puede ser... metros una expresión una variable Actuales si corresponde a un parám. formal por referencia, debe una variable ser únicamente ... Resolución de Problemas y Algoritmos Dr. Alejandro J. García 17 Procedimientos y parámetros en Pascal • MultiplicarFracciones tiene 6 parámetros: 4 por valor (para recibir datos) y 2 por referencia (para devolver datos) PROCEDURE MultiplicarFracciones ( Num1, Den1, Num2, Den2: INTEGER; VAR NumRes,DenRes: INTEGER); BEGIN NumRes := Num1 * Num2; DenRes := Den1 * Den2; END; • ¿Puede un procedimiento tener sólo parámetros por valor? PROCEDURE BAJAR_LINEAS(cant:INTEGER); var v:integer; BEGIN FOR v:=1 TO cant DO writeln; END; Resolución de Problemas y Algoritmos Dr. Alejandro J. García 18 Procedimientos y parámetros en Pascal ¿ Puede un procedimiento tener sólo parámetros por referencia? PROCEDURE PasarAmayuscula(VAR L:char); begin L := chr(ord(L) - (ord(‘a’) - ord (‘A’)); end; ¿ Puede un procedimiento no tener parámetros? PROCEDURE PAUSA; BEGIN writeln(‘ pulse ENTER para continuar’); readln; END; Resolución de Problemas y Algoritmos Dr. Alejandro J. García 19 Procedimientos y parámetros en Pascal • ¿Puede un procedimiento tener un único dato de salida? PROCEDURE EsVocal (letra :char; var ES: boolean); BEGIN CASE letra OF ‘A’,’E’,’I’,’O’,’U’, ‘a’,’e’,’i’,’o’,’u’: Es:=true; ELSE Es:=false; END; • ¿Qué diferencia hay con tener una función? FUNCTION EsVocal (letra :char): boolean; BEGIN CASE letra OF ‘A’,’E’,’I’,’O’,’U’, ‘a’,’e’,’i’,’o’,’u’: EsVocal:=true; ELSE EsVocal:=false; END; Resolución de Problemas y Algoritmos Dr. Alejandro J. García 20 Funciones y parámetros en Pascal • ¿Puede una función no tener parámetros? FUNCTION leer_letra:CHAR; var aux: char; BEGIN REPEAT read(aux) UNTIL (aux>=‘A’) and (aux<=‘Z’) or (aux>=‘a’) and (aux<=‘z’) leer_letra:= aux END; Resolución de Problemas y Algoritmos Dr. Alejandro J. García 21 Funciones y parámetros en Pascal • ¿ Puede una función tener parámetros por referencia? FUNCTION leer_letra(VAR error:boolean) :CHAR; var aux: char; BEGIN read(aux); IF (aux>=‘A’) and (aux<=‘Z’) or (aux>=‘a’) and (aux<=‘z’) then error:=FALSE else error:=TRUE; { Alternativa: error := not ((aux>=‘A’) and (aux<=‘Z’) or (aux>=‘a’) and (aux<=‘z’) ) ; } leer_letra:= aux END; Resolución de Problemas y Algoritmos Dr. Alejandro J. García 22 Ejemplo de traza con parámetros por valor PROGRAM Ejemplo2; {mostrar param por valor} VAR M,N: integer; M PROCEDURE PocoYNada ( A, B: integer); N VAR Aux: integer; BEGIN write( A, B); Aux := A ; A := aux + 1; B := Aux; write( A, B, Aux); END; Al comenzar la ejecución se crea el BEGIN registro de activación. Las variables aún M:=0; no tienen valor. N:=9; Writeln('Inicialmente M es ',M,' y N es ',N,'.'); PocoYNada(M,N); Writeln(’Al terminar M es ',M,' y N es ',N,'.') END. Resolución de Problemas y Algoritmos Dr. Alejandro J. García ?? ?? 23 Ejemplo de traza con parámetros por valor PROGRAM Ejemplo2; {mostrar param por valor} VAR M,N: integer; 0 M PROCEDURE PocoYNada ( A, B: integer); 9 N VAR Aux: integer; BEGIN write( A, B); Aux := A ; A := aux + 1; B := Aux; write( A, B, Aux); END; BEGIN Antes de llamar al procedimiento “PocoYnada” M:=0; las variables M y N ya tienen valor asignado. N:=9; Writeln('Inicialmente M es ',M,' y N es ',N,'.'); PocoYNada(M,N); Writeln(’Al terminar M es ',M,' y N es ',N,'.') END. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 24 Ejemplo de traza con parámetros por valor PROGRAM Ejemplo2; {mostrar param por valor} VAR M,N: integer; PROCEDURE PocoYNada ( A, B: integer); VAR Aux: integer; BEGIN write( A, B); Aux := A ; A := aux + 1; B := Aux; write( A, B, Aux); END; Al entrar al procedimiento se crea un nuevo registro de activación y los BEGIN parámetros toman los valores que les M:=0; fueron enviados. Las variables locales N:=9; aún no tienen Writeln('Inicialmente M es valor. ',M,' y N es ',N,'.'); PocoYNada(M,N); Writeln(’Al terminar M es ',M,' y N es ',N,'.') END. Resolución de Problemas y Algoritmos Dr. Alejandro J. García M 0 N 9 A 0 B 9 aux ?? 25 Ejemplo de traza con parámetros por valor PROGRAM Ejemplo2; {mostrar param por valor} VAR M,N: integer; PROCEDURE PocoYNada ( A, B: integer); VAR Aux: integer; BEGIN write( A, B); Aux := A ; A := aux + 1; B := Aux; write( A, B, Aux); END; Antes de terminar el BEGIN procedimiento los valores M:=0; de A, B y aux cambiaron N:=9; Writeln('Inicialmente M es ',M,' y N es ',N,'.'); PocoYNada(M,N); Writeln(’Al terminar M es ',M,' y N es ',N,'.') END. Resolución de Problemas y Algoritmos Dr. Alejandro J. García M 0 N 9 A 1 B 0 aux 0 26 Ejemplo de traza con parámetros por valor PROGRAM Ejemplo2; {mostrar param por valor} VAR M,N: integer; 0 M PROCEDURE PocoYNada ( A, B: integer); 9 N VAR Aux: integer; BEGIN write( A, B); Aux := A ; A := aux + 1; B := Aux; write( A, B, Aux); END; BEGIN Al volver del procedimiento “PocoYnada” las M:=0; variables M y N conservan su valor asignado. N:=9; Writeln('Inicialmente M es ',M,' y N es ',N,'.'); PocoYNada(M,N); Writeln(’Al terminar M es ',M,' y N es ',N,'.') END. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 27 • • • • Registros de activación Para reflejar lo que sucede en ejecución (dinámicamente) y poder hacer una traza, veremos que existe una unidad (llamada registro de activación) por cada bloque del programa. Esta unidad contendrá un espacio por cada parámetro formal, para cada variable local del mismo y tendrá anotada cuál es la sentencia que está siendo ejecutada (instruction pointer o IP). Cada vez que se invoca un procedimiento o función se crea un nuevo registro de activación. Cada vez que finaliza un procedimiento o función se destruye el registro de activación correspondiente. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 28 Elementos de un registro de activación al hacer la traza Parámetros por valor Parámetros por referencia Variables Locales Registro de activación de un bloque en ejecución Resultado de la función Resolución de Problemas y Algoritmos Dr. Alejandro J. García 29 Traza del programa Ejemplo2 (1) (2) (3) (4) M 0 M 0 M 0 M 0 N 9 N 9 N 9 N 9 A 0 A 1 B 9 B 0 aux 0 aux ?? (1) Antes de llamar al procedimiento “PocoYnada” (2) Al entrar al procedimiento (3) Antes de salir del procedimiento (4) Después de salir del procedimiento Resolución de Problemas y Algoritmos Dr. Alejandro J. García 30 Ejemplo de intercambio de valores PROGRAM IntercambiarVariables; VAR M,N: integer; PROCEDURE Intercambiar (VAR A, B: integer); VAR Aux: integer; BEGIN Aux := A; A := B; B := Aux END; BEGIN M:=5; N:=9; Writeln('Inicialmente M es ',M,' y N es ',N,'.'); Intercambiar(M,N); Writeln(’Al terminar M es ',M,' y N es ',N,'.') END. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 31 Ejemplo de intercambio de valores Cuando comienza el programa IntercambiarVariables. M N IntercambiarVariables Después de ejecutar las asignaciones M y N quedan con los siguientes valores: No se puede mostrar la imagen en este momento. IntercambiarVariables Resolución de Problemas y Algoritmos Dr. Alejandro J. García 32 Ejemplo de intercambio de valores Cuando se invoca al procedimiento Intercambiar debe crearse un bloque para ese procedimiento. M N 5 9 A B Aux Resolución de Problemas y Algoritmos IntercambiarVariables Intercambiar Dr. Alejandro J. García 33 Pasaje de parámetros por referencia Cuando un parámetro es pasado por referencia, el parámetro formal “es una referencia” al parámetro actual. M N 5 9 A B Aux Resolución de Problemas y Algoritmos IntercambiarVariables Intercambiar Dr. Alejandro J. García 34 Pasaje de parámetros por referencia Cuando un parámetro es pasado por referencia, cada cambio en el parámetro formal “afecta” al parámetro real. M N 9 9 5 5 A B Aux 5 Resolución de Problemas y Algoritmos IntercambiarVariables Intercambiar Dr. Alejandro J. García 35 Ejemplo de intercambio de valores Cuando termina la ejecución de Intercambiar queda el siguiente estado: M N 9 9 5 5 IntercambiarVariables En pantalla se imprimirá lo siguiente:. Inicialmente M es 5 y N es 9. Al terminar M es 9 y N es 5. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 36 Repaso: Tipos de datos en Pascal Tipo de Dato: Conjunto de valores posibles que puede tomar una variable, expresión, parámetro o función. Un tipo tiene también asociado un conjunto de operaciones y viene equipado con una representación interna. ¿Qué elementos de Pascal tienen un tipo asociado? • una variable, • una expresión, • un parámetro, • una función. 37 Tipo de Dato: Conjunto de valores posibles que puede tomar una variable, expresión, parámetro o función. En Pascal –REAL –BOOLEAN Tipos –CHAR Predefinidos –INTEGER –TEXT (archivos de texto) Tipos definidos – subrangos –Archivos por el – Enumerados programador –muchos otros (que no veremos en esta materia) Definir nuevos tipos permite claridad y abstracción. 38 Repaso: Tipos definidos por el programador • El programador puede “ redefinir ” o “ renombrar” a los tipos predefinidos y luego usarlos para definir variables, parámetros, funciones, otros tipos, etc. TYPE Entero = integer; Logico = Boolean; NroReal = real; Letra = char; Telemento = Entero; Tarchivo = FILE OF Telemento; TDia = (Domingo, Lunes, Martes, Miercoles, Jueves, Viernes, Sabado); TMes = (Ene, Feb, Mar, Abr, May, Jun, Jul, Ago, Sep, Oct, Nov, Dic ); VAR Precio : NroReal; Num: Entero; Es_Par: Logico; Inicial: Letra; F1, F2: Tarchivo; MesFavorito : TMes; Hoy : TDia; 39 Repaso: Relaciones entre tipos En Pascal existen tres relaciones entre tipos: 1. Igualdad o Identidad. 2. Compatibilidad. 3. Compatibilidad de asignación. 40 Repaso: Tipos idénticos en Pascal • Dos elementos (variables, parámetros, funciones) tienen tipos idénticos si se cumple una de las siguientes declaraciones : a) Están declarados con el mismo identificador de tipo. b) Los identificadores de tipo son diferentes ( ej: T1 y T2) pero han sido definidos como equivalentes por una declaración de la forma TYPE T1 = T2. Ejemplo: ¿cuales son idénticos? TYPE T = INTEGER; T1 = T; VAR A, A1: T; B: INTEGER; C: T1; D: -32768 .. 32767; Function F(p1: T1; var p2: T):T; 41 Repaso: Tipos compatibles en Pascal Dos tipos son compatibles si al menos una de las siguientes declaraciones es verdadera: a) Ellos son idénticos. b) Uno es subrango o subintervalo del otro. c) Ambos son subrangos del mismo tipo. Ejemplo: ¿cuáles son compatibles? TYPE Sub = 1..1000; Sub2 = Sub; Sub1 = 100..200; Sub3 = 0..99; VAR A: Sub; B: INTEGER; C: Sub1; D: Sub2; E: Sub3; 42 Repaso: Asignación compatible V := E T1 T2 Una expresión E de tipo T2 es asignación-compatible con una variable V de tipo T1 si al menos una de las siguientes declaraciones es verdadera: 1) T1 y T2 son idénticos. 2) T1 es real y T2 es entero o subrango de entero. 3) T1 y T2 son tipos compatibles ordinales (enumerados, subrangos o enteros), y el valor de E es un valor permitido del tipo T1. 43 Compatibilidad entre parámetros • Si un procedimiento o función tiene un parámetro formal pasado POR REFERENCIA, entonces el tipo del parámetro formal debe ser idéntico al tipo del parámetro actual. Por ejemplo, si hemos declarado: PROCEDURE Calcula( VAR valor : real ); y se realiza la invocación: Calcula( numero ); entonces numero debe ser de tipo idéntico a real. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 44 Compatibilidad entre parámetros El valor de un parámetro actual pasado POR VALOR debe ser de asignación-compatible al tipo del parámetro formal. Por ejemplo, si hemos declarado: PROCEDURE Calcula(valor : real); y se realiza la invocación: Calcula( numero ); entonces numero debe ser asignación compatible con real. Resolución de Problemas y Algoritmos Dr. Alejandro J. García 45 Compatibilidad entre parámetros • Puedo invocar con: Var r : real; i : integer; Procedure calcula( valor : real ); begin … end; Begin R := 3.4; i := 3; Calcula( R ); Calcula( 3.6 ); Calcula( i ); Calcula( 3.4 * 5.6 ); Calcula ( 4+5 ); Calcula( sin(4.5) * cos(4) ); … Resolución de Problemas y Algoritmos Dr. Alejandro J. García 46 OBSERVACIÓN IMPORTANTE Problema: Agregue al archivo “mis-numeros.dat” (ya creado y con números en él) un entero ingresado por el usuario al final del mismo. Observación: En Pascal estándar, no se puede abrir un archivo para leer y luego escribir en él. Algoritmo: 1. copio del original (F1) a un temporario (F2), 2. agrego lo nuevo a F2, cierro los dos, 3. copio todo lo de F2 a F1. 4. elimino F2 Resolución de Problemas y Algoritmos Dr. Alejandro J. García 47 Consideraciones • Si un procedimiento o función tiene un parámetro formal pasado por referencia, entonces el tipo del parámetro formal debe ser idéntico al tipo del parámetro real. • El tipo de un parámetro formal por referencia (en el encabezamiento de un procedimiento o función) debe ser especificado con un identificador de tipo. • Por lo tanto, no es posible escribir cosas como: PROCEDURE Incorrecto(VAR Arg : 1..5); { MAL!!! } • Forma correcta: {$R+} { Habilitar testeo de rangos} TYPE Subrango = 1..5; PROCEDURE Correcto(VAR Arg : Subrango); 48