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

关于函数的VAR参数设置

答題得分者是:st33chen
zhouying82
高階會員


發表:150
回覆:272
積分:189
註冊:2004-03-16

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-10-21 13:29:02 IP:218.80.xxx.xxx 訂閱

[code delphi]
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
function caculate(n:integer):integer;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
edit1.Text :=inttostr(caculate(10));
end;

function TForm1.caculate n: integer): integer;
begin
n:=n*10;
end;

end.
請在此區域輸入程式碼

[/code]
照规矩,按照参数原则,我是不是应该在函数参数前添加VAR ? 但是实际使用却出现以下错误。不加VAR倒是可以运行正常,什么原因啊?
[Error] Unit1.pas(30): Types of actual and formal var parameters must be identical
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'
是什么原因啊,不过不加VAR,编译可以通过,但是计算出来的结果不对,应该是100,而他却是142768?有哪位大大知道吗?急,小弟在线等。
------
断断续续的学了几年,还是一个初学者,永远支持Delphi !
foxelf
初階會員


發表:9
回覆:42
積分:30
註冊:2003-03-05

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-10-21 14:22:14 IP:61.231.xxx.xxx 訂閱
傳入的參數只要宣告是什麼型態就可以了
你的FUNCTION改成下面的試試看

function TForm1.caculate (n: integer): integer;
begin
n:=n*10;
result := n; //回傳
end;


===================引 用 zhouying82 文 章===================

[code delphi]
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
function caculate(n:integer):integer;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
edit1.Text :=inttostr(caculate(10));
end;

function TForm1.caculate n: integer): integer;
begin
n:=n*10;
end;

end.
請在此區域輸入程式碼

[/code]
照规矩,按照参数原则,我是不是应该在函数参数前添加VAR ? 但是实际使用却出现以下错误。不加VAR倒是可以运行正常,什么原因啊?
[Error] Unit1.pas(30): Types of actual and formal var parameters must be identical
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'
是什么原因啊,不过不加VAR,编译可以通过,但是计算出来的结果不对,应该是100,而他却是142768?有哪位大大知道吗?急,小弟在线等。
zhouying82
高階會員


發表:150
回覆:272
積分:189
註冊:2004-03-16

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-10-21 14:31:20 IP:218.80.xxx.xxx 訂閱
还是没有告诉我为是么加上VAR就不行了呢?另外还有,那个函数,我在D2009上面,就直接打
N:=N*10,而不用RESULT就可以通过的,但是D6就不行了。
------
断断续续的学了几年,还是一个初学者,永远支持Delphi !
eaglewolf
資深會員


發表:4
回覆:268
積分:429
註冊:2006-07-06

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-10-21 14:50:20 IP:211.75.xxx.xxx 訂閱
當你宣告var 時
代表你要傳入一個變數;
但是你卻傳入一個常數
當然會編譯失敗!

另不加 Result 在D2009會過是
D2009的compiler幫你做掉了!
------
先查HELP
再查GOOGLE
最後才發問

沒人有義務替你解答問題
在標題或文章中標明很急
並不會增加網友回答速度

Developing Tool:
1.Delphi 6
2.Visual Studio 2005
3.Visual Studio 2008
DBMS:
MS-SQL
zhouying82
高階會員


發表:150
回覆:272
積分:189
註冊:2004-03-16

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-10-21 14:53:02 IP:218.80.xxx.xxx 訂閱
什么叫变数啊?我看书中写着,如果这个值不是在函数体内运作,而是要带给其他的函数使用的话,就要加VAR,是不是这么理解的啊?
------
断断续续的学了几年,还是一个初学者,永远支持Delphi !
pcfinger
一般會員


發表:0
回覆:1
積分:0
註冊:2008-10-18

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-10-21 17:04:16 IP:220.141.xxx.xxx 訂閱

[code delphi]
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
function caculate(var n:integer):integer;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var n : integer;
begin
n := 10;
caculate(n);
edit1.Text :=inttostr(n);
end;

function TForm1.caculate(var n: integer):integer;
begin
n:=n*10;
end;

end.


[/code]
答案請看Online Help


Value and variable parameters

Most parameters are either value parameters (the default) or variable (var) parameters. Value parameters are passed by value, while variable parameters are passed by reference. To see what this means, consider the following functions.

function DoubleByValue(X: Integer): Integer; // X is a value parameter
begin
X := X * 2;
Result := X;
end;
function DoubleByRef(var X: Integer): Integer; // X is a variable parameter
begin
X := X * 2;
Result := X;
end;

These functions return the same result, but only the second one--DoubleByRef--can change the value of a variable passed to it. Suppose we call the functions like this:

var
I, J, V, W: Integer;
begin
I := 4;
V := 4;
J := DoubleByValue(I); // J = 8, I = 4
W := DoubleByRef(V); // W = 8, V = 8
end;

After this code executes, the variable I, which was passed to DoubleByValue, has the same value we initially assigned to it. But the variable
V, which was passed to DoubleByRef, has a different value.

A value parameter acts like a local variable that gets initialized to the value passed in the procedure or function call. If you pass a variable as a value parameter, the procedure or function creates a copy of it; changes made to the copy have no effect on the original variable and are lost when program execution returns to the caller.

A variable parameter, on the other hand, acts like a pointer rather than a copy. Changes made to the parameter within the body of a function or procedure persist after program execution returns to the caller and the parameter name itself has gone out of scope.

Even if the same variable is passed in two or more var parameters, no copies are made. This is illustrated in the following example.

procedure AddOne(var X, Y: Integer);
begin
X := X 1;
Y := Y 1;
end;
var I: Integer;
begin
I := 1;
AddOne(I, I);
end;

After this code executes, the value of I is 3.

If a routine's declaration specifies a var parameter, you must pass an assignable expression--that is, a variable, typed constant (in the {$J }
state), dereferenced pointer, field, or indexed variable--to the routine when you call it. To use our previous examples, DoubleByRef(7) produces an error, although DoubleByValue(7) is legal.

Indexes and pointer dereferences passed in var parameters--for example, DoubleByRef(MyArray[I])--are evaluated once, before execution of the routine.
------
一定要學會BCB
zhouying82
高階會員


發表:150
回覆:272
積分:189
註冊:2004-03-16

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-10-21 17:11:23 IP:218.80.xxx.xxx 訂閱
有哪位可以翻译一下啊?
------
断断续续的学了几年,还是一个初学者,永远支持Delphi !
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-10-22 08:39:25 IP:118.231.xxx.xxx 訂閱
連除錯訊息都看不懂,不管你程式程度如何
你語文的程度 ................. 令人忘塵莫及,遠遠超過許多人

但可以的話,請往另一邊跑 (第一名,其實有兩種)

大家拉裡拉渣被他牽著跑

問題跟加不加 var,有關嗎?

Types of actual and formal var parameters must be identical <-- 請將宣告察看一次,仔仔細細,一個字元一個字元的看

答案自然揭曉

===================引 用 zhouying82 文 章===================

[code delphi]
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
function caculate(n:integer):integer;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
edit1.Text :=inttostr(caculate(10));
end;

function TForm1.caculate n: integer): integer;
begin
n:=n*10;
end;

end.
請在此區域輸入程式碼

[/code]
照规矩,按照参数原则,我是不是应该在函数参数前添加VAR ? 但是实际使用却出现以下错误。不加VAR倒是可以运行正常,什么原因啊?
[Error] Unit1.pas(30): Types of actual and formal var parameters must be identical
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'
是什么原因啊,不过不加VAR,编译可以通过,但是计算出来的结果不对,应该是100,而他却是142768?有哪位大大知道吗?急,小弟在线等。
編輯記錄
syntax 重新編輯於 2008-10-22 08:47:38, 註解 無‧
zhouying82
高階會員


發表:150
回覆:272
積分:189
註冊:2004-03-16

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-10-22 12:06:23 IP:218.80.xxx.xxx 訂閱
真是搞不懂,都是一样的回复,为什么就不肯好好回答,而非要说些无关紧要的话?人人都有初学的时候,这样可不好啊。
------
断断续续的学了几年,还是一个初学者,永远支持Delphi !
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#10 引用回覆 回覆 發表時間:2008-10-23 02:01:50 IP:61.67.xxx.xxx 未訂閱

===================引 用 zhouying82 文 章===================
真是搞不懂,都是一样的回复,为什么就不肯好好回答,而非要说些无关紧要的话?人人都有初学的时候,这样可不好啊。
編輯記錄
P.D. 重新編輯於 2008-10-23 02:02:50, 註解 無‧
P.D. 重新編輯於 2008-10-23 02:03:41, 註解 無‧
eaglewolf
資深會員


發表:4
回覆:268
積分:429
註冊:2006-07-06

發送簡訊給我
#11 引用回覆 回覆 發表時間:2008-10-23 09:35:07 IP:211.75.xxx.xxx 訂閱
Syntax大的回答並非無關緊要
會出現 Types of actual and formal var parameters must be identical 這樣的訊息
代表你在 interface區塊 跟 implementation區塊 函數的參數傳遞方式不一樣
例如:
interface
function Caculate(var n:Integer):Integer;
implementation
function Caculate(n:Integer):Integer;
或是
interface
function Caculate(n:Integer):Integer;
implementation
function Caculate(var n:Integer):Integer;

正確的應該如下:
interface
function Caculate(n:Integer):Integer;
implementation
function Caculate(n:Integer):Integer;

interface
function Caculate(var n:Integer):Integer;
implementation
function Caculate(var n:Integer):Integer;

所以syntax大要你一個字元一個字元的檢查
------
先查HELP
再查GOOGLE
最後才發問

沒人有義務替你解答問題
在標題或文章中標明很急
並不會增加網友回答速度

Developing Tool:
1.Delphi 6
2.Visual Studio 2005
3.Visual Studio 2008
DBMS:
MS-SQL
zhouying82
高階會員


發表:150
回覆:272
積分:189
註冊:2004-03-16

發送簡訊給我
#12 引用回覆 回覆 發表時間:2008-10-23 10:31:50 IP:218.80.xxx.xxx 訂閱
不是啊,我就是想要知道,如果上面的程式我如果添加了VAR,结果会有什么不同,为什么我编译不通过,我也知道VAR里面不能代入常数,有谁可以帮我吗?
------
断断续续的学了几年,还是一个初学者,永远支持Delphi !
st33chen
尊榮會員


發表:15
回覆:591
積分:1201
註冊:2005-09-30

發送簡訊給我
#13 引用回覆 回覆 發表時間:2008-10-23 12:03:14 IP:122.116.xxx.xxx 未訂閱
您好,
利用這個機會, 我實測了一下 ( D6) :
1. 沒有加 var 的情況
a. 您的原程式碼 ( compile 可以過, 但結果錯誤 )
function TForm1.calc10(n: integer) : integer;
begin
n := n*10;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
edit1.Text := inttostr(calc10(10));
end;
b. 修正的程式 ( 正確 )
function TForm1.calc10(n: integer) : integer;
begin
result := n*10; <--- delphi 官方用法
// calc10 := n*10; <--- 許多程式語言的用法, 用 fuction name 傳回值, 今天 delphi 實測, 也可以用. (以後我可能就用這種寫法)
// n := n*10; <--- 在 D6 會傳回錯誤值, 我想可能是因為 就 d6 而言, 您未指定傳回值, 那他就用他的 logic 找到一個值傳回去.
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
edit1.Text := inttostr(calc10(10));
end;

2. 使用 var 的情況
function TForm1.calc10(var n: integer) : integer;
begin
n := n*10;
result := n; <--- 一樣要用 delphi 認可的方式傳回值.
// calc10 := n; <--- 也可以.
end;
procedure TForm1.Button1Click(Sender: TObject);
var ii: integer;
begin
// edit1.text := inttostr(calc10(10)); <-- compile 不過, 因為參數是變數, 您不能傳入常數 10. 所以要改成用一個變數, 放入值 10, 然後傳入這個變數.
// 您說您也知道 var 不能傳入常數, 那為什麼還一直問為什麼 compile 不過 ?
ii := 10;
edit1.Text := inttostr(calc10(ii));
edit2.text := inttostr(ii); <--- 用 var 的話, 若 參數在 function 中被改過值, 也會傳回給 call 的程式, 所以, 利用 var 可以使 function 傳回多個值,
// 打破一般 function 只能傳回一個值的想法.
end;
=====================
另外一種寫法, 請比較一下對 傳入變數的影響
function TForm1.calc10(var n: integer) : integer;
begin
result := n*10; <--- 一樣要用 delphi 認可的方式傳回值.
// calc10 := n*10; <--- 也可以.
end;
procedure TForm1.Button1Click(Sender: TObject);
var ii: integer;
begin
// edit1.text := inttostr(calc10(10)); <-- compile 不過, 因為參數是變數, 您不能傳入常數 10. 所以要改成用一個變數, 放入值 10, 然後傳入這個變數
ii := 10;
edit1.Text := inttostr(calc10(ii));
edit2.text := inttostr(ii); <--- 因為在 function 中, n 沒被改過, 所以 ii 值不變, 請比較一下和上一種寫法的不同之處.
end;

要不要加 var, 各有適用情況, 您就看情況使用吧.

參考一下.
------
IS IT WHAT IT IS
我是 李慕白 請倒著唸.
又想把老話拿出來說, 請用台語發音 : 專家專家全是ROBOT CAR (滷肉腳啦);
都已接手這麼久了, 績效還是那麼爛, 講話還那麼大聲.
編輯記錄
st33chen 重新編輯於 2008-10-23 12:06:45, 註解 無‧
st33chen 重新編輯於 2008-10-23 12:08:59, 註解 無‧
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#14 引用回覆 回覆 發表時間:2008-10-23 12:04:11 IP:203.73.xxx.xxx 未訂閱
不就是程式觀念問題, 搞得心都碎了...

以下一些個人看法, 提供您參考,
比較一下執行的結果, 看看在叫用函式的過程中
變數值, 變數的位址 有何改變???

[code delphi]
unit fMain;
interface

uses
Classes, Controls, StdCtrls, SysUtils, Forms, Dialogs;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
public
function Calc_call_by_value(n: Integer): Integer;
function Calc_call_by_reference(var n: Integer): Integer;
function Calc_call_by_address(n: PInteger): Integer;
function Calc_call_by_address2(var n: PInteger): Integer;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.Calc_call_by_value(n: Integer): Integer;
begin
n := n * 10;
Result := Integer(@n);
end;

function TForm1.Calc_call_by_reference(var n: Integer): Integer;
begin
n := n * 10;
Result := Integer(@n);
end;

function TForm1.Calc_call_by_address(n: PInteger): Integer;
begin
n^ := n^ * 10;
Result := Integer(n);
end;

function TForm1.Calc_call_by_address2(var n: PInteger): Integer;
begin
n^ := n^ * 10;
Result := Integer(@n);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
V: Integer; //測試值變數, 測試數值=10
PV: PInteger; //指向'測試值變數'的指標, 其內容為 V 的記憶體位址
I: Integer;
S: string;
L: TStringList;
begin
PV := @V;
L := TStringList.Create;
try
for I := 0 to 10 do
begin
V := 10;//initial
case I of
0: S := Format('PV: Address=%4X, Value=%4X', [Integer(@PV),Integer(PV)]);
1: S := Format('V: Address=%4X, Value=%d', [Integer(@V),V]);
2: S := Format('n: Address=%4X, Value=%d',[Calc_call_by_value(10),10]);
3: S := Format('n: Address=%4X, Value=%d',[Calc_call_by_value(V),V]);
4: S := Format('n: Address=%4X, Value=%d',[Calc_call_by_reference(V),V]);
5: S := Format('n: Address=%4X, Value=%d',[Calc_call_by_address(@V),V]);
6: S := Format('n: Address=%4X, Value=%d',[Calc_call_by_address(PV),PV^]);
7: S := Format('n: Address=%4X, Value=%d',[Calc_call_by_address(PV),V]);
8: S := Format('n: Address=%4X, Value=%d',[Calc_call_by_address2(PV),PV^]);
9: S := Format('n: Address=%4X, Value=%d',[Calc_call_by_address2(PV),V]);
end;
L.Add(IntToStr(I) ': ' S);
end;
L.Insert(2,'------以下是 Calc_XXX() 回傳值 ------');
ShowMessage(L.Text);
finally
FreeAndNil(L);
end;
end;

end.
[/code]

謹供參考....
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#15 引用回覆 回覆 發表時間:2008-10-23 15:07:18 IP:118.231.xxx.xxx 訂閱
1. 你第一篇  post 就少了一個括號 --> "(" ,編程就是要細心,一個字元都不能錯
2. 你添加了VAR,怎麼添的,誰知到,應該早貼出來,起碼一堆人可以幫你檢查
3. 初學不可恥,但茶來張口的懶,就不是了,而最單的連自己寫出代碼並驗證都不做,不知道是啥心態,如果你有做,那代碼呢?光是用嘴嚷嚷,只是像個吵著糖吃的小孩,快把你做的貼出來,就算是編不過,也貼出來
4. 還有你要看一本基礎入門的書,不要問「懶惰」的問題,新手不表示就不用作基本功夫,不表示可以大大方方用來作不看書或不學習的藉口(等人家告訴你,不是學習,如果不記不學,大家同你說再多知識也沒用),站上也有推薦一堆書,範圍從入門到精通,如果你有唸過,什麼是 Var ,起碼會有基本觀念吧!而不是像個全然門外漢,至少,你應該問的是「我怎麼做與我該做什麼」,而不是「你要告訴我,不然我生氣」

我想你也不想這樣,但是,你要學習

1. 如何問問題,可以切重要點 ---> 節省你的時間,讓大家可以馬上回答你的問題到重心
2. 如何做好基本功夫 --> 不然從何說起?
3. 如果你會了,記得跟交你的人說聲謝 (至於我就不用了,這是替以上一推熱心幫你回答的人說的,我只會打你跟罵你而已)

st33chenjow 幫你做了不錯的實驗與解說,你欠缺的不是[Var 不會用(不會用又如何,沒啥大不了)],而是他們這種精神

===================引 用 zhouying82 文 章===================
不是啊,我就是想要知道,如果上面的程式我如果添加了VAR,结果会有什么不同,为什么我编译不通过,我也知道VAR里面不能代入常数,有谁可以帮我吗?
zhouying82
高階會員


發表:150
回覆:272
積分:189
註冊:2004-03-16

發送簡訊給我
#16 引用回覆 回覆 發表時間:2008-10-23 16:22:57 IP:218.80.xxx.xxx 訂閱
上面的语句,就这条不懂。
edit2.text := inttostr(ii); 他的值肯定是120啊,因为前面已经声明了初始值,而且这句也没有用到CALU10这个函数啊。
------
断断续续的学了几年,还是一个初学者,永远支持Delphi !
st33chen
尊榮會員


發表:15
回覆:591
積分:1201
註冊:2005-09-30

發送簡訊給我
#17 引用回覆 回覆 發表時間:2008-10-23 16:35:54 IP:122.116.xxx.xxx 未訂閱

1. edit2.text 是新增用來給您觀察當使用 var 時傳入變數的變化情形

2. 在使用 var 時
第一例的值是 100 因為 calc10 中改變 n 的值就會改變傳入變數(就是例中的 ii) 的值.
第二例的值是 10 因為 calc10 中並未改變 n 的值, 只是拿來計算而已, 所以傳入變數不受影響.



===================引 用 zhouying82 文 章===================
上面的语句,就这条不懂。
edit2.text := inttostr(ii); 他的值肯定是120啊,因为前面已经声明了初始值,而且这句也没有用到CALU10这个函数啊。
------
IS IT WHAT IT IS
我是 李慕白 請倒著唸.
又想把老話拿出來說, 請用台語發音 : 專家專家全是ROBOT CAR (滷肉腳啦);
都已接手這麼久了, 績效還是那麼爛, 講話還那麼大聲.
系統時間:2024-05-08 0:17:20
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!