Temas:
Ejercicio:
Defina una función mayor que calcule el máximo valor en un arreglo. Por ejemplo, si el arreglo tab contiene las siguientes asociaciones:
| Llave | Valor |
|---|---|
| 1 | 4.5 |
| 2 | 15.0 |
| 3 | 2.2 |
| 4 | 4.3 |
entonces:
El primer argumento es el arreglo, el segundo es la llave inicial en el
arreglo y el tercero es la llave final.
println( mayor(tab, 1, 4) ); // despliega 15.0
println( mayor(tab, 3, 4) ); // despliega 4.3
Solución:
Este ejemplo muestra que una función puede recibir como argumentos
referencias a objetos. En otros ejemplos veremos que una función puede
entregar (retornar) referencias a objetos.
double mayor(Map tab, int pri, int ult) {
int i= pri;
double max= tab.getDouble(pri);
while (i<=ult) {
if (tab.getDouble(i)>max)
max= tab.getDouble(i);
i= i+1;
}
return max;
}
Observación:
Los métodos getTipo(llave) requieren que la llave exista en el arreglo. Si la llave no existe, se produce un error. Por ejemplo, la siguiente invocación de la función mayor produce un error en tiempo de ejecución:
println( mayor(tab, 2, 5) ); // error!
println( ... );
Las acciones que realiza la invocación de println consisten en desplegar
en pantalla el argumento que recibe. Es ilegal escribir asignaciones
como:
porque println no retorna ningún valor.
x= println( ... );
Ejemplos de uso de mostrar son los siguientes:
void mostrar(Map tab, int pri, int ult) {
int i= pri;
while (i<=ult) {
println(i+" -> "+tab.getDouble(i));
i= i+1;
}
// no hay return
}
que produce el siguiente resultado en pantalla:
mostrar(tab, 1, 4);
1 -> 4.5
2 -> 15.0
3 -> 2.2
4 -> 4.3
Defina el procedimiento grabar que reciba como argumentos un arreglo con valores de tipo double, dos enteros que señalan el rango de llaves válidas (pri y ult) y el nombre de un archivo. Su procedimiento debe producir un archivo con el contenido del arreglo. Por ejemplo, la siguiente invocación:
debe producir un archivo de nombre "cont.txt" con 4 líneas cuyo contenido
es:
grabar(tab, 1, 4, "cont.txt");
4.5
15.0
2.2
4.3
debe producir el siguiente resultado en pantalla:
Map tabB= new Map(); // tabB está vacío
leer(tabB, "cont.txt");
mostrar(tabB, 1, 4);
1 -> 4.5
2 -> 15.0
3 -> 2.2
4 -> 4.3
Una función o procedimiento puede modificar los arreglos que recibe
como argumentos. En general, pueden producir efectos laterales
sobre sus parámetros, cuando son algún tipo de objetos.
void leer(Map tab, String nom) {
TextReader lect= new TextReader(nom);
int i= 0;
while (true) {
double x= lect.readDouble();
if (lect.eofReached())
break;
i= i+1;
tab.put(i, x);
}
lect.close();
}
En una función o procedimiento, los parámetros que corresponden a algún tipo de objetos son en realidad referencias de objetos (recuerde que una referencia es como el teléfono celular del objeto). Por lo tanto, dentro del procedimiento leer, la variable tab referencia el mismo objeto que es referenciado por la variable tabB en la invocación de leer:

Para esto hay que cambiar la definición de leer por:
Map tabC= new Map(); // tabC está vacío
int ult= leer(tabC, "cont.txt");
mostrar(tabC, 1, ult);
En la primera versión de leer la asignación:
int leer2(Map tab, String nom) {
... // idéntico a leer
return i; // la última llave inicializada
}
es ilegal porque se definió leer como void. Con la segunda
versión sí es válida esta asignación.
int ult= leer(tabB, "cont.txt");
Observación:
¿Qué despliega el siguiente programa?
En este caso, el valor desplegado para i es 1. La variable i que
usa la función leer es interna a esa función y no tiene relación alguna
con la variable i recién escrita. Diremos que la variable i declarada
internamente en la función leer es invisible fuera de la función.
int i=1;
Map tabD= new Map();
int ult= leer2(tabD, "cont.txt");
println("leidos= "+i);
en donde leer3 es una función que recibe el nombre de un archivo
y construye un arreglo asociativo con los valores almacenados en el archivo.
Se como:
Map tabE= leer3("cont.txt");
mostrar(tab3);
Esta función crea un objeto de tipo Map, lo inicializa con valores leídos
de un archivo (cuyo nombre está almacenado en nom) y al final
retorna la referencia del arreglo.
Map leer3(String nom) {
Map tab= new Map();
... // idéntico a leer
return map; // la última llave inicializada
}