Delphi数组索引边界

时间:2017-03-22 21:18:04

标签: arrays delphi

我想看看delphi是如何管理数组的,我已经创建了这种代码(使用Delphi 10 Seattle和VCL):

procedure TForm1.Button1Click(Sender: TObject);
var a: array[1..8] of integer;
    i: integer;
    res: string;
begin

try

 for i := 1 to 8 do
  a[i] := i*i;

 Memo1.Clear;
 res := '';

 for i := 1 to 8 do
  begin
   res := res + a[i].toString + ' ';
  end;

 Memo1.Lines.Add(res);

except
 on E: Exception do
  showmessage(E.Message);
end;

end;

我已经知道我可以使用Low()High()来安全地选择下限和上限。我不得不制作一个程序,我不能使用这两个函数,而是必须使用整数变量(在其他地方计算)。

我发现了这种奇怪的行为。上面的代码产生了这个输出:

  

1 4 9 16 25 36 49 64

当我尝试将两个循环的边界更改为1和9时(对于i:= 1到9)我有这个:

  

1 4 9 16 25 36 49 64 81

为什么这不会引发异常?我已声明为[1..8]。当我将边界设置为1和10(对于i:= 1到9)时,异常会像我期望的那样被提出。

我也知道C++并且我知道即使在声明中指定了数组绑定也没有控制,因此for循环可以继续超过限制。就像我可以拥有

int a[5] = {};

for(int i=0; i<20; i++) {
 a[i] = i;
}

这不会给我一个错误(主要是因为[i]是指针*(a + i))。 delphi数组是否也用poineters实现,但是使用范围检查?

修改

当我使用此代码时:

procedure TForm1.Button1Click(Sender: TObject);
var a: array[5..8] of integer;
    i: integer;
    res: string;
begin

try

 for i := 1 to 8 do
  a[i] := i*i;

 Memo1.Lines.Clear;
 res := '';

 for i := 1 to 8 do
  begin
   res := res + a[i].toString + ' ';
  end;

 Memo1.Lines.Add(res);

except
 on E: Exception do
  showmessage(E.Message);
end;

end;

我有下面的输出看起来不正确因为边界是5..8但是我正在做一个从1到9的循环。

  

1 4 9 16 25 36 49 64

1 个答案:

答案 0 :(得分:7)

  

为什么这不会引发例外?

您可能没有启用Range Checks

  

{$R+}状态下,所有数组和字符串索引表达式都被验证为在定义的范围内,并且对标量和子范围变量的所有赋值都将在范围内进行检查。 **如果范围检查失败,则引发ERangeError异常(或者如果未启用异常处理则终止程序)。

默认情况下,范围检查为OFF。要启用它,您可以将此指令添加到您的代码中:

{$RANGECHECKS ON}

或者您可以在“Delphi编译器|编译|运行时错误”下的“项目选项”中启用它。