搜索
bottom↓
回复: 25

指针的用法之函数指针

[复制链接]

出0入0汤圆

发表于 2013-3-26 11:48:38 | 显示全部楼层 |阅读模式

  最近在忙着学习移植操作系统,但是操作系统全是由c语言编程实现的,里面的各式各样的指针用法都有,所以将指针用法复习了一遍,现在把我的学习笔记贴出来,感兴趣的都一起学习学习吧

另:该文档属原创,转载请说明出处
1、             指向函数的指针

一个函数在编译的时候,分配一个入口地址,这个函数的入口地址就称为函数的指针。可以通过一个指针变量指向函数,然后通过该指针变量调用此函数。



#include <stdio.h>

Void mian ()

{

   Int max(int,int);

   Int (*p)(int,int);

   Int a,b,c;

   P=max;

   Scanf(“%d,%d”,&a,&b);

C=(*p)(a,b);

Printf(“max=%d”,c);

}

其中 Int (*p)(int,int);用来定义p是一个指向函数的指针变量 ,该函数有两个整型参数,函数值为整型。

注意*p两侧的括号不可以省略,表示p先与*结合,是指针变量,然后再与后面的()结合,表示此指针变量指向函数



如果写成 int *p(int ,int); 则由于()优先级高于*,它就成了声明一个p函数了(这个函数的返回值是指向整型变量的指针)。



赋值语句“p=max;”的作用是将函数max的入口地址赋给指针变量p。和数组名代表数组首元素地址类似 ,函数名代表该函数的入口地址。这时,p就是指向函数max的指针变量,p和max都是指向函数的开头。但是不能用*(p+1)表示函数的下一条指令。



注意:

(1)      指向函数的指针变量定义形式

数据类型 (*指针变量名)(函数参数列表);

       这里的数据类型指函数返回值的类型。

(2)      函数调用可以通过函数名,也可以通过函数指针。

(3)      Int(*p)(int,int);表示定义一个指向函数的指针变量P,不是固定指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门存放函数的入口地址的,在一个程序中,一个指针变量可以先后指向同类型的不同函数。

(4)      给指针变量赋值时,只需给出函数名而不必给出参数
如p=max;
因为这是将函数的入口地址赋给p,而不牵涉实参和形参的结合问题,不能写成
p=max(a,b);

(5)      用函数指针变量调用参数时,只需将(*P)代替函数名即可,在(*p)之后的括号中,根据需要写上实参。如
c=(*p)(a,b)
表示“调用由p指向的函数,实参为a,b得到的函数值赋给 c”

(6)      对指针函数的指针变量,像p++,p+n,p—等运算是没有意义的。





2、             用指向函数的指针作函数的参数



原理:有一个sub函数,它有两个形参x1,x2,定义x1,x2为指向函数的指针变量。在调用函数sub时,实参为另个函数名f1,f2,给形参传递的是函数f1,f2的地址。这样在函数sub中就可以调用f1,f2了。如:



实参函数名     f1       f2      

void sub(int(*x1)(int),int(*x2)(int))

{

   inta,b,i,j;

   a=(*x1)(i);

   b=(*x2)(i,j);

}

      为什么不直接调用f1,f2函数呢,而要用函数指针变量呢? 如果只是用到f1,f2函数,完全可以在sub函数中直接调用f1,f2;但是如果在每次调用sub函数时,要调用的函数不是固定的,这次调用f1f2,下次可能需要调用f3,f4,这时,用指针变量就比较方便了。只要在每次调用sub函数时给出不同的函数名作为实参即可。

              如:
#include <stdio.h>



void main()

{

              int max(int,int);

              int min(int,int);

              int add(int,int);

              voidprocess(int,int,int(*fun)(int,int));



              //以上是函数声明



              int a,b;

              printf("enter a andb:");

              scanf("%d,%d",&a,&b);

              printf("max=");

              process(a,b,max);

              printf("min=");

              process(a,b,min);

              printf("sum=");

              process(a,b,add);



}

//函数定义

int max(int x,int y)

{

              int a;

              if(x>y)

                   a=x;

              else

                   a=y;

              return (a);

}

int min (int x,int y)

{

              int z;

              if(x>y)

                   z=y;

              else

                   z=x;

              return z;

}

int add(int x,inty)

{

              int z;

              z=x+y;

              return z;

}

void process(int x,inty,int(*fun)(int,int))

{

              int  result;

              result=(*fun)(x,y);

              printf("%d\n",result);

}

运行结果:

Enter a and b :1,6

Max=6

Min=1

Sum=7



分析:在定义process函数时,在函数首部用int (*fun)(int,int)表示fun是指向函数的指针,该函数是一个整型函数,有两个整型实参。

注意,对作为实参的函数,应在主调函数中用原型作函数声明。

参考:谭浩强 《C程序设计》第三版

出0入0汤圆

 楼主| 发表于 2013-3-26 11:49:02 | 显示全部楼层
我自己顶一下

出0入0汤圆

 楼主| 发表于 2013-3-26 11:50:23 | 显示全部楼层
怎么还没有人关注呢

出0入0汤圆

发表于 2013-3-26 11:52:39 | 显示全部楼层
呵呵!这个对于应用操作系统来讲是必备的知识!

出0入0汤圆

 楼主| 发表于 2013-3-26 11:56:17 | 显示全部楼层
minier 发表于 2013-3-26 11:52
呵呵!这个对于应用操作系统来讲是必备的知识!

出0入0汤圆

 楼主| 发表于 2013-3-26 11:56:59 | 显示全部楼层
minier 发表于 2013-3-26 11:52
呵呵!这个对于应用操作系统来讲是必备的知识!

小弟刚接触,还请多多指教

出0入0汤圆

发表于 2013-3-26 12:02:54 | 显示全部楼层
GUI常用函数指针。

出0入0汤圆

发表于 2013-3-26 16:33:26 | 显示全部楼层
好复杂的样子

出0入0汤圆

发表于 2013-3-27 07:49:26 | 显示全部楼层
学习了,多谢!

出0入0汤圆

发表于 2013-3-27 11:42:58 | 显示全部楼层
什么os?uCOS吗

出0入0汤圆

发表于 2013-3-31 21:45:45 | 显示全部楼层
写的挺好的,顶一下

出0入0汤圆

发表于 2013-3-31 22:11:24 来自手机 | 显示全部楼层
学习了,谢谢了。

出0入0汤圆

发表于 2013-4-18 15:58:07 | 显示全部楼层
学习了,谢谢了。

出0入0汤圆

发表于 2013-4-18 19:01:37 | 显示全部楼层
学习一下。。。。

出0入0汤圆

发表于 2013-4-19 17:08:24 | 显示全部楼层
写得不错哈

出0入0汤圆

发表于 2014-4-1 15:51:30 | 显示全部楼层
写的好~,虽然代码的大小写很奇怪~

出0入0汤圆

发表于 2014-4-2 11:56:13 | 显示全部楼层
楼主总结的不错。
不过,建议谭浩强C语言的书 刚开始看看即可,以后就扔掉,不然会进入很多误区,等你上项目工程后千万别拿着这本书翻过来覆过去的看!

出0入0汤圆

发表于 2014-4-4 11:07:47 | 显示全部楼层
第一次用函数指针就出现了错误!求帮忙
void basic_mowement(void(*move)(void));
void basic_mowement(void(*move)(uint16_t),uint16_t value);
这个两函数函数名一样,形参类型和数目不一样,这两个以函数指针为形参的函数声明没有问题吧?

出0入0汤圆

发表于 2014-4-11 10:10:53 | 显示全部楼层
谭教授的那本C语言书,适合应付个考试。写大点的程序就不够用了。

出0入0汤圆

发表于 2014-5-30 10:12:15 | 显示全部楼层
我学习下.....

出0入0汤圆

发表于 2014-6-6 11:28:00 | 显示全部楼层
建议不要参考谭浩强

出0入0汤圆

发表于 2015-2-23 23:36:18 来自手机 | 显示全部楼层
楼主有个地方错了吧~

出0入0汤圆

发表于 2015-2-23 23:40:34 来自手机 | 显示全部楼层
生来孤独 发表于 2015-2-23 23:36
楼主有个地方错了吧~

void sub(int(*x1)(int),int(*x2)(int))



b=(*x2)(i,j);

出0入0汤圆

发表于 2015-3-8 20:17:54 | 显示全部楼层
学习了,写的很清楚。

出0入0汤圆

发表于 2015-3-8 20:48:06 | 显示全部楼层
很好的东西,谢谢楼主

出0入0汤圆

发表于 2015-7-10 12:11:46 | 显示全部楼层
顶下楼主
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 05:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表