array & SetLength(50分)

  • 主题发起人 主题发起人 savenight
  • 开始时间 开始时间
S

savenight

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure TForm1.Button1Click(Sender: TObject);
var
a:array of double;
begin
SetLength(a,3);
a[0]:=2.3;
a[12]:=38;
showmessage(floattostr(high(a)))
//*
showmessage(floattostr(a[12]));
end;

把带星号的这行注释掉,程序运行显示38,
但不注释,程序运行显示2.29342341234E-307。

请解释?
 
这么写是不对的,a[12]已经超出数组下标了,你为什么不定义长一点
 
同意楼上的。
 
你的程序有问题。
动态数组a大小为3,
因此你应该只可以访问a[0],a[1],a[2]

“把带星号的这行注释掉,程序运行显示38”
访问的是a[12]的值;
不注释掉,可能是在调用high(a)的时候编译器做了范围检查,但没有报错(为什么不报错,我也不知道),
于是阻止访问a[12]的值,只返回了a[12]地址。

 
我知道,我是让你们解释为什么?
 
yxyyyy,例子返回都是38,不知你要说什么?
 
显然是因为你使用为申请地址空间,a[12]:=38;
语句在a【2】之后的第10*sizeof(integer)上存储了数38
在你直接showmessage(floattostr(a[12]));时他能正确显示
但当你加上showmessage(floattostr(high(a)));时存储那个地址的空间被使用,所以显
示就不同了
你看这2个例子就知道了

procedure TForm1.Button1Click(Sender: TObject);
var
a:array of double;
begin
SetLength(a,3);
a[0]:=2.3;
a[3]:=38;
a[0] := 2
//*
showmessage(floattostr(a[3]));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
a:array of double;
begin
SetLength(a,3);
a[0]:=2.3;
a[100]:=38;
a[0] := 2
//*
showmessage(floattostr(a[100]));
end;

分别运行一下(加注释和不加注释)
在后一种情况下因为a[100]在比较后面,a[0] := 2;
这一句没有覆盖到,所以显示结果是一样的

 
在C中,数组越界是不检查的,而在PASCAL中是检查的。
然而,在D4开始引进了开放阵列(台湾的讲法)后,问题就不一样了
你无论调是否越界,系统只往内存里加,而不做检查(注)
由于访问的是非预分配资源,所以,可能覆盖掉现有的数据,也可能被别人所覆盖。
调用HIGH以后,可能进行了某种边界检测,所以访问发生了错误。
记得系统可以社定是否有越界检查的???忘记了
我会验证这个问题的。
 
CJ:多谢!
我已找到了:
project---->options--->compiler--->runtime error--->range checking
不过这是运行期,编译期好像找不到方法?
 
呵呵,编译器不可能检查出错误的:
setlength(i*2+3)
编译器不是神仙哦
 
呵呵呵,那就只能收摊了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部