转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
Delphi2005学习笔记3——数组参数的研究         ★★★★

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

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1365 更新时间:2009/4/23 18:28:21

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

var
  aa:Ta;
  bb:array of Int32;

implementation

{$AUTOBOX ON}

procedure Change(a:array of Int32);
begin
  a[0]:=123;
  a:=bb;
end;

procedure Change0(var a:array 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].ToString());
  if &Object(aa)=&Object(bb) then MessageBox.Show(''''='''');

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

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

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


反汇编结果如下
method public static void Change(int32[] a) cil managed
{
      // Code Size: 13 byte(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 int32[] WinForm.Units.WinForm::bb
      L_000a: starg.s a
      L_000c: ret
}

.method public static void Change0(int32[]& a) cil managed
{
      // Code Size: 14 byte(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 int32[] WinForm.Units.WinForm::bb
      L_000c: stind.ref 
      L_000d: ret 
}
.method public static void Change2(int32[] a) cil managed
{
      // Code Size: 42 byte(s)
      .maxstack 4
      .locals (
            int32 num1)
      L_0000: ldarg.0 
      L_0001: callvirt instance object [mscorlib]System.Array::Clone()
      L_0006: castclass int32[]
      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 int32[] 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]System.Array::Copy([mscorlib]System.Array, [mscorlib]System.Array, int32)
      L_0029: ret 
}


.method public static void Change3(int32[]& a) cil managed
{
      // Code Size: 31 byte(s)
      .maxstack 4
      .locals (
            int32 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 int32[] 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]System.Array::Copy([mscorlib]System.Array, [mscorlib]System.Array, int32)
      L_001e: ret 
}

结论:
使用array of Int32 方式,实际上对应于C#的可变数目参数,即 params Int32[],
这种参数方式是传递的数组的首地址(即参数的值),而不是存放数组首地址的变量的地址
加上Var修饰,即加入ref修饰,传递的是存放数组首地址的变量的地址(即参数变量自身的地址)







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





对应的C#代码为

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

public static void Change0(p

[1] [2]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台