回 帖 发 新 帖 刷新版面

主题:Dephi参数传递

Dephi中的参数传递有哪些
什么样的是值传递,什么样的是址传递

回复列表 (共9个回复)

沙发

首先,

procedure Test(Const X: TX);//这样的,和
procedure Test(Var X: TX);//这样的,都是传址

然后,

procedure Test(X : TX);//这样的,又分几种情况:

TX 如果是简单类型,就是传值,如 integer、Double、Char等
string类型是传址(较复杂)

TX 如果是类类型,就是传址。如:
procedure Test(Sender: TObject);


我是第一次这样总结,可能有漏或错。

板凳

给你一个简单的实例比较容易理解
参数传递有返回结果区分
1、不返回结果的
过程:
procedure test(str:string);
{这边提供参数可以根据自己的要求确定,也可以同时提供多个参数}
begin
  showmessage(str);
end;
调用:
procedure TForm1.button1click(Sender: TObject);
begin
  test('delphi')
end;
2、返回值
  Function test(i:integer):integer;
  begin
   i:=i+10;
   Result:=i;
  end;
procedure TForm1.button1click(Sender: TObject);
begin
  edit1.text:=test(5')
end;

3 楼

//最后一个调用应该是下面的。刚刚笔误
procedure TForm1.button1click(Sender: TObject);
begin
  edit1.text:=test(5)
end;

4 楼

[quote]首先,

procedure Test(Const X: TX);//这样的,和
procedure Test(Var X: TX);//这样的,都是传址

然后,

procedure Test(X : TX);//这样的,又分几种情况:

TX 如果是简单类型,就是传值,如 integer、Double、Char等
string类型是传址(较复杂)

TX 如果是类类型,就是传址。如:
procedure Test(Sender: TObject);


我是第一次这样总结,可能有漏或错。[/quote]
的确有错误~~
首先 string是传值,虽然他是个引用类型。这个比较特殊,(操作符重载,很好理解)。
不能笼统地说类类型~准确的应该说:引用类型。

5 楼

//控件的传递
function NoValue(AnEditBox:TEdit):Boolean;
begin
  if AnEditBox.Text='' then
     begin
       AnEditBox.Color := clRed;
       AnEditBox.Text := '请输入整数值';
       Result := True;
     end
  else
     begin
       AnEditBox.Color := clWindow;
       Result := False;
     end;
end;

function tt(t1,t2:integer):integer ;
begin
  result:=t1*t2;  {也可用tt:=t1*t2代替,效果一样}
end;

6 楼

to xiaohongna:

首先 string是传值,虽然他是个引用类型。这个比较特殊,(操作符重载,很好理解)。

-------------------

请讲解一下“操作符重载,很好理解”

另外,string类型并不是传值的。String类型使用Copy on Write技术,是传址的。

7 楼

TO Xiaohongna :

简单在做个测试,然后用CPU窗口反汇编看一下即可明白,String类型是传址:

procedure XX(X: string);
begin
  Showmessage(X);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Str : string;
begin
  Str := InttoStr(Self.Handle);
  XX(Str);
end;

下面是procedure TForm1.Button1Click(Sender: TObject);的部分汇编助记符:

0045213A 8BC3             mov eax,ebx
0045213C E8F75AFEFF       call TWinControl.GetHandle
00452141 33D2             xor edx,edx
00452143 52               push edx
00452144 50               push eax
00452145 8D45FC           lea eax,[ebp-$04] ///
00452148 E8775CFBFF       call IntToStr     /// !!

0045214D 8B45FC           mov eax,[ebp-$04]
00452150 E887FFFFFF       call XX          ///!!

下面是procedure XX(X: string);的部分汇编助记符:

004520DC 55               push ebp
004520DD 8BEC             mov ebp,esp
004520DF 51               push ecx
004520E0 8945FC           mov [ebp-$04],eax
004520E3 8B45FC           mov eax,[ebp-$04]
004520E6 E81122FBFF       call @LStrAddRef  ////!!
004520EB 33C0             xor eax,eax
004520ED 55               push ebp
004520EE 6817214500       push $00452117
004520F3 64FF30           push dword ptr fs:[eax]
004520F6 648920           mov fs:[eax],esp

004520F9 8B45FC           mov eax,[ebp-$04]
004520FC E86352FDFF       call ShowMessage  /////!!

8 楼

[quote]to xiaohongna:

首先 string是传值,虽然他是个引用类型。这个比较特殊,(操作符重载,很好理解)。

-------------------

请讲解一下“操作符重载,很好理解”

另外,string类型并不是传值的。String类型使用Copy on Write技术,是传址的。[/quote]
那我问你string默认的是传值得,那对原变量会不会有影响啊?你说了copy on write技术,那不就是相当于把原字符串复制一份新的在函数里面是用吗?
我知道这里的string变量是指针,它是对象当然就是指针了,不要给别人误导。对string类型的都是引用,但是在作为普通参数的时候 他会copy一份新的string 然后再把这个新的传体给函数,所以他的效果是传值。你没有发现个函数外面和函数里面的string是不同的两个string?
参数的传递类型最明显的区别就是会不会对原变量产生影响。

9 楼

呵呵,你说话的语气好激烈啊。

Copy On Write 技术,并不是说“把原字符串复制一份新的在函数里面是用”,Delphi编译器和Delphi的内存管理没有这么笨拙。当然,字符串类型“引用计数”的机制,与传址、传值的讨论,可能是擦边的,嘿嘿,对不起了。

之所以我一开始说:

TX 如果是简单类型,就是传值,如 integer、Double、Char等
string类型是传址(较复杂)

是为了让贴主知道:String类型的处理与integer等简单类型是不同的,因为String类型事实上在内部的实现上是传址的,并不是简单地把参数“值”压栈或放入寄存器。

这就是我们的分歧所在:看问题的角度不一样。
而你说的,是比较正统的;我有点走偏门了哈,对不起了各位。

我来回复

您尚未登录,请登录后再回复。点此登录或注册