关于动态数组和静态数组的问题(50分)

  • 主题发起人 主题发起人 CADVector
  • 开始时间 开始时间
C

CADVector

Unregistered / Unconfirmed
GUEST, unregistred user!
DELPHI中的动态数组可以再使用的时候动态分配内存,比如
var
a1:array of integer;
a2:array[0..1] of integer;
begin
setlength(a1,2);
a2[0]:=1;
a2[0]:=2;
a1:=@a2;//把A2的首地址赋给A1
a1:=@a2[0];//把A2的首地址赋给A1
//这里这两句话实现的功能一样.说明静态数组的数组名中存着这个数组的第一个元素,
那么再执行
f.write(a2,sizeof(integer)*2);//这句话可以将A2中的数据写入一个文件
而 f.write(a1,sizeof(integer)*2);//这句话只能将A1中每个元素的地址写入到文件中
如果要实现与f.write(a2,sizeof(integer)*2);同样的功能,需要该成
f.write(a1[0],sizeof(integer)*2);
这说明write 函数中第一个参数必须传一个缓存的第一个字符,而不是缓存的地址

end;
以上的解释不知道对不对,望高手指点
本人还有一个疑问:
procdure aaa(var a:array of integer)
var
i,iCount:integer;
begin
iCount:=High(a);
for i:=0 to iCount do
begin
a:=10;
end;

end;
procdure bbb( a:array of integer)
var
i,iCount:integer;
begin
iCount:=High(a);
for i:=0 to iCount do
begin
a:=10;
end;

end;
procedure ccc;
var
a:array of integer;
b:array[0..2] of integer;
begin
setlength(a,2);
aaa(b);//该过程可以将b内容修改,因为是引用参数,将B的地址传给了函数AAA的参数
bbb(b);//该过程不能修改b中的内容,因为是传数值,是将B中的内容复制给了函数BBB中的参数
aaa(a);//该过程也能将a的内容修改,
bbb(a);//将a 中的值传给了BBB函数中的参数,那么因为a本来就是地址,也应该可以修改a中的内容,但实际情况不行,为什么
end;
问题:
bbb(a);//将a 中的值传给了BBB函数中的参数,那么因为a本来就是地址,也应该可以修改a中的内容,但实际情况不行,为什么
 
其实很简单, 你只需要把动态数组看作是一个数组的指针就行了
只是它带有自动内存管理功能

对静态数组取地址,取到的是数组数据的地址
对动态数组变量取地址,取到的是一个指针的地址

在函数中传递动态数组,也就是传递数组指针,当然全都是引用的

如果两个动态数组变量引用了同一个动态数组,
则修改其中的一个, 也就修改了另一个,
因为他们引用的是同一个东西

这些在Delphi 的帮助中写的清清楚楚
 
to:lich
你说道我也是这么认为的,但是我不是说了上面的问题吗?
当我使用动态数组做为参数传递时,在函数中只能有VAR,引用参数才能修改原动态数组,如果是传值的就不能修改原来的动态数组,所以感觉奇怪啊
本人还有一个疑问:
procdure aaa(var a:array of integer)
var
i,iCount:integer;
begin
iCount:=High(a);
for i:=0 to iCount do
begin
a:=10;
end;

end;
procdure bbb( a:array of integer)
var
i,iCount:integer;
begin
iCount:=High(a);
for i:=0 to iCount do
begin
a:=10;
end;

end;
procedure ccc;
var
a:array of integer;
b:array[0..2] of integer;
begin
setlength(a,2);
aaa(b);//该过程可以将b内容修改,因为是引用参数,将B的地址传给了函数AAA的参数
bbb(b);//该过程不能修改b中的内容,因为是传数值,是将B中的内容复制给了函数BBB中的参数
aaa(a);//该过程也能将a的内容修改,
bbb(a);//将a 中的值传给了BBB函数中的参数,那么因为a本来就是地址,也应该可以修改a中的内容,但实际情况不行,为什么
end;
问题:
bbb(a);//将a 中的值传给了BBB函数中的参数,那么因为a本来就是地址,也应该可以修改a中的内容,但实际情况不行,为什么
 
看看下面的代码:
function Test1(a: TIntArray): Integer;
begin
a[0] := 100;
end;

function Test2(var a: TIntArray): Integer;
begin
a[0] := 100;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
a: TIntArray;
b: array[0..20] of Integer;
begin
SetLength(a, 20);
a[0] := 5;
Test1(a);
ShowMessage(IntToStr(a[0]));

a[0] := 5;
Test2(a);
ShowMessage(IntToStr(a[0]));
end;

符合我所说的情况
 
补充一下:

function Test2(var a: array of Integer): Integer;
begin
SetLength(a, 200);
a[0] := 100;
end;

这个函数的第一行代码是无法编译通过的

也就是说,在函数的参数中:
声明:
type
TIntArray = array of Integer;

a1: array of Integer;
a2: TIntArray;

是不同的,a2会被当作动态数组来处理,和字符串的情况类似
符合我上面所说的情况

但对于 a1 ,不过调用时,参数是怎么传递的,全都会被当作静态数组来处理
(因为静态数组和动态数组在内存中是兼容的)
如果不声明为变量 var 参数,则函数内部会在栈上建立一个同等大小的数组,
并复制原数组的内容

如果声明为变量参数,则函数内部直接将传入的数组作为静态数组
(因为他们的内存表达是兼容的)
调用时,都传递了数据的数据区的地址和数组的长度

所以, 千万不要以为这两种声明方法是等效的, 他们完全不同
 
function Test2(var a: array of Integer): Integer;
begin
SetLength(a, 200);
a[0] := 100;
end;

这个函数的第一行代码是无法编译通过的
我可以通过的啊???
但是如果声明:
type
TIntArray = array of Integer;
那么可以理解了,但是当不声明该类型的时候就有点理解不通了
 
接受答案了.
 
后退
顶部