看看你的Delphi的基本功(300分)

  • 主题发起人 主题发起人 教父
  • 开始时间 开始时间

教父

Unregistered / Unconfirmed
GUEST, unregistred user!
我们知道在Delphi中,参数传递有两种方式:传值和传址,一个变量如果是传值方式传递的话,
在函数或是过程中对参数的修改并不会影响此变量,举例说明:

procedure ChangeVal(i:integer);
begin
inc(i);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
i:=1;
ChangeVal(i);
ShowMessage(Format('%d',));
end;

ChangeVal将传入的参数加1,但是很显然,Button1Click过程显示的i值仍然为1,因为
ChangeVal的参数传递方式采用的是传值的方式。

那再来看看下面这个例子:
procedure TForm1.Button1Click(Sender: TObject);
begin
TButton(Sender).Caption:='Changed';
end;

这是由Delphi自动生成的Button1的OnClick事件处理代码,很明显,这里的Sender是通过
传值的方式传递的,但是那个Button1的Caption又确实被改变了,这是为什么?

如果你无法回答这个问题的话,我真切地奉劝你,踏踏实实地把Delphi从头至尾地啃一啃,
而不要去研究什么浏览器、播放器、黑客程序等等。
 
[:)]的确如此
 

procedure ChangeVal(i:integer);//定义为传值
procedure ChangeVal(var i:integer);//定义为变量,
sender本身就是变量

 
朋友,Delphi中所有的类(非基本类)其实都是指针,指针作为参数在pascal中传递,只有地址
传递的效果.不信?

TYourClass = class
I : integer;
end;
...
var
C1 : TYourClass;

procedure DoSth(CC : TYourClass);
begin
Inc(CC.I);
end;

procedure main;
begin
DoSth(C1);
end;

TButton都是指针!
 
我想你的问题应该很好解决。
sender的值其实就是某个对象(类的实例)的引用值(注意也是一种值),通过这个
引用值可以访问及修改sender所指向的对象的方法或者属性(如:TButton(Sender).Caption),
那么对sender所指向的对象的属性进行修改与修改sender的引用值并无任何关系,实际
上你还是无法修改sender的引用值,这就符合“一个变量如果是传值方式传递的话,
在函数或是过程中对参数的修改并不会影响此变量”的规定。

更简单的说,就如同在C语言里,通过传值方式将一个结构的地址值传给函数,在函数中
可以通过结构的地址值修改结构成员的值一样。
 
考试,有意思
 
因为OP里是
value/refence model
所以是这样了,
你传递的是 REFENCE NOT VALUES
当然可以理解成传递了,
引用的 值
 
第一种情况我暂且不说,具体分析一下第二种情况发生的原因.
//////////////
procedure TForm1.Button1Click(Sender: TObject);
begin
TButton(Sender).Caption:='Changed';
end;
这是由Delphi自动生成的Button1的OnClick事件处理代码,很明显,这里的Sender是通过
传值的方式传递的,但是那个Button1的Caption又确实被改变了,这是为什么?
/////////////////
不错看这一句,procedure TForm1.Button1Click(Sender: TObject);,我可以知道Sender
在这里,的确是一个传值方式传递,再来看看Sender 的TYPE,Sender :TObject ,可知Sender
为一对象事例,即其实质为一指针类型,假设程序执行时刻Integer(Sender)为 $abcd,
Ok,程序执行 TButton(Sender).Caption:='Changed'后,我可以测试到Integer(Sernder)的
Values 还是@abcd, 满足一个变量如果是传值方式传递的话,
在函数或是过程中对参数的修改并不会影响此变量.

我要下班了,这是我的实验结果.

procedure test (a:PInteger);
begin
a^:= 10;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i:Pinteger;
begin
New(i);
i^:=9;
ShowMessage (IntToStr(i^))
//为9
test (i );
ShowMessage (IntToStr(i^))
//哈哈,为10
Dispose(i);
end;










 
看看Sender后面是什么:

Sender: TObject

TObject是什么?它不是简单的变量,而是一个对象。在delphi内部,对象是以指针传递的。
 
呵呵,看来DFW的水平还是比较能令人满意的。
Object Pascal与C++最大的差别就在于:Object Pascal 的对象实质上是引用,所以才会
出现上面我所说的情况。

把分给各位分了吧 :)
 
糟糕,分给错了,203010真是有运气。
请:吕雪松,kk98,byrybye,Jhdandcl,kthy到
http://www.delphibbs.com/delphibbs/dispq.asp?lid=800102
中去拿分。
 
呵呵,勉强弄得清楚,不行,偶得回去好好啃书去了[:D]
 
哈哈,谢了,不过这分给我也不亏啊,我没回答只是觉得应该留给新手们想想
 
说到底还是指针的问题,学过汇编的朋友仔细想想都可以想得通!
 
我想,是不是因为Sender是一个指向TObject类的指针,
传递参数时因为是传值,所以实际上就是复制了一个TObject类的指针,
指针并没有被改变,改变的是这个指针所指的内容。
 
后退
顶部