获取自定义类型数组的长度

时间:2014-01-15 07:59:41

标签: arrays delphi types dynamic-arrays

我想获取声明为自定义类型的数组的长度,并将自定义类型声明为数组。我遵循这条路线允许我传递数组作为参考。

这是我的代码:

type
    TDLLPointerReference = Record
        Pointer  : Pointer;
        IconName : Integer;
        DLLType  : TDLLType;
    end;

type
 TReffArray = array of TDLLPointerReference;

//compressor array's
    PARCompressors : TReffArray;
    PAROnCompressors : TReffArray;
    PARBaseCompressors : TReffArray;
    PARReserveCompressors : TReffArray;
    PARUnavailableCompressors : TReffArray;

function TCompressorPrioritiser.GetCompListLength(Aname : string250): integer;
var
i, k : integer;
begin
    i := ConvertStringtoIndex(AName);   //function to translate comp name to index
    case i of
        0 : k := length(PARCompressors);
        1 : k := length(PAROnCompressors);
        2 : k := length(PARBaseCompressors);
        3 : k := length(PARReserveCompressors);
        4 : k := length(PARUnavailableCompressors);
    else k := 0;
    end;
    result := k;//does not executes

    //test code begin Only added afterward
    PARUnavailableCompressors[1].Pointer := 0;  //executes
    k := length(PARUnavailableCompressors);     //executes
    i := k; //does not executes
    result := 5; //executes
    //test code ends
end;

此函数负责自定义类型的数组。

procedure TCompressorPrioritiser.MoveComp(AIndex : integer; var ACompListOut : TReffArray;var ACompListIn : TReffArray);
var
i : integer;
begin
//This will move a compressor at the index in ACompListOut to  ACompListin
    setlength(ACompListIn, length(ACompListIn)+1);
    ACompListIn[length(ACompListIn)-1] :=  ACompListOut[AIndex];
    For i := Aindex to length(ACompListOut)-2 do
    begin
        ACompListOut[i] := ACompListOut[i+1];
    end;
    setlength(ACompListOut, length(ACompListOut)-1);
end;

有没有办法可以获得数组长度? 或者更改底部函数,以便我可以将数组作为参数发送。

主要问题是我标记为不编译的行,似乎没有运行。当我设置断点时,只会跳过这些代码行,并且无法在那里设置断点。因为我想要做的是获得数组的长度。该函数假设返回它,但它跳过返回函数。另外,如果添加一个观察变量k,delphi告诉我K对于优化是不可用的,尽管它只是使用了它的后退线。当我向var i添加一个手表时也会发生同样的情况。

我做了一些进一步的测试。现在每行执行的函数的第一个版本。行结果的第二个版本:= k不执行,为什么会这样?

第1版

function TCompressorPrioritiser.GetCompListLength(Aname : string250): integer;
var
i, k : integer;
begin
    i := ConvertStringtoIndex(AName);   //function to translate comp name to index
    case i of
        0 : k := length(PARCompressors);
        1 : k := length(PAROnCompressors);
        2 : k := length(PARBaseCompressors);
        3 : k := length(PARReserveCompressors);
        4 : k := length(PARUnavailableCompressors);
    else k := 0;
    end;
    result := k;//executes

    //test code begin
    k := length(PARUnavailableCompressors);     //executes
    //test code ends
end;

2版

function TCompressorPrioritiser.GetCompListLength(Aname : string250): integer;
var
i, k : integer;
begin
    i := ConvertStringtoIndex(AName);   //function to translate comp name to index
    case i of
        0 : k := length(PARCompressors);
        1 : k := length(PAROnCompressors);
        2 : k := length(PARBaseCompressors);
        3 : k := length(PARReserveCompressors);
        4 : k := length(PARUnavailableCompressors);
    else k := 0;
    end;
    result := k;//does not executes

    //test code begin
    //k := length(PARUnavailableCompressors);     
    //test code ends
end;

编辑 将压缩器更改为阵列。它是对压缩器的一系列引用,没有正确输入抱歉。

EDIT2 在底部添加了问题陈述

EDIT3 更改了代码以反映建议的代码更改。并增加了进一步测试的次要部分。

EDIT4

我得到了代码可以工作,我得到了我正在寻找的结果,但我也没有得到为什么我需要这一行:“k:= length(PARUnavailableCompressors); //执行”它没有任何目的但没有它行,“result:= k”行不执行。如果我用K:= 6替换K:=长度线,结果:= k line也不会执行。那我为什么还需要其他那条线?

function TCompressorPrioritiser.GetCompListLength(Aname : string250): integer;
var
i, k : integer;
begin
    k := 0;
    i := ConvertStringtoIndex(AName);   //function to translate comp name to index
    case i of
        0 : k := length(PARCompressors);
        1 : k := length(PAROnCompressors);
        2 : k := length(PARBaseCompressors);
        3 : k := length(PARReserveCompressors);
        4 : k := length(PARUnavailableCompressors);
    else k := 0;
    end;
    result := k;
    k := length(PARUnavailableCompressors);     //Withint this line code above line does not execute
    //k :=6;  // this does not have the same effect as the above line
end;

2 个答案:

答案 0 :(得分:0)

要获取类型数组的长度,请使用Length方法:

type
    TTestRecord = record
        Id: Integer;
        Name: String;
    end;

    TTestRecordArray = array of TTestRecord;

...

procedure TForm1.btnTestClick(Sender: TObject);
var
    myArray: TTestRecordArray;
    mySize: Integer;
begin
    SetLength( myArray, 100 );
    ShowMessage( IntToStr( Length( myArray ) ) );
end;

但这已经是你在MoveComp中所做的事了,所以其他地方出了问题。并且i := k;编译当i和k是整数时,无论如何,所以你的调试逻辑对我来说似乎不对...

编辑>>根据您更新的问题,您的问题是在执行期间似乎跳过Result := k;行。我会期待这种行为,因为之后你有Result := 5;行,所以编译器不需要为你的Result := k;而烦恼。删除//test code begins//test code ends之间的代码,看看现在发生了什么......

答案 1 :(得分:0)

使用Length()查找数组的长度。

您无法在标记的行上设置断点的原因是编译器已将它们优化掉。编译器已确定它们没有任何影响。

例如,您为Result分配了一个值,然后在Result中为Result分配了不同的值,而在此期间没有从i读取。因此,第一项任务毫无意义,可以删除。

i的分配是一样的。您没有在赋值后执行的任何代码中引用局部变量k,并且由于赋值没有副作用,因此可以将其删除。编译器会警告你这一点。我希望你已启用警告并注意它们。

在编译器选项中禁用优化将阻止编译器切除这些代码行。


关于您的第二次更新,优化程序再次让您感到困惑。编译器检测到变量Result是多余的,并直接分配给function TCompressorPrioritiser.GetCompListLength(Aname : string250): integer; begin case ConvertStringtoIndex(AName) of 0 : Result := length(PARCompressors); 1 : Result := length(PAROnCompressors); 2 : Result := length(PARBaseCompressors); 3 : Result := length(PARReserveCompressors); 4 : Result := length(PARUnavailableCompressors); else Result := 0; end; end; 。你可以这样编写这个函数:

ACompListOut

我还必须指出out被错误地声明为var参数。由于您在函数内部读取它,因此必须将其声明为string


我还建议可能是时候停止使用短字符串并转到{{1}}。