在Delphi中传递参数中的静态字节数组

时间:2010-10-12 03:12:11

标签: delphi

我有一个静态数组:

myArray: array [0..15] of byte;

我希望将此数组(不是数组的副本)传递给函数。在函数内部,我将操作数组中的数据。

不同长度的STATIC字节数组可以在不同时间传递给Init。因此,我不希望声明Init只能接收一定长度的字节数组。 (例如,在这种情况下,它是16字节。在其他时候,它可能是65000字节)

这是我使用该功能的方式:

Init(@myArray[0]); //passing in pointer to static array

我试图像这样声明Init:

procedure Init(x: array of byte);
begin
//Do some stuff with x, for e.g.
Length(x);  //I do not intend to pass in the length as a parameter, 
            //but determine it in this function itself.  


end;

这也是声明Init函数参数的正确方法吗?

4 个答案:

答案 0 :(得分:3)

  1. 而不是Init(@myArray [0])使用Init(myArray)。 Delphi将通过引用转移myArray
  2. 您将x声明为打开的字节数组。 open数组参数与具有相同元素类型的数组变量类型兼容。 Delphi将固定数组长度作为隐藏参数传输。您可以使用Length(x)访问它,例如for i := Low(x) to High(x) do
  3. 打开数组参数不能设置为nil。如果需要将x设置为nil,则必须将x声明为指向字节的指针或指向字节数组[..]的指针。

答案 1 :(得分:2)

首先,声明

procedure Init(x: array of byte);

声明一个开放的数组参数(不是动态数组,与其他声明不同)。

要做你想做的事,你需要这样声明:

type
  TMyArray: array [0..15] of byte; 
var
  MyArray : TMyArray;

Procedure Init(var X : TMyArray)

但是,我不确定你为什么试图将变量设置为nil。静态数组变量有点像记录,你不能将它设置为nil。而 IF 你传递一个指向函数的指针,你需要首先将你的数组分配给一个变量(或直接在函数中分配内存)。像这样:

type
  TMyArray : Array[0..15] of byte;
  pTMyArray : ^TMyArray;

  Procedure Init(var X : pTMyArray);
procedure DoSomething;
var P : pTMyArray;
begin
  New(P); //or if you array is global, simply do "P := @MyArray"
  try
    //code here
    Init(P);
    //code here
  finally
    Dispose(P);
  end;
end

但是这将是一个糟糕的构造IMO,因为如果你在Init函数中将数组指针设置为nil,你将得到内存泄漏。所以这开始是非常糟糕的。但我想如果你的Init函数保留了内存就可以了。

如果您满足于打开数组参数,我建议使用LowHigh来确定数组的边界。

我认为这是我能给你的最好的信息,直到你详细说明你想要实现的目标。

修改的 好的,如果你需要函数接受不同大小的数组,你需要一个开放的数组参数。

你在你的例子中做得对。但是你不能在函数中将它设置为nil。

我认为不可能将指向开放数组类型的指针传递给函数。如果你真的想要一个指针将它设置为nil,你需要将它作为PByteArray传递......但是你还需要传递数组的大小。

答案 2 :(得分:2)

对于静态数组,在运行时没有关于它们长度的信息,但仅在编译时。

因此,如果在将静态数组传递给函数时丢失类型信息,则无法找到函数内数组的长度。

=>如果要使用具有可变大小的静态数组,则必须将大小作为附加参数传递。

干净的方法是使用指针aritmetic而不是数组。

PByte = ^byte;
procedure Init(arr: PByte; len: Integer);
var
  i: Integer;
begin
  //Write 0, 1, 2 ... to arr
  for i:= 0 to len-1 do 
  begin
    arr^:= i;
    Inc(arr);
  end;
end;

不洁解决方案:

TByteArray = array [0..$FFFFFFFF] of Byte;
PByteArray = ^TByteArray;

procedure Init(arr: PByteArray; len: Integer);
begin
  arr^[0]:= 0;
  arr^[1]:= 1;
  ...
end;

...
var
  myAray: array[0..10] of byte;
begin
  Init(PByteArray(@myArray[0]), 10);
end;

答案 3 :(得分:1)

首先宣布这个

procedure Init(x: array of byte);

您正在使用动态数组 open array参数而不是static array。 要将静态数组作为参数传递,必须定义类型

像这样

type
  Arr15      = array [0..15] of byte;

然后声明这样的过程,使用关键字var通过引用传递。

procedure Init(var x: Arr15);

关于nil assign,你不能设置为static array

另一种选择是使用dynamic array 检查此样本

type
  ByteArray  = array of byte; 

procedure Init(var x : ByteArray);
const
 LenArray=15;
var
  i       : Byte;
begin
  SetLength(x,LenArray); //alocate the memory and set the length of the array.

  for i:=0 to LenArray-1  do //fill the array
     x[i]:=i;

   Writeln(Length(x)); //show the len of the array
   SetLength(x,0); //now dealocates de memory
   Writeln(Length(x)); //show the len of the array again 
end;

Var
  myArray : ByteArray;
begin
  try
     Init(myArray);
     Readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
相关问题