PDA

Ver la Versión Completa : Pasar array como parámetro


santiago14
16-09-2008, 22:11:01
Buenas, tengo la siguiente definición:


interface

type
TDatos = record
temperatura:double;
humedad:double;
end;

procedure proceso(A:array of TDatos);

implementation

//por otro lado...

procedure proceso(A:array of TDatos);
begin
//...
end;


Ahora, hasta aquí todo bien pero resulta que quiero llamar al procedimiento de la siguiente forma y no me deja:


proceso([(20,78),(18,95),(23,93)]);


Se que de la manera tradicional puede hacerse pero necesitaría que el pasaje fuera de la manera que indico pues evitaría que yo inicializara el array dinámico, que armara uno por uno los registros y todo eso.
Creo que estoy haciendo algo mal por eso no me deja hacer el pasaje de esa manera. Pido que alguien me corrija o brinde alguna sugerencia.

Saludos.

Ana María
16-09-2008, 23:13:44
Ensaya con estointerface

type
TDatos = record
temperatura:double;
humedad:double;
end;

type Miarray = array of TDatos;

procedure proceso(A:MiArray);

implementation

//por otro lado...

procedure proceso(A: MiArray);
begin
//...
end;

santiago14
17-09-2008, 02:12:37
Ensaya con estointerface

type
TDatos = record
temperatura:double;
humedad:double;
end;

type Miarray = array of TDatos;

procedure proceso(A:MiArray);

implementation

//por otro lado...

procedure proceso(A: MiArray);
begin
//...
end;

He probado con esto pero no funciona, me sigue diciendo que no es una forma adecuada de pasar al array como parámetro.

Para citar un ejemplo aún mas claro, si hago lo siguiente no hay problemas:



procedure proceso(a:array of integer);
begin
//...
end;


//Ahora hago una llamada

procedure TForm1.buttonClick(sender);
begin
//Esto lo acepta perfectamente, quiero hacer lo mismo pero mandando
//dos valores en la componente en lugar de uno
proceso([5,4,3,10]);
end;



Gracias.

santiago14
17-09-2008, 02:32:42
Para ser mas gráfico, estoy ante un problema que se llama "Parámetros de vector abierto (Open Array)"

Espero que alguien tenga una idea de como arreglar la cosa.

Saludos.

Delphius
17-09-2008, 02:54:51
Hola santiago14,
La verdad es que no te sabría decir si es posible hacer lo que buscas.
Una posible alternativa es que el procedimiento reciba dos vectores dinámicos.
Se que no es demasiado elegante, pero es una opción.

La otra alternativa que se me ocurre es un tanto mas complicada y tal vez sea demasiado para tus propósitos:
en vez de tener un record, implementar una clase TDatos que tenga los mismos campos.

Después tener un TObjectList que hará de vector. De este modo el procedimiento puede recibir a un objeto TObjectList y recorrer todos los objetos TDatos que estén dentro de éste.

El asunto es que este enfoque obliga a crear cada objeto TDato y llenarlo por separado, y relacionarlo con el TObjectList.

Por esto digo que tal vez esta opción sea más complicada que tener dos vectores.

Saludos,

Caro
17-09-2008, 03:07:38
Hola Santiago14, creo que así directamente no se puede, la forma que se me ocurre es inicializar como una constante de esta forma:


VarDatos : Array[1..3] of TDatos = ((temperatura : 20; humedad : 78), (temperatura : 20; humedad : 78), (temperatura : 20; humedad : 78));
.......


la otra forma es darle tu los valores correspondientes a cada atributo de tu registro, para luego pasar ese array como parametro.


var
varDatos : Array[1..3] of TDatos;
begin
varDatos[1].temperatura := 20;
varDatos[1].humedad := 78;
varDatos[2].temperatura := 20;
varDatos[2].humedad := 78;
varDatos[3].temperatura := 20;
varDatos[3].humedad := 78;

proceso(varDatos);


Saluditos

santiago14
17-09-2008, 03:19:00
Quiero agradecerles a todos que a esta hora de la noche se han tomado la molestia de buscar una solución a todo esto.
Hasta ahora no he tenido buenos resultados; espero encontrar la respuesta en el corto plazo.

Agradecido nuevamente les deseo buenas noches.

Por supuesto que voy a considerar todas las respuestas y veo si haciendo un merengue entre todas puedo llegar a algo. Por favor, si tienen nuevas sugerencias no duden en ponerlas.

Neftali [Germán.Estévez]
17-09-2008, 09:01:17
Yo tengo esto funcionando en Delphi 6 desde hace mucho tiempo:


procedure DefaultSort(AttrIndex:array of integer;
AttrSortType: array of TSQLSortType);
....

Y la llamada...

Self.DefaultSort([1],[sstASC]);

coso
17-09-2008, 13:06:33
Hola, es normal q te salte error puesto q no le estas pasando un array de TDatos, sino un array de enteros. Puedes hacer varias cosas (para mantener el formato de pares de numeros...).

1.- hacer overload de 'proceso' : mientras que en una acepte array de tdatos, en la otra acepte array de [0..1] real (pares de numeros), llamando, luego de transformar los parametros, una a la otra, segun te convenga.
2.- Crear una clase cuyo constructor acepte pares de numeros, tendras que llamar a proceso entonces de la manera proceso([TDatos(0,1),TDatos(20,3)]) etc...
3.- Crear una funcion que, a partir de pares de numeros, te devuelva un array de tdatos. Algo parecido a Rect()... te quedaria como proceso(A_Datos([(0,1),(20,80),(30,20)]));
4.- Crear una clase TDatos con un array [0..1] of double, y dentro ella crear dos propiedades, temperatura y humedad, con su read/write, los cuales devolverian v[0] i v[1];
5.- Que proceso solo acepte array de array[0..1] of double, y que TDatos sea eso (type TDatos : array [0..1] of double), sabiendo tu ya q el primer valor es temperatura y el segundo humedad.

... y alguna q otra manera mas hay, seguro...

Para mi la mejor de todas seria la primera (la menos laboriosa y visualmente mas entendible, una vez escrita) si bien segun para q lo quieras (si tiene q desarrollarse bastante) quizas te salga mas a cuenta crear una clase correctamente (la opcion 4). Creo q en c del antiguo si se podia tratar una struct (record) asi tal como escribes, colocandose cada valor en su sitio. Me parece q la OOP anulo esto , pues son necesarios los typecast para casi todo. Igualmente, no estoy seguro, investigo un poco. Saludos y a ver si te sirve lo escrito.

coso
17-09-2008, 13:22:05
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TPar = record
temperatura : double;
humedad : double;
end;

procedure Proceso( T: array of TPar);

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }

end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function Par(t, h : double) : TPar;
begin
result.temperatura := t;
result.humedad := h;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
t : TPar;
begin
t.temperatura := 50;
t.humedad := 0;
proceso([Par(20,78), Par(30,40),t]);
end;

procedure Proceso( T: array of TPar);
var
i : integer;
begin
for i := 0 to length(T) - 1 do
begin
SHowmessage(FormatFloat('0.00',T[i].temperatura) + ' ' + FormatFloat('0.00',T[i].humedad));
end;
end;


otra...esta es analoga a como trabaja TPoint.

santiago14
17-09-2008, 14:31:00
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TPar = record
temperatura : double;
humedad : double;
end;

procedure Proceso( T: array of TPar);

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }

end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function Par(t, h : double) : TPar;
begin
result.temperatura := t;
result.humedad := h;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
t : TPar;
begin
t.temperatura := 50;
t.humedad := 0;
proceso([Par(20,78), Par(30,40),t]);
end;

procedure Proceso( T: array of TPar);
var
i : integer;
begin
for i := 0 to length(T) - 1 do
begin
SHowmessage(FormatFloat('0.00',T[i].temperatura) + ' ' + FormatFloat('0.00',T[i].humedad));
end;
end;


otra...esta es analoga a como trabaja TPoint.

Gracias Coso, la verdad que está bueno el proceso que mandaste.