关于 在function 或procedure 里out声明 的参数一个小问。 ( 积分: 20 )

  • 主题发起人 主题发起人 cyf_106
  • 开始时间 开始时间
C

cyf_106

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure a(out ss: integer);
begin
Inc(ss) ;
ss:= ss+5;
ss:=ss+5;
end;
procedure a1(var ss: integer);
begin
Inc(ss) ;
ss:= ss+5;
ss:=ss+5;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
s,s1: integer;
begin
s:= 5;
s1:=5;
a(s);
a1(s1);
a(s1);
a1(s);
Showmessage(format('s %d : s1 %d',[s,s1]))
end;
上面是我的一个测试用例,help说,out 参数传入的值 会忽略!但测试的结果是out和var是一样的,有谁知道其中的差别?
 
procedure a(out ss: integer);
begin
Inc(ss) ;
ss:= ss+5;
ss:=ss+5;
end;
procedure a1(var ss: integer);
begin
Inc(ss) ;
ss:= ss+5;
ss:=ss+5;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
s,s1: integer;
begin
s:= 5;
s1:=5;
a(s);
a1(s1);
a(s1);
a1(s);
Showmessage(format('s %d : s1 %d',[s,s1]))
end;
上面是我的一个测试用例,help说,out 参数传入的值 会忽略!但测试的结果是out和var是一样的,有谁知道其中的差别?
 
out是传出型
var是传入传出型
 
不过out型参数的确和ver一样会拿传入的值去用,与help中说的有出入。。似乎out只是给人看的(就像vc中的OUT、FAR等宏一样)
xianguo貌似没动手过
 
out,var的确是有区别的:
out参数是指要求有一个同类型的指针,不要求有指针指向的实例存在。
var参数不仅要求有一个同类型的指针,并且要求指针指向的实例存在。

你给的例子是一个Integer类型,属于值类型,编译器已经分配了存储区域。
考虑以下传入非值类型的例子:
TTest = Class
public
i: Integer;
end;
procedure TOut(out tt: TTest);//将返回内部创建的TTest实例。
begin
tt := TTest.Create;//区别所在
tt.i :=100;
end;
procedure TVar(var tt: TTest);//外部创建,内部使用。
begin
tt.i := 100;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
s,s1: TTest;
begin
TOut(s);
s1 := TTest.Create;
TVar(s1);
s.Free;
s1.Free;
end;

如果先创建s直接传入TOut();那么TOut中就不需要创建了。
help说,out 参数传入的值 会忽略!是指在TOut中创建实例。
如果在TOut外部创建s,内部调用,由于是使用指针,当然不会忽略。也就跟使用var参数一样了。
 
out,var的确是有区别的:
out参数是指要求有一个同类型的指针,不要求有指针指向的实例存在。
var参数不仅要求有一个同类型的指针,并且要求指针指向的实例存在。

你给的例子是一个Integer类型,属于值类型,编译器已经分配了存储区域。
考虑以下传入非值类型的例子:
TTest = Class
public
i: Integer;
end;
procedure TOut(out tt: TTest);//将返回内部创建的TTest实例。
begin
tt := TTest.Create;//区别所在
tt.i :=100;
end;
procedure TVar(var tt: TTest);//外部创建,内部使用。
begin
tt.i := 100;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
s,s1: TTest;
begin
TOut(s);
s1 := TTest.Create;
TVar(s1);
s.Free;
s1.Free;
end;

如果先创建s直接传入TOut();那么TOut中就不需要创建了。
help说,out 参数传入的值 会忽略!是指在TOut中创建实例。
如果在TOut外部创建s,内部调用,由于是使用指针,当然不会忽略。也就跟使用var参数一样了。
 
to xypHikaru 如果向下面这样,会怎样?不回答也没关系,我回去测试一下就知道了!

TTest = Class
public
i: Integer;
end;
procedure TOut(out tt: TTest);//将返回内部创建的TTest实例。
begin
//tt := TTest.Create;//区别所在
tt.i :=100;
end;
procedure TVar(var tt: TTest);//外部创建,内部使用。
begin
//tt := TTest.Create 如果这样呢?这肯定没什么问题!
tt.i := 100;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
s,s1: TTest;
begin
s := TTest.create
//我会丢失吗?
TOut(s);
s1 := TTest.Create;//这句改成在tvar里面创建
TVar(s1);
s.Free;
s1.Free;
end;
 
to islet8
--就像vc中的OUT、FAR等宏一样

vc 中的指针确有区别,这是在兼容c中的指针!
c的指针有近、远和巨之区别!
近指针 * 是指的范围在64k,是在实模式下使用的!
far larg 是在有了大内存以后使用的!
 
这个我不知道,但从编译后生成的汇编代码看out和var没有什么区别,没法生用out生命的参数会被清除的情况。我用的是d6+sp2
 
thx to 草原牧歌 &amp
xypHikaru :)
 
怎么才可以在论坛里发帖呢?
 
我猜测这个out关键字在com开发的时候可能与var不同吧!
难得t.tt提醒在汇编级来查看。虽不懂汇编,
但反编译以后的代码还是能看出区别的,回去试试!
 
多人接受答案了。
 
后退
顶部