在C语言中,指针变量除能够指向数据对象外,也可以指向函数。
一个函数在编译时,分配了一个入口地址,这个入口地址就成为函数的指针。函数的指针能够赋给一个指向函数的指针变量,并能够通过指向函数的指针变过量调用它所指向的函数。
定义一个指向函数的指针变量的一般形式是:
类型标识符 (*指针变量名)();
例如:用指向函数的指针调用函数
main()
{
int min(int a, int b); /* 声明min函数 */
int (*P)(); /* 定义指向函数的指针 */
int x,y,z;
P=min; /* 指针P指向函数min的入口地址,不必写函数形参 */
scanf("%d,%d",x,y);z=(*P)(x,y);printf("x=%d y=%d min=%d",x,y,z);
}
int min(int a,int b);
{
int c;
c=a<b?a:b;
return(c);
}
//////////////////////////////////////////////////
上面是从书上看到的一段话,看完之后我就开始想,在delphi中有没有这种指向函数的指针存在哪?下面是我的实现方法。
一个函数在编译时,分配了一个入口地址,这个入口地址就成为函数的指针。函数的指针能够赋给一个指向函数的指针变量,并能够通过指向函数的指针变过量调用它所指向的函数。
定义一个指向函数的指针变量的一般形式是:
类型标识符 (*指针变量名)();
例如:用指向函数的指针调用函数
main()
{
int min(int a, int b); /* 声明min函数 */
int (*P)(); /* 定义指向函数的指针 */
int x,y,z;
P=min; /* 指针P指向函数min的入口地址,不必写函数形参 */
scanf("%d,%d",x,y);z=(*P)(x,y);printf("x=%d y=%d min=%d",x,y,z);
}
int min(int a,int b);
{
int c;
c=a<b?a:b;
return(c);
}
//////////////////////////////////////////////////
上面是从书上看到的一段话,看完之后我就开始想,在delphi中有没有这种指向函数的指针存在哪?下面是我的实现方法。
解决方案 »
- MDI主窗口打开DLL子窗口后再关闭报内存错误
- 用什么方法判断数字或时间格式最快?
- 高分讨论:Windows下如何通过一个已经建立的端口收发数据
- 比较两个表(很急啊,求救了)
- 关于scrollbox控件的问题。。。。。 在线等 急。。。。。急。。。。急
- 沾大家的光,取个名字!谢谢!
- 在写Active Server对象的时候,怎样判断任意一个数据库字段是否为空
- Borland产品专家评选-----大家认为谁合适呢?
- delphi代码编写器左边有个树形东西,列出了代码中全部东西
- 在DBComboBox中添加记录怎么做?
- 怎么样截获窗口移动的消息,不用wm_nchittest消息
- 求助,怎么使用 sql 脚本,谢谢!
Form1: TForm1;implementation{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var Ptest:TMyTest;
begin
Ptest:=test;
Ptest(65);
end;procedure TForm1.test(aaa: integer);
begin
showmessage(Char(aaa));
end;end.
功能虽然实现了,但是和C语言的实现已比较,就感觉到delphi中的实现简直是太笨重了,难道说我为了实现一种函数的指针还要专门定义一个TMyTest = procedure(aaa:integer) of object;
在这里贴出来是为了请教各位大虾,有没有比较灵活的实现方法,我觉得C能做到的delphi也一定能够做到,而且应该做的更好,等待大家的执教!!!^_^
var Ptest:TMyTest;从本质上讲,是一样的,都是定义函数原型,再定义一个指针,没有任何区别
对于其中的可读性,见仁见智c里面一样可以用typedef来实现,你这个属于特殊例子,如果定义多个变量肯定不会重复
int (*P)();
而是用typedef实现
int min(int a, int b);
int (*P)();
int x,y,z;
P=min;
scanf("%d,%d",&x,&y);/*这里更正一个错误,scanf是要求地址的*/
z=(*P)(x,y,z);
/*
这里故意写错,多写一个参数,编译通过,运行时忽略了z,这个问题不严重么?
可以说是自由,但不得不承认,这是个问题,
至于调用的时候到底压几个参数入栈,出来的时候清理了几个,我没有看
如果压进3个,问题就出现了,以后对栈的调用,都会错乱
如果压进2个,只能说编译器比较聪明,看代码的人却胡涂了
*/ printf("x=%d y=%d min=%d",x,y,z);
}int min(int a,int b){
int c;
c=a<b?a:b;
return(c);
}
/*这样调用也可以*/
procedure TForm1.Button1Click(Sender: TObject);
var Ptest: procedure(aaa: Integer) of Object;
begin
Ptest:=test;
Ptest(65);
end;
.net的检查更为严格,
函数签名不同就会报错,
这样就是类型安全的了
/////////////////////////////
回复人: sdzeng(大头鸟) ( ) 信誉:100 2005-07-11 13:05:00 得分: 0
两种语言各有特色,C的指针用法虽然灵活,但是也存在滥用的情况,Pascal就是Pascal,没必要用C的标准来要求
//==========================================================
我是在看一本关于C的书的时候偶尔看到的关于指向函数的指针的,所以想看看delphi中怎么实现,没有可以用C的标准来要求delphi的,不过Pascal的语法确实比较严谨,现在认识更深刻了,呵呵!!!
没有可以用C的标准来要求delphi的
此处可以为“刻意”的笔误
int (*P)(); /* 定义指向函数的指针 */
int x,y,z;
P=min; /* 指针P指向函数min的入口地址,不必写函数形参 */
scanf("%d,%d",x,y);z=(*P)(x,y);这些代码对于标准C来说并不是合法的,在标准c中编译器要进行类型检查
c++primer书中曾说过
"省略实参或者传递类型错误的实参都是c语言标准化之前严重的运行时刻错误的根源"
TMyTest=procedure(a:integer);
var
Form1: TForm1;implementation{$R *.dfm}procedure test1(a:integer);
begin
showmessage(Char(a));
end;procedure test2(a:string);
begin
showmessage(a);
end;procedure TForm1.Button1Click(Sender: TObject);
var MyTest:TMyTest;
begin
MyTest:=@test1; //这样调用没有任何问题,和下面的作用一样
//MyTest:=test1;
MyTest(65);
end;procedure TForm1.Button2Click(Sender: TObject);
var MyTest2:TMyTest;
begin
MyTest2:=@test2; //这样编译没有问题,但是执行会出错
MyTest2(65);
end;end.