代码改变世界

[转]函数指针简单讲解

2011-10-01 19:39  ...平..淡...  阅读(290)  评论(0编辑  收藏  举报

本文出自 http://www.wutianqi.com/?p=2721

因为基本没用过函数指针,所以对这个概念及用法比较模糊,最近温习C++在,再次看见这个概念,于是百度了下,看见网上有很多关于函数指针的文章,不过在纷纷转载的过程中,格式上的错位,让人看着难受,我自己也简单的总结下,方便以后查阅。

首先要清楚一个概念:

1.数组的数组名就这个数组的地址,也即数组第一个元素的地址(指针)。

2.函数的函数名就这个函数的入口地址(指针)。

3.结构体的结构名不是这个结构的地址,要取得结构体的地址,必须得用&(取地址运算符)。

其次,还得对函数指针,指针函数,数组指针,指针数组这四个容易混淆的概念区分清楚。(这个可以百度,网上资料太多了,一个小秘诀,这四个概念的主体都是后两字,比如数组指针,主体是指针,只不过这个指针指向一个数组,很容易理解吧?)。

上面说了:“函数名实际上也是一种指针,指向函数的入口地址”。

我们先来看一个函数指针最简单的例子,这个例子仅仅只为了展示函数指针这个概念,而无法体现其优点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>    
using namespace std;
 
int fun(int a)      // ①
{
	cout << a << endl;
	return 0;
}
 
int (*pfun)(int);  // ②
 
int main()
{
	pfun = fun;   // ③
	(*pfun)(3);   // ④
	return 0;
}

运行结果:
pfun

首先看代码的①处,定义一个函数fun,输出参数的值;

再看②处,这里是函数指针的定义,因为括弧的优先级高于*,所以要把pfun用括弧包围,否则就变成指针函数了,返回一个指针int *.另外,函数指针的返回类型,参数个数,参数类型等都要和要匹配的参数一模一样!

再看③处,因为在②出是函数指针的定义,函数指针是一个指针,而函数名是函数的入口地址,所以把fun赋值给pfun,这样,pfun这个函数指针就指向fun这个函数了。

所以在④处,调用(*pfun)(3);就相当于调用fun(3)了。

但是看完这个例子,肯定脑海里对函数指针的作用毫无概念,不过起码函数指针的用法基本了解了,那么看下这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
using namespace std;
 
void imax(int a, int b)
{
	cout << "Now call max(" << a << "," << b << "):" << endl;
	int t = a>b? a:b;
	cout << t << endl;
}
 
void imin(int a, int b)
{
	cout << "Now call min(" << a << "," << b << "):" << endl;
	int t = a<b? a:b;
	cout << t << endl;
}
 
// 定义一个函数指针
typedef void (*myFun)(int a, int b);
 
// 回调函数
void callback(myFun fun, int a, int b)
{
	fun(a, b);
}
 
int main()
{
	int a = 10;
	int b = 20;
 
	callback(imax, a, b);
 
	callback(imin, a, b);
 
	return 0;
}

运行结果:

callback

很直观的就可以看出函数指针的作用,有点类似函数模版。

一般都是把指向函数的指针作为另一个函数的形参,这样可以在运行时确定参数。

接下来简单说下typedef和函数指针:

我们一般定义函数指针是:

void (*pfun)(int, int);

不过,我们也可以用typedef:

typedef void (*pfun)(int, int);

请注意第一个是定义一个变量,而第二个是设置一个类型的别名,也即第二个的pfun实际上只是一个类型! 

更多的类容,我在网上找了几篇,不过有的格式比较混乱,将就下也无所谓:

1.http://dev.10086.cn/cmdn/wiki/index.php?doc-view-6757.html (推荐!)

2.http://zhangming3113.blog.163.com/blog/static/6217914820083911444353/

3.http://topic.csdn.net/t/20051016/20/4329907.html

4.http://zhaowei1119.blog.163.com/blog/static/7297435720095704327919/