[C语言] 函数指针

[复制链接]
 楼主| 一路向北lm 发表于 2019-7-14 17:20 | 显示全部楼层 |阅读模式
什么是函数指针
如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针

那么这个指针变量怎么定义呢?虽然同样是指向一个地址,但指向函数的指针变量同我们之前讲的指向变量的指针变量的定义方式是不同的。例如:int(*p)(int, int);
这个语句就定义了一个指向函数的指针变量 p。首先它是一个指针变量,所以要有一个“*”,即(*p);其次前面的 int 表示这个指针变量可以指向返回值类型为 int 型的函数;后面括号中的两个 int 表示这个指针变量可以指向有两个参数且都是 int 型的函数。所以合起来这个语句的意思就是:定义了一个指针变量 p,该指针变量可以指向返回值类型为 int 型,且有两个整型参数的函数。p 的类型为 int(*)(int,int)。
所以函数指针的定义方式为:
函数返回值类型 (* 指针变量名) (函数参数列表);
“函数返回值类型”表示该指针变量可以指向具有什么返回值类型的函数;“函数参数列表”表示该指针变量可以指向具有什么参数列表的函数。这个参数列表中只需要写函数的参数类型即可。
我们看到,函数指针的定义就是将“函数声明”中的“函数名”改成“(*指针变量名)”。但是这里需要注意的是:“(*指针变量名)”两端的括号不能省略,括号改变了运算符的优先级。如果省略了括号,就不是定义函数指针而是一个函数声明了,即声明了一个返回值类型为指针型的函数。
那么怎么判断一个指针变量是指向变量的指针变量还是指向函数的指针变量呢?首先看变量名前面有没有“*”,如果有“*”说明是指针变量;其次看变量名的后面有没有带有形参类型的圆括号,如果有就是指向函数的指针变量,即函数指针,如果没有就是指向变量的指针变量。
最后需要注意的是,指向函数的指针变量没有 ++和 -- 运算。

评论

好几年了 一直用不好  发表于 2019-7-16 16:55
 楼主| 一路向北lm 发表于 2019-7-14 17:22 | 显示全部楼层
如何用函数指针调用函数
给大家举一个例子:
  1. 1.        int Func(int x);   /*声明一个函数*/
  2. 2.        int (*p) (int x);  /*定义一个函数指针*/
  3. 3.        p = Func;          /*将Func函数的首地址赋给指针变量p*/
赋值时函数 Func 不带括号,也不带参数。由于函数名 Func 代表函数的首地址,因此经过赋值以后,指针变量 p 就指向函数 Func() 代码的首地址了。

下面来写一个程序,看了这个程序你们就明白函数指针怎么使用了:
  1. 1.        # include <stdio.h>
  2. 2.        int Max(int, int);  //函数声明
  3. 3.        int main(void)
  4. 4.        {
  5. 5.            int(*p)(int, int);  //定义一个函数指针
  6. 6.            int a, b, c;
  7. 7.            p = Max;  //把函数Max赋给指针变量p, 使p指向Max函数
  8. 8.            printf("please enter a and b:");
  9. 9.            scanf("%d%d", &a, &b);
  10. 10.            c = (*p)(a, b);  //通过函数指针调用Max函数
  11. 11.            printf("a = %d\nb = %d\nmax = %d\n", a, b, c);
  12. 12.            return 0;
  13. 13.        }
  14. 14.        int Max(int x, int y)  //定义Max函数
  15. 15.        {
  16. 16.            int z;
  17. 17.            if (x > y)
  18. 18.            {
  19. 19.                z = x;
  20. 20.            }
  21. 21.            else
  22. 22.            {
  23. 23.                z = y;
  24. 24.            }
  25. 25.            return z;
  26. 26.        }
输出结果是:
please enter a and b:3 4
a = 3
b = 4
max = 4

airwill 发表于 2019-7-14 22:02 | 显示全部楼层
函数指针是比较难懂的概念, 却又用得比较多.   值得好好研究讲解一下, 谢谢
 楼主| 一路向北lm 发表于 2019-7-15 19:48 | 显示全部楼层
airwill 发表于 2019-7-14 22:02
函数指针是比较难懂的概念, 却又用得比较多.   值得好好研究讲解一下, 谢谢 ...

慢慢品味
雪山飞狐D 发表于 2019-7-15 20:23 | 显示全部楼层
我提一点:函数指针不能+1,呵呵,原因就是不同函数步进肯定不一样
airwill 发表于 2019-7-15 21:37 | 显示全部楼层
函数指针不能+1, 是不对的,  肯定能加, 不过加1 后的地址增加量要看指针类型
coody 发表于 2019-7-15 22:14 | 显示全部楼层
记得一个名字:指向函数指针数组指针的指针

评论

指针的指针的指针  发表于 2019-12-28 08:36
hobbye501 发表于 2019-7-16 16:56 | 显示全部楼层
都怪基础没打好。。。指针,链表。函数指针 一直没有研究明白
fswyt 发表于 2019-7-17 09:04 | 显示全部楼层

这个函数指针调用不是直接是c = p(a,b)吗?为什么还要加*号?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
QWE4562009 发表于 2019-7-17 10:35 | 显示全部楼层
指针属于C中比较难学的是吗
 楼主| 一路向北lm 发表于 2019-7-17 13:23 | 显示全部楼层
hobbye501 发表于 2019-7-16 16:56
都怪基础没打好。。。指针,链表。函数指针 一直没有研究明白

写个操作系统 全明白
 楼主| 一路向北lm 发表于 2019-7-17 13:24 | 显示全部楼层
fswyt 发表于 2019-7-17 09:04
这个函数指针调用不是直接是c = p(a,b)吗?为什么还要加*号?

自己领悟
 楼主| 一路向北lm 发表于 2019-7-17 13:24 | 显示全部楼层
QWE4562009 发表于 2019-7-17 10:35
指针属于C中比较难学的是吗

精髓
 楼主| 一路向北lm 发表于 2019-7-17 13:24 | 显示全部楼层
coody 发表于 2019-7-15 22:14
记得一个名字:指向函数指针数组指针的指针

脑袋炸了
lihui567 发表于 2019-7-17 13:39 | 显示全部楼层
特别在回调函数中,我们经常把函数指针作为函数参数,挺方便的
fswyt 发表于 2019-12-27 14:57 | 显示全部楼层

没想通,能指教下吗?我平时都是c=p(a,b)的
fswyt 发表于 2019-12-27 15:02 | 显示全部楼层


如图,这是我平常使用的函数指针

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
chongdongchen 发表于 2019-12-28 10:51 | 显示全部楼层
函数指针本身肯定不能做+1运算,因为函数体大小是不确定的。
但是函数指针的指针就可以了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

3837

帖子

81

粉丝
快速回复 在线客服 返回列表 返回顶部