有两个函数:
fucntion selqry( qry: TQuery; strSQL: string): integer;//执行sql语句,返回数据集的条数
fucntion selqry( var qry: TQuery; strSQL: string): integer;//执行sql语句,返回数据集的条数
这两个函数功能一致,唯一的不同是,第一个参数,分别是传值和传引用。今天偶然翻翻《参透 delphi/kylix》,关于参数传值和传引用部分,好像是说,传引用不会给参数分配额外的空间,使用的是引用的内存空间;而传值会给参数在函数内分配一块内存空间,将值赋给参数。
我在cpu窗口下看了看两个函数的汇编代码,基本一致,就是传值  mov .. ebx,传引用 mov ..[ebx],
没有什么不同。
另外delphi 中的对象都是对象指针,根据这一点,我觉得上面两个函数应该是一样的。
我想问问高手的是,传值的函数会比传引用的函数多占用内存空间吗?那个更好一些?
谢谢!

解决方案 »

  1.   

    传值会给变量copy一个副本进行操作, 而传引用就是传一个对像的引用,这样, 没有这个副本就没有额外的空间了, 传引用还可以改变传递的对像的状态!
      

  2.   

    你还是选第一种,因为参量局部化,用完就销毁,这才是正理。本来就是一个写函数的基本思路。不是特殊应用,不要轻易使用原来的参数,尽量不使用var,能用const尽量用const。你考虑入口了,你有没有考虑回去?也就是函数执行完毕之后?如果你修改了,返回之后,如果有处理代码,寄存器做出了修改,自然就有保护寄存器的入栈代码。希望这样吗?可变参量和Result函数使用的寄存器冲突?register方式,你的第一个参数自然入ebx寄存器,如果只有一个参数呢?结果是eax保存的是Result,[eax]保存的是你的可变参数。尽管没有什么冲突,但你希望这样吗?感觉上是优化,其实总在使用一两个地方,就像在一些代码里使用几个全局变量没有什么区别。即便寄存器编译器会给你保护,但你就得时时刻刻注意你这个可变参量的变化,不知道什么时候,你就会忘记了哪个地方修改。不要管那么多优化的事情,不需要优化所谓的空间。函数执行完毕,空间自然回收。在乎吗?维护代码重要还是空间重要?
      

  3.   

    另外,如果按你说的:没有什么不同。那还专门加这么一个关键字var干吗?Vcl那么多代码,统统都用var的方式传值就是了。你有没有想到?如果没有什么不同,大家为什么不都用var?可以剩空间!你看书不看重点,看到这个了…… 那不是剩空间。老用var,那不但模块化设计保证不了,更何况对象化设计,纯粹的空谈。用C语言来解释局部参数,老的声明方式:void a(b)
      int b;
    {
      b = 1;
    }现在的声明方式void a(int b)
    {
      b = 1;
    }这就是上面所说的多出来的空间,声明一个局部参数自然就有分配的空间唉,你看完就是了,在乎这么多??????
      

  4.   

    主要要看你想对其要做什么?
     对比比较大的对象<包括自定义类型>  一般是传引用 因为较大的对象拷贝时就需要更多的空间,时间, 如果要修改的话 就用var aaa:TAAA;如果不修改 就用const aaa:TAAA,
    如果是自定义类型的话 可以定义指针类型 传指针也是一个不错的选择。
      

  5.   

    就是传值  mov .. ebx,传引用 mov ..[ebx]
    ---------------------
    这还叫没区别?一个是ebx,一个是[ebx]
    就像
    P: ^Record;
    那么
      P := @aRecord; 

      new(p); 
      P^ := aRecord'
    怎么会一样呢?
    在Delphi里一般是不需要考虑传递参数这样的损耗的,因为大量使用了对象引用。Delphi规范中只是建议字符串最好加上Const来改进性能,不过我也从来没真正实行过。完全没有必要为了空间考虑来讨论这两者的不同,重要的还是语义上的差别。
      

  6.   

    >>你还是选第一种,因为参量局部化,用完就销毁,这才是正理。对象好像不是这样吧
      

  7.   

    fucntion selqry( qry: TQuery; strSQL: string): integer;//执行sql语句,返回数据集的条数
    fucntion selqry( var qry: TQuery; strSQL: string): integer;//执行sql语句,返回数据集的条数
    第一,楼主的这两句语句是一样的.
    大一看是有些不同.但是把一个对象作为参数,其实就是传的是一个指针.所以使用var 和不使用 var 是一样的.
    fucntion selqry( qry: TQuery; const strSQL: string): integer;//执行sql语句,返回数据集的条数这想这样会好一些.这是从DELPHI算法数据结构上看到的.请参考.说的不一定对.
      

  8.   

    错了
    两个是不同的
    你试试在函数里创建这个Query,再在外面使用就知道了。
      

  9.   

    [ebx]毕竟传递的是内容。指针指向的内容。ebx 传递的是指针本身。本身就是两码事,看一下debug inspector,不用var,传过来是ebx,用了var,传过来的是,是那个对象指针的地址。asj的例子很直接,说的就是这个意思。
      

  10.   

    也就是说,传值即使产生一个复本,也只是一个指针的复本,right?
      

  11.   

    我真的不想再参与这个问题了,如果你有汇编的基础。你大可以参照汇编的机理仔细研究一下。如果你还认为ebx和[ebx]没有什么区别?我只能劝你去补习一下……