指针函数和函数指针这对词语总是让人迷惑,其实只是语法长得像,造成极易混淆。先来说明它们的区别
| 项目 | 指针函数 | 函数指针 |
|---|---|---|
| 本质 | 函数 | 指针 |
| 写法 | int *func(int a) | int (*p)(int a) |
| 含义 | 函数执行完,返回一个指针 | 保存函数的入口地址,可以调用函数 |
| 括号位置 | *和返回类型在一起,func是函数名 | (*p)整体 |
| 内存 | 函数在代码段,返回值指针指向数据区 | p变量本身在栈,存函数地址 |
然后逐一展开介绍两者定义和实际使用情况
一、指针函数--返回指针的函数
1、定义
本质是一个函数,这个函数的返回值是指针,一般定义形式是:
数据类型* 函数名 (参数列表);
注意:不能将具有局部作用域的变量的地址作为函数的返回值(因为局部变量的内存空间在函数返回后即被释放,而该变量也不再有效),可以返回全局、static静态变量、malloc堆内存的地址
2、主要应用
a标准库就是指针函数
b返回堆上malloc开辟的内存地址(调用方free释放)
c返回数组/结构体指针,返回对象地址
示例代码
c
#include<stdio.h>
#include<windows.h>
#include<math.h>
int* get_max(int *a,int*b )
{
if(*a>*b)
{
return a;
}
else{
return b;
}
}
int main(){
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
int a=10,b=20;
int *p=get_max(&a,&b);
printf("%d\n",*p);
return 0;
}
运行结果:

二、函数指针--指向函数的指针变量
在C程序中,可以将函数地址保存在函数指针变量中,然后用该指针间接调用函数。
1、定义--
本质是一个指针变量,这个指针保存函数的地址,指向一个函数,一般定义形式是:
返回类型 (*指针名)(参数列表)
2、主要应用
a把函数作为参数传给另一个函数,内部自动调用
c
#include<stdio.h>
#include<windows.h>
#include<math.h>
int add(int a,int b){
return a+b;
}
int sub(int a,int b){
return a-b;
}
int main(){
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
//定义函数指针p,输入是2个int,输出是1个int
int (*p)(int,int);
p=add;//函数名代表函数入口地址
printf("两个数的和是%d\n",p(5,4));//等价add(5,4),结果为9
p=sub;//函数名和&函数名,都可以表示函数的地址
printf("两个数的差是%d\n",p(5,4));//等价sub(5,4),结果为1
return 0;
}
b在嵌入式、单片机大量使用函数指针作为函数表、跳转表
c
#include<stdio.h>
#include<windows.h>
#include<math.h>
void add(int a,int b){
printf("两个数之和是%d\n",a+b);
}
void sub(int a,int b){
printf("两个数之差是%d\n",a-b);
}
int main(){
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
//函数指针数组
void (*func[])(int,int)={add,sub};
func[0](5,4);
func[1](5,4);
return 0;
}
两个运行结果都是如下:

c、多态事项、接口封装
硬件驱动:不同硬件,统一接口,替换不同底层函数(eg:lcd显示,切换lcd1、lcd2,只需要修改函数指针,上层代码不用改动)
d、信号处理、中断回调(单片机):中断触发后执行注册好的回调函数。
当有参数时,函数指针写起来很长,工程代码常常使用typedef重命名,示例如下:
c
#include<stdio.h>
#include<windows.h>
#include<math.h>
int add(int a,int b){
printf("两个数之和是%d\n",a+b);
return a+b;
}
int sub(int a,int b){
printf("两个数之差是%d\n",a-b);
return a-b;
}
int main(){
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
//定义Func_P为函数指针-类型:指向输入2个int参数,返回1个int
typedef int (*Func_P)(int a,int b);
Func_P p=add;
p(1,2);
p=sub;
p(1,2);
return 0;
}
运行结果:
