函数指针的用法
2010-12-20 02:02
274 查看
函数指针的用法
概要:本文描述的函数指针的一些使用方法。关键字:函数指针、返回函数指针的函数
提到函数指针,一般我们能够想到的用法如下。
1、 第一种,直接使用,比较原始的方式。
return_type (*func_pointer)(parameter_list),即:返回类型 (*函数名)(参数列表) 例如: int (*pFun)(int n); int testFun1(int n) { cout << n << endl; return 1; } int _tmain(int argc, _TCHAR* argv[]) { pFun = testFun1; (*pFun)(1); pFun(1); }
说明:首先,我们定义一个函数指针变量pFun,函数的原型是:int (*)(int n),即,该函数是一个参数为整形,返回值是空值的函数。请注意我在这里使用的措辞,pFun是一个“变量”,而非“类型”,那么,既然是变量,它就应该能够被赋值,能够被初始化。因此,由于函数testFun1的参数与返回值与上面所描述的类型吻合,所以我们能够对pFun进行赋值pFun = testFun1。然后使用函数指针进行调用,(*pFun)(1)。为什么可以这么调用呢?我们需要理解:函数的函数名本质上就是一个指针,函数名指向该函数在内存中的首地址。就像int array[10]中array就能代表数组首地址一样。所以,表达式(*pFun)(1)表达的意思是先取pFun的值,得到testFun1的地址,然后再进行调用,与直接调用testFun1(1)没有任何区别。
那pFun(1)又是怎么回事,为什么也能够进行调用?为什么与(*pFun)(1)表达同一个意思?
以下说明解释了为什么?在这里引用了一位达人的链接,膜拜先,同时也灰肠感谢这位达人的文字指点。
http://blog.21ic.com/user1/3742/archives/2007/34818.html
/*****************************************************************/ 如何获得函数的地址: 有两种方式获取函数的地址。假设funcptr是一个函数指针。如果我们将它指向一个兼容函数func()。 第一种方法使用隐式指针转换(implicit conversion to pointer): funcptr = func; 第二种方法使用显式指针转换(explicit conversion to pointer): funcptr = &func; 这两种方法都是可行的。实际上,如果在程序中有第一种形式的语句,编译器会把它自动转换为第二种方式。 使用函数指针调用函数: 象获取函数的地址一样,通过函数指针调用函数的方法也有两种: 第一种是使用显式指针(explicit dereference of the pointer),如下: extern void func(int x, int y); void (*func_ptr)(int x, int y) = func; (*funcptr)(3, 2); 第二种称为隐式指针(implicit dereference of the pointer)。 extern void func(int x, int y): void (* func_ptr)(int x, int y) = func; funcptr(3, 2); /*****************************************************************/
如果你看明白了上面的描述,那么应该很清楚的知道为什么了。呵呵。
2、 第二种,使用typedef的方式。
先说明一下typedef的作用,该关键字的目的是将一个已知的类型定义成一个新的类型,使用新的类型可能会具有更加明确的语义,或者使用更加方便。
如:typedef int INT; INT n = 100;
这种方式是如下定义的。
typedef return_type (*新类型)(parameter_list),即:返回类型 (*新类型)(参数列表) 例如: typedef int (*FUN)(int n); int testFun1(int n) { cout << n << endl; return 1; } int _tmain(int argc, _TCHAR* argv[]) { FUN pFun; pFun = testFun1; (*pFun)(1); pFun(1); }
说明:这种方式与第一种唯一不同的就是使用了typedef,它为函数的原型为:int (*)(int n)的类型定义了一个新的名字(或称为类型),叫FUN,使用FUN定义一个变量pFun,pFun就能代表一个函数指针,代表的函数原型就是int (*)(int n)。pFun既然是一个变量,那么其使用也就和前面所述的第一种方式无异了,这里不再赘述。
3、 第三种,在类中使用函数指针。
class CTest { public: int Add(int n1, int n2) { return (n1 + n2); } }; typedef int (CTest::*PADD)(int, int); int _tmain(int argc, _TCHAR* argv[]) { PADD pFun = &CTest::Add; CTest testobj; int rt = (testobj.*pFun)(1, 2); CTest* pTestobj = new CTest(); rt = (pTestobj->*pFun)(3, 4); return 0; }
指针的定义加上了“类”限制, 指针的使用加上了的“对象”限制,用来指明指针指向的函数是哪个类的, 使用的时候是对象相关的.
个人感觉在类中使用函数指针没有一点用处, 至少我现在不知道有啥用途.
直到我在阅读《STL源码剖析》之前,我一直认为函数指针的使用方式也就只有这么多,但今天在读这本书的时候,发现了以下奇怪的用法,见书:P57页,代码如下:
static void (*__malloc_alloc_oom_handle)(); ......(略) void ( *set_malloc_handle(void (*f)()) ) () { void (*old)() = __malloc_alloc_oom_handle; __malloc_alloc_oom_handle = f; return (old); } ......(略) void (*__malloc_alloc_template<inst>)::__malloc_alloc_oom_handle() = 0; /* 为静态变量赋初值*/
乍一看,不对呀,void ( *set_malloc_handle(void (*f)()) ) ()这个定义明明是返回一个空值啊,为什么返回的是一个函数指针,难道书出错了?google了一下,终于明白是怎么回事。原来函数指针还可以这么用。
4、 第四种,定义返回函数指针的函数。
return_type ( *function(func_parameter_list) ) (parameter_list)
说明:这里定义了一个函数function,该函数的参数列表是(func_patameter_list),返回类型是一个函数指针,这个函数指针的原型是return_type (*)(parameter_list)。
得之这种使用方式后,上面的源代码我们就能够明白到底是怎么回事了。
因此:void ( *set_malloc_handle(void (*f)()) ) ()这个定义就是说,定义了一个函数set_malloc_handle,其参数是一个函数指针f,其原型是void (*)(),函数set_malloc_handle的返回值也是一个指针,其原型也是void (*)(),函数内部先将旧的函数指针保存起来,然后设置新的函数指针,最后将旧的函数指针返回出去。一目了然。
实际上,按照这种方式,看着总归有些别扭,感觉语义晦涩难懂,无非就是一个函数,它即能够接收一个函数指针,又能够返回一个函数指针,因此,完全可以按照以下方式来做:
typedef void (*newfun)(); newfun set_malloc_handle(newfun f) { newfun old = malloc_alloc_oom_handle; malloc_alloc_oom_handle = f; return old; }
这样看起来是不是更加清晰了呢?呵呵。实际上,我查看了一下windows的STL版本里面的定义,就是按照这种方式。代码如下:
typedef int (__cdecl *new_hand)(size_t); new_hand __cdecl _set_new_handler(new_hand);
再看一个例子,以前我在刚学linux信号的时,没怎么搞明白,现在也一目了然了。
signal函数原型
Linux 2.0之前版本 void (*signal (int signo, void (*func)(int))) (int); Linux 2.6 版本 typedef void (*__sighandler_t) (int); extern __sighandler_t signal (int __sig, __sighandler_t __handler)
本文参考链接:
1. 关于C++中函数指针的使用:
http://www.98exe.net/Article/a/2006-10-23/2025.html
2. 函数指针及其应用:
http://blog.21ic.com/user1/3742/archives/2007/34818.html
3. 定义返回函数指针的函数:
http://dev.firnow.com/course/3_program/c++/cppjs/20091012/178580.html
相关文章推荐
- c语言中函数指针的用法和技巧
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- typedef函数指针的用法
- typedef函数指针用法
- typedef 函数指针的用法
- typedef函数指针的用法(附例子)
- 剑指offer_面试题14_调整数组顺序使奇数位于偶数前面(函数指针用法)
- typedef函数指针的用法
- 二级指针作为函数参数的典型用法
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- c/c++ 函数指针的用法
- typedef 函数指针的用法
- IOS typedef 函数指针的用法
- typedef 函数指针的用法
- typedef函数指针用法 assert()
- C语言结构体指针,函数指针的用法
- typedef 函数指针的用法
- 《C++ Primer》学习 之 函数指针相关用法
- delphi中函数指针的用法
- typedef函数指针的用法(C++)