专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Delphi教程 » delphi数组:Delphi2005学习笔记3——数组参数的研究 »正文

delphi数组:Delphi2005学习笔记3——数组参数的研究

来源: 发布时间:星期四, 2009年2月12日 浏览:181次 评论:0



有如下代码:
procedure Change(a:.gif' /> of Int32);
procedure Change0(var a:.gif' /> of Int32);
type
Ta = .gif' />[0..10] of Int32;
procedure Change2(a:Ta);
procedure Change3(var a:Ta);

var
aa:Ta;
bb:.gif' /> of Int32;

implementation

{$AUTOBOX _disibledevent=> a:=bb;
end;

procedure Change0(var a:.gif' /> of Int32);
begin
a[0]:=123;
a:=bb;
end;

procedure Change2(a:Ta);
begin
a[0]:=123;
a:=bb;
end;

procedure Change3(var a:Ta);
begin
a[0]:=123;
a:=bb;
end;

然后执行下面语句
SetLength(bb,11);bb[0]:=5678;

aa := Ta(&Array.CreateInstance(typeof(Int32),11));
aa[0]:=0;
Change(aa);
MessageBox.Show(aa[0].);
&Object(aa)=&Object(bb) then MessageBox.Show(\'=\');

aa := Ta(&Array.CreateInstance(typeof(Int32),11));
aa[0]:=0;
Change0(aa);
MessageBox.Show(aa[0].);
&Object(aa)=&Object(bb) then MessageBox.Show(\'=\');

aa := Ta(&Array.CreateInstance(typeof(Int32),11));
aa[0]:=0;
Change2(aa);
MessageBox.Show(aa[0].);
&Object(aa)=&Object(bb) then MessageBox.Show(\'=\');

aa := Ta(&Array.CreateInstance(typeof(Int32),11));
aa[0]:=0;
Change3(aa);
MessageBox.Show(aa[0].);
&Object(aa)=&Object(bb) then MessageBox.Show(\'=\');
结果发现 .gif' /> of Int32 方式可以改变元素但不能改变变量中存储首地址输出123
var .gif' /> of Int32 既可以改变又可以改变变量中存储首地址输出5678和=
Ta方式不能改变元素但是却很奇怪aa和bb指向同输出0和=
var Ta方式 可以改变元素但是却不是5678而是123;但是aa和bb指向同输出123和=


反汇编结果如下
method public void Change(32 a) cil managed
{
// Code Size: 13 (s)
.maxstack 3
L_0000: ldarg.0
L_0001: ldc.i4.0
L_0002: ldc.i4.s 123
L_0004: stelem.i4
L_0005: ldsfld 32 WinForm.Units.WinForm::bb
L_000a: starg.s a
L_000c: ret
}



.method public void Change0(32& a) cil managed{ // Code Size: 14 (s) .maxstack 3 L_0000: ldarg.0 L_0001: ldind.ref L_0002: ldc.i4.0 L_0003: ldc.i4.s 123 L_0005: stelem.i4 L_0006: ldarg.0 L_0007: ldsfld 32 WinForm.Units.WinForm::bb L_000c: stind.ref L_000d: ret }

.method public void Change2(32 a) cil managed{ // Code Size: 42 (s) .maxstack 4 .locals ( 32 num1) L_0000: ldarg.0 L_0001: callvirt

instance object [mscorlib].Array::Clone L_0006: cast 32 L_000b: starg.s a L_000d: ldarg.0 L_000e: ldc.i4.0 L_000f: ldc.i4.s 123 L_0011: stelem.i4 L_0012: ldsfld 32 WinForm.Units.WinForm::bb L_0017: dup L_0018: ldlen L_0019: stloc.0 L_001a: ldarg.0 L_001b: ldloc.0 L_001c: ldc.i4.s 11 L_001e: ble.s L_0023 L_0020: ldc.i4.s 11 L_0022: stloc.0 L_0023: ldloc.0 L_0024: call void [mscorlib].Array::Copy([mscorlib].Array, [mscorlib].Array, 32) L_0029: ret }




.method public void Change3(32& a) cil managed{ // Code Size: 31 (s) .maxstack 4 .locals ( 32 num1) L_0000: ldarg.0 L_0001: ldind.ref L_0002: ldc.i4.0 L_0003: ldc.i4.s 123 L_0005: stelem.i4 L_0006: ldsfld 32 WinForm.Units.WinForm::bb L_000b: dup L_000c: ldlen L_000d: stloc.0 L_000e: ldarg.0 L_000f: ldind.ref L_0010: ldloc.0 L_0011: ldc.i4.s 11 L_0013: ble.s L_0018 L_0015: ldc.i4.s 11 L_0017: stloc.0 L_0018: ldloc.0 L_0019: call void [mscorlib].Array::Copy([mscorlib].Array, [mscorlib].Array, 32) L_001e: ret }
结论:
使用.gif' /> of Int32 方式实际上对应于C#可变数目参数即 params Int32
这种参数方式是传递首地址(即参数值)而不是存放首地址变量地址
加上Var修饰即加入ref修饰传递是存放首地址变量地址(即参数变量自身地址)







使用Ta方式则在内部对值进行克隆既不改变首地址也不改变原
加入var 修饰好像传递是变量自身地址这里还是没看懂是为什么





对应C#代码为

public void Change(params a){ a[0] = 0x7b; a = WinForm.bb;}




public void Change0(params ref a){ a[0] = 0x7b; a = WinForm.bb;}




public void Change2( a){ a = () a.Clone; a[0] = 0x7b; num1 = WinForm.bb.Length; (num1 > 11) { num1 = 11; } Array.Copy(WinForm.bb, a, num1);}




public void Change3(ref a){ a[0] = 0x7b; num1 = WinForm.bb.Length; (num1 > 11) { num1 = 11; } Array.Copy(WinForm.bb, a, num1);}









0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: