网站首页 > 技术文章 正文
一个函数会占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这就和数组名表示数组的首地址概念类似。可以把函数的首地址赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这样的指针就是函数指针,函数指针就是指向函数的指针。通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。
1.函数指针的定义
函数指针将C语言的灵活性和强大功能推向了一个新的高度。作为一种指向函数的指针,它不仅能够提高代码的复用性,还能实现回调、模拟面向对象编程以及设计模式等高级特性。
函数指针的定义形式为:
returnType (*pointerName)(param list);
# 返回值类型 +(指针变量名)(形参列表)
eg:
int (*p)(int, int);
例如:
typedef int (*fun_ptr)(int,int); // 声明一个指向同样参数、返回值的函数指针类型
(1)returnType 表示函数返回值类型,pointerNmae 为指针名称,param list 为函数参数列表。
(2)param list参数列表中可以同时给出参数的类型和名称,也可以只给出参数的类型,省略参数的名称,这一点和函数原型非常类似。
(3)注意( )的优先级高于*,第一个括号不能省略,如果写作 returnType *pointerName(param list);就成了函数原型,它表明函数的返回值类型为 returnType *。
2. 函数指针的三种定义方式
(1)先定义出函数的类型,再通过类型定义函数指针变量
/*定义出一个函数类型,返回值是void,形参列表(int,char)*/
typedef void(MAX)(int, char);
MAX* pFunc = func;
(2)先定义出函数指针的类型,再通过指针类型定义函数指针变量
typedef void(*MAX)(int, char);
MAX pFunc = func;
(3)重点:直接定义函数指针变量
int max(int a,int b);
int (*p1max) (int a,int b) = max;
函数指针和指针函数的区别:
# 指针函数本质是一个函数,其返回值是一个指针:
int* p(int, int);
# 函数指针本质是一个指针,其指向一个函数:
int (*p)(int, int);
简单点就是:函数名带括号的就是函数指针,否则就是指针函数。
3.函数指针的应用—回调函数
函数指针变量可以作为某个函数的参数来使用,回调函数就是一个通过函数指针调用的函数。
写一个函数A,并把这个函数A的地址赋值给一个函数指针,然后把这个函数指针当作参数赋给另一个函数B,函数B通过函数指针来调用函数A。这个函数A就是回调函数。为什么要使用回调函数,因为使用回调函数能够实现底层代码的解耦。
实例
functionpointMain.c
#include<stdio.h>
#include "Method.h"
int main()
{
int x,y,max_value = 0;
int ps[2] = {0,0};
/*定义函数指针*/
/* 函数指针的定义形式:returnType (*pointerName)(param list);*/
int (*p1max) (int a,int b) = max;
int (*p2max) (int ,int ) = max;/*参数名称可以省略*/
printf("Input two numbers:");
scanf("%d%d",&x,&y);
max_value = (*p1max)(x,y);
printf("Max value: %d\n", max_value);
max_value = 0;
max_value = (*p2max)(x,y);
printf("Max value: %d\n", max_value);
max_value = 0;
populate_array(x,y,ps, sizeof(ps)/sizeof(ps[0]), max,min);/*max min 是回调函数 */
printf("Max value: %d\n", ps[0]);
printf("Min value: %d\n", ps[1]);
getchar();
return 0;
}
Method.c
#include "Method.h"
#include<stdio.h>
int max(int a,int b)
{
return a>b ? a : b;
}
int min(int a,int b)
{
return a<b ? a : b;
}
void populate_array(int a,int b,int *array, int arraySize, int (*getMaxValue)(int a,int b),int (*getMinValue)(int a,int b))
{
array[0] = getMaxValue(a,b);
array[1] = getMinValue(a,b);
printf("size = %d\n",arraySize);
}
Method.h
#ifndef _METHOD_H /*防止头文件重复包含*/
#define _METHOD_H
int max(int a,int b);/*有函数返回值的求最大值函数*/
int min(int a,int b);
void populate_array(int a,int b,int *array, int arraySize, int (*getMaxValue)(int a,int b),int (*getMinValue)(int a,int b));
#endif
运行结果
4.参考内容
[1]菜鸟教程《C函数指针与回调函数》
https://www.runoob.com/cprogramming/c-fun-pointer-callback.html
[2]CSDN作者极客代码的文章《C语言函数指针全面指南:从入门到精通》,文章链接为
https://blog.csdn.net/suifengme/article/details/141174126
[3]C语言中文学习网
[4]CSDN作者woshizuopie的文章《嵌入式C语言基础知识 -- 函数指针&回调函数&结构体指针》,文章链接为:
https://blog.csdn.net/woshizuopie/article/details/118608507
本文内容来源于网络,仅供参考学习,如内容、图片有任何版权问题,请联系处理,24小时内删除。
作 者 | 郭志龙
编 辑 | 郭志龙
校 对 | 郭志龙
- 上一篇: C++知识点 35:赋值运算符重载
- 下一篇: 精品案例-用C语言实现成绩与等级相互转换
猜你喜欢
- 2025-08-02 C|在一个结构体嵌套一个共用体实现一体多用
- 2025-08-02 C++中,常用的强制类型转换函数
- 2025-08-02 如何使用C语言编程实现一个推箱子游戏?技术核心和算法实现
- 2025-08-02 C++20 新特性(24):模板访问权限和typename的放宽
- 2025-08-02 C++零基础到工程实践
- 2025-05-14 “Rust真能防住C代码里的那些老问题吗?我们做了个实验验证”
- 2025-05-14 C语言连续生成不同的随机数方法实例加程序
- 2025-05-14 C++20尝鲜:新增语法糖
- 2025-05-14 C 语言的整数提升
- 2025-05-14 C语言之位运算符
- 08-06中等生如何学好初二数学函数篇
- 08-06C#构造函数
- 08-06初中数学:一次函数学习要点和方法
- 08-06仓颉编程语言基础-数据类型—结构类型
- 08-06C++实现委托机制
- 08-06初中VS高中三角函数:从"固定镜头"到"360°全景",数学视野升级
- 08-06一文讲透PLC中Static和Temp变量的区别
- 08-06类三剑客:一招修改所有对象!类方法与静态方法的核心区别!
- 1524℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 663℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 532℃MySQL service启动脚本浅析(r12笔记第59天)
- 494℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 494℃启用MySQL查询缓存(mysql8.0查询缓存)
- 482℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 464℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 462℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (70)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)