好天气看好电影

魔戒台词:刚铎和洛汉的好男儿,我的好兄弟;我在你们眼中...,看到了我心中也感受到的恐惧;有一天人类将失去勇气...,我们将众叛亲离,一败涂地;但不是今天;有一天邪将胜正,人类的世界也会完全毁灭;但不是今天;今天我们要誓死奋战。为了你们在世上所珍惜的一切...,一定要奋战到底
free hit counter

统计

最新评论

  • 1. re: Invoke and BeginInvoke
  • 哥们,写得太好了,真正的为我解惑了,看了好多文章都云里雾里的,今天终于明白了!
  • --拼命郎
  • 2. re: 三聚氰胺算法
  • @丁学首先说明,我没有造任何谣言。第四题弄错了,1楼纠正了一下,我非常感谢。其它数据都是从网络上取下来,对一个养牛的奶农来说, 就像1楼算出的3吨,或者说1吨有什么区别? 你觉得奶农会一年买几吨或者买...
  • --信息加油站义工
  • 3. re: Invoke and BeginInvoke
  • 受益匪浅
  • --清清爽爽
  • 4. re: 对.net事件的看法
  • 嗯,受教了,不错师傅!
  • --清清爽爽
  • 5. re: 三聚氰胺算法
  • @信息加油站义工
    但是你觉得使用“造谣”的方式对一个中国企业落井下石很好吗?
  • --丁学

转载函数指针

源:http://www.i170.com/user/killercat/Article_63999


函数指针指向一个函数的地址(不仅仅只有变量才有地址,程序代码会被分配一定的内存空间)

下面是一个简单的例子,给大家一个初步的印象:

#include <stdio.h>

float add(float a, float b)

{
 return a + b;
}
float mult(float a, float b)

{
 return a * b;
}
float sub(float a, float b)

{
 return a - b;
}
float div(float a, float b)

{
 return a / b;
}

float getAns(float a, float b, float (*prtF)(float, float))

{
 return (*prtF)(a,b);
}

int main()

{
 printf("%g\n",getAns(1,2,&add));
 printf("%g\n",getAns(1,2,&sub));
 return 0;
}

 

1. 定义一个函数指针:

int (*PRF)(int, char, float) = NULL;

这样定义了一个函数指针变量 PRF,它保存着指向这样的函数的指针:返回类型为 int,参数列表为(int, char, float);

这里注意一下,PRF 被看做一个变量

前面有谈到 typedef 可以定义一个类型名,那么我们可以定义这样的一个类型名:

typedef int (*PRF)(int, char, float);

这时候,PRF 成为一个类型名,而不是一个变量。

关于typedef,可以参考:http://www.i170.com/user/killercat/Article_64000

 

2. 取函数的地址:

和取变量地址一样,使用 &函数名,请看上面的例子,取add函数的地址为:&add

 

3. 关于调用约定:

看到这里,我们知道,对于一个函数指针变量,我们可以给它一个函数的地址,注意一下,函数指针在定义的时候使用如下格式:

返回类型 (*变量名)(参数列表);

这个函数指针变量,只能保存有着相同的返回类型和参数列表的函数指针。其实除了这两点之外,还需要注意一下调用约定。在Windows程序设计中,我们常见到的一个定义:

typedef LRESULT (CALLBACK* WNDPROC)(HWND, UNIT, WPARAM, LPARAM);

初学者一眼就看蒙了,其实这里就是定义了一个类型名(或称之为类型,这两个概念在某些书上是不区分的):WNDPROC,它可以用来定义函数指针。这里有点不一样的是 CALLBACK,在Windows中,CALLBACK被这样定义:

#define CALLBACK    __stdcall

__stdcall是调用约定(有关调用约定的内容可以在http://www.i170.com/user/killercat/Article_63188的后半部分找到),注意一下:

typedef LRESULT (__stdcall* WNDPROC)(HWND, UNIT, WPARAM, LPARAM);

typedef LRESULT (__cdecl* WNDPROC)(HWND, UNIT, WPARAM, LPARAM); 

那么这里的2个 WNDPROC 就表达了不同的意思了,也就是说,某个函数指针变量保存的函数指针,不但要求有着相同的返回类型和参数列表,还需要相同的调用约定。

在默认情况下(不写调用约定)采用 __cdecl 的调用约定(C/C++均以__cdecl为默认调用约定)。

 

4. 函数指针变量是可以比较的(同于一般的指针变量)

 

5. 函数指针变量的另一种使用方式:

除了前面说的赋值,比较之外,函数指针还可以这样用:

#include <stdio.h>

float add(float a, float b){
 return a + b;
}

int main(){
 float (*t)(float, float) = &add;
 printf("%g\n",(*t)(1,2));
 return 0;
}

注意到 (*t)(1,2); 等价于 add(1,2);

也就是一个函数指针变量可以看作是一个函数名,这里注意一下,使用的是 (*t) 来表示函数名,当然也可以使用 t,也就是 t(1,2)

对于使用(*t),可以理解成为,取出指针t指向的具体的值,即函数。

这种用法,通常使用在把函数指针作为参数传递的时候:

void PassPtr(int (*pt2Func)(float, char, char))
{
   int result = (*pt2Func)(12, 'a', 'b');
}

 

6. 函数指针可以被函数返回(同于普通变量)

 

7. 用数组来保存函数指针:

int (*fp[10])(float, char, char) = {NULL};

或者

typedef int (*FP)(float, char, char);

FP fp[10] = {NULL};

posted on 2008-07-10 14:30 信息加油站义工 阅读(31) 评论(0)  编辑 收藏 网摘 所属分类: 2. c++与汇编


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-07-10 14:32 编辑过
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: