線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1012
推到 Plurk!
推到 Facebook!

procedure Test(A: string);改成var A: string有何不同?

尚未結案
lovelypp
初階會員


發表:122
回覆:111
積分:46
註冊:2003-02-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-07-20 11:02:35 IP:218.2.xxx.xxx 未訂閱
参数 A:string
lovelypp
初階會員


發表:122
回覆:111
積分:46
註冊:2003-02-19

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-07-20 11:05:27 IP:218.2.xxx.xxx 未訂閱
对不起,还没有打完按错按钮了: 参数 A:string; var A: string; const A:string 有何不同?
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-07-20 13:15:39 IP:202.39.xxx.xxx 未訂閱
女下剪自 delphi 的 help:
// X 是傳值
function DoubleByValue(X: Integer): Integer; // X is a value parameter
begin
  X := X * 2;
  Result := X;
end;    // X 是傳址
function DoubleByRef(var X: Integer): Integer; // X is a variable parameter
begin
  X := X * 2;
  Result := X;
end;    var
  I, J, V, W: Integer;
begin
  I := 4;
  V := 4;
  J := DoubleByValue(I);   // J = 8, I = 4用傳值的方式, I 的值不變
  W := DoubleByRef(V);     // W = 8, V = 8用傳址的方式, I 的值會變
end;
而 const A: string 的方式表示 A 這個參數的值是唯讀的, 不能修改 -- 向 KTop 的弟兄們致敬! 發表人 - hagar 於 2004/07/20 13:18:10
lovelypp
初階會員


發表:122
回覆:111
積分:46
註冊:2003-02-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-07-20 17:15:10 IP:218.2.xxx.xxx 未訂閱
兄弟,如果不是传Integer而是类如TComponent呢?
lovelypp
初階會員


發表:122
回覆:111
積分:46
註冊:2003-02-19

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-07-20 17:17:30 IP:218.2.xxx.xxx 未訂閱
这时情况又如何? A: TComponent; var A: TComponent; const A: TComponent;
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-07-20 17:53:51 IP:202.39.xxx.xxx 未訂閱
procedure ValueParameter(btn: TButton);
begin
  btn.Caption := 'Value Parameter';
  btn := Form1.Button2; // 這行會出現 Value assignd to 'btn' never used,第二次按 Button1, Button2 的 Caption 不會變 'Value Parameter'
end;    procedure VarParameter(var btn: TButton);
begin
  ShowMessage(btn.Caption);
  btn.Caption := 'Var Parameter';
  btn := Button2; // 此時第二次按 Button1, Button2 的 Caption 會變 'Value Parameter'
end;    procedure ConstParameter(const btn: TButton);
begin
  btn.Caption := 'Const Parameter';
  btn := Button2; // 這行會出現 "Left Side cannot be assiged to" 的 Error, 表示用 const 的 btn 參數值不能修改
end;    procedure TForm1.Button1Click(Sender: TObject);
begin
  ValueParameter(Button1); // 這行測試 Value Parameter
  //VarParameter(Button1); // 這行測試 Variable Parameter
  //ConstParameter(Button1); // 這行測試 Const Parameter
end;    procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowMessage('Button2 Click');
end;
結果: 1.btn: TButton 第一次按 Button1 會改變 Button1 的 Caption, 第二次按 Button1 不會改變 Button2,可見 Button1 沒有指向 Button2 即 btn := Button2 所指向的位址在 procedure 結束後即無作用 2.var btn: TButton 第一次按 Button1 會改變 Button1 的 Caption, 第二次按 Button1 會改變 Button2,可見 Button1 有指向 Button2 可由第二次的 ShowMessage(btn.Caption); 的結果得知 不過小弟覺得奇怪的是, 既然 Button1 已經指向 Button2 了 為何第二次按 Button1 時,不會觸發 Button2Click? 3.const btn: TButton 第一次按 Button1 會改變 Button1 的 Caption 且 btn 這參數所指向的位址不能改變 -- 向 KTop 的弟兄們致敬!
timhuang
尊榮會員


發表:78
回覆:1815
積分:1608
註冊:2002-07-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-07-21 00:09:15 IP:61.62.xxx.xxx 未訂閱
Hi, 引用 help 中的一段,    Parameter passing Variable (var) parameters are always passed by reference, as 32-bit pointers that point to the actual storage location. ... A pointer, class, class-reference, or procedure-pointer parameter is passed as a 32-bit pointer. 由上可知, class 變數也是和 passed by reference 一樣, 所以無論你的 class 變數在當做參數時, 是否有加上 var (variable parameters) , 皆是以 passed by reference 的方式傳入該 function 中. 至於 hagar 兄的測試, 應該要先解決 compiler 因為最佳化所略去的 statement 才能有效測出來效果, 由於在 ValueParameter 中的 btn := Form1.Button2; 之後沒有程式碼, 造成 compiler 在編譯最佳化的狀況下, 不進行該行程式的編譯, 為能達到正碼的測試結果, 可以簡單在該行後做一些動作即可, 如,
procedure ValueParameter(btn: TButton);
begin
  ShowMessage(btn.Caption);
  btn := Form1.Button2;
  btn.Caption := 'Value Parameter';
end;
如此一來測試的結果就會如同 var 的方式一般. 再來說明一下 hagar 兄所提紅色字的部分, 其實在 form 上的 Button1 變數只是一個指標, 所以將 Button1 := Button2 時, 就只是將 Button2 變數位址抄寫一份給 Button1, 所以原來的 Button1 的 event 當然還是不會變動, 還是執行原來的程式碼囉, 只是那原來的 Button1 實際的位址, 就永遠取不到囉. (其實不會啦, 仍舊可以利用 form 上的 component 來找到的啦..) 這樣說明不知道還清楚嗎? < src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=16750208&CC=374612">
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-07-21 09:01:12 IP:202.39.xxx.xxx 未訂閱
小弟印象之前承蒙 ha0009 的教導 其實 delphi 的物件變數名稱就是一個指標(pointer) 只是 delphi 已經幫我們動了手腳 所以存取物取時只需簡單如 s := Button1.Caption; 而不必如其它 pointer 的存取方式如 s := Button1^.Caption; 所以如 timhuang 兄所言, 是否有加上 var 關鍵字 皆是以傳 reference 的方式傳入 procedure / function 中 至於最佳化的問題的確在測試時沒想到 感謝 timhuang 兄的開示!  -- 向 src="http://www.sweetbaby.net/~hagar/good.bmp">
系統時間:2024-05-17 17:35:27
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!