[ Foro de Pascal ]
program funcion_mas_de_un_valor_record;
uses
crt, math;
type
Tcuadrado = record
superficie: real;
perimetro: real;
end;
var
cuadrado: Tcuadrado;
lado: real;
function calculos (lado: single): Tcuadrado;
begin
calculos.superficie := lado ** 2;
calculos.perimetro := 4 * lado;
end;
begin
clrscr;
writeln ('Superficie y perímetro de un cuadrado');
writeln ('-------------------------------------');
write ('Teclea el lado: ');
readln (lado);
cuadrado := calculos(lado);
writeln;
writeln ('Superficie: ', cuadrado.superficie:0:4);
writeln ('Perímetro: ', cuadrado.perimetro:0:4);
end.
¡Hola!
Pues he metido la pata y no he puesto el mensaje completo anteriormente, así que lo pongo ahora completo y pido disculpas.
En Pascal una función no puede devolver más de un valor. Sin embargo hay un truco que nos permite hacerlo. Consiste en definir un tipo de dato como array o record, y hacer que la función devuelva al programa principal un resultado con ese tipo de datos.
Como ejemplo, un programa que calcula el perímetro y la superficie de un cuadrado, dado el lado. La función recibe el lado como dato y devuelve perímetro y superficie.
Podemos hacerlo de dos maneras: usando arrays o registros. Si usamos arrays el programador tiene que acordarse a qué dato corresponde cada elemento.
Primer caso: array.
program funcion_mas_de_un_valor_array;
uses
crt, math;
type
Tcuadrado = array [1..2] of single;
//en el primer elemento del vector guardamos la superficie del cuadrado
//en el segundo elemento guardamos el perímetro
var
cuadrado: Tcuadrado;
lado: real;
function calculos (lado: real): Tcuadrado;
begin
calculos[1] := lado ** 2; //superficie
calculos[2] := 4 * lado; //perímetro
end;
begin
clrscr;
writeln ('Superficie y perímetro de un cuadrado');
writeln ('-------------------------------------');
write ('Teclea el lado: ');
readln (lado);
cuadrado := calculos(lado);
writeln;
writeln ('Superficie: ', cuadrado[1]:0:4);
writeln ('Perímetro: ', cuadrado[2]:0:4);
end.
Segundo caso: registro.
program funcion_mas_de_un_valor_record;
uses
crt, math;
type
Tcuadrado = record
superficie: real;
perimetro: real;
end;
var
cuadrado: Tcuadrado;
lado: real;
function calculos (lado: single): Tcuadrado;
begin
calculos.superficie := lado ** 2;
calculos.perimetro := 4 * lado;
end;
begin
clrscr;
writeln ('Superficie y perímetro de un cuadrado');
writeln ('-------------------------------------');
write ('Teclea el lado: ');
readln (lado);
cuadrado := calculos(lado);
writeln;
writeln ('Superficie: ', cuadrado.superficie:0:4);
writeln ('Perímetro: ', cuadrado.perimetro:0:4);
end.
Efectivamente.
Aun así, te falta una tercera forma, que posiblemente es la más natural: pasar dos parámetros por referencia.
procedure calcularPerimetroYSuperficie
(lado: real, var perimetro: real, var superf:real);
Es verdad, pero en este caso ya sería un procedimiento en vez de una función. Gracias
Hola,
Y también podría ser una función que, aparte de devolver el valor 'final', modificase de forma 'colateral' valores por referencia, no?
Es decir, una mezcla de los dos... aunque no le veo mucha utilidad...
Saludos!
Efectivamente, podría ser un procedimiento o incluso una función, aunque no es algo habitual.
Yo lo he usado alguna vez para cosas como comprobar el ratón: una función que devolvía "true" (un booleano) si se había pulsado el ratón, y entonces se podía saber la X y la Y de esa pulsación, mirando dos parámetros pasados por referencia.
En general, yo prefiero aislar cosas: me parece más legible, aunque sea un poco más largo, tener 3 funciones separadas: un IsButtonPressed para ver si se ha pulsado y un GetX y un GetY para comprobar la posición.
(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)