函数指针
定义:函数指针本质上是指针,它是函数的指针(定义了一个指针变量,变量中存储了函数的地
址)。函数都有一个入口地址,所谓指向函数的指针,就是指向函数的入口地址。这里函数名就代
表入口地址。
函数指针存在的意义:
- 让函数多了一种调用方式
- 函数指针作为形参,可以形式调用(回调函数)
定义格式:
返回值类型 (*变量名) (形式参数列表);
举例:
int (*p)(int a,int b);
函数指针的初始化:
- 定义的同时赋值
// 函数指针需要依赖于函数,先有函数,再有指针
// 定义一个普通的函数
int add(int a,int b){ return a + b;}
// 定义一个函数指针,并给他赋值
// 通过以下代码我们发现:函数指针的返回类型和依赖函数的返回类型一致,函数指针的参数个数类型和依赖函
数一致
int (*p)(int a,int b) = add;// 赋值一定要注意:函数不能带有()
- 先定义后赋值
// 定义一个普通的函数
int add(int a,int b){ return a + b;}
// 定义一个函数指针
// int (*p)(int a,int b);
int (*p)(int,int); // 一般写作这种
// 给函数指针赋值
p = add;
注意:
- 函数指针指向的函数要和函数指针定义的返回值类型,形参列表对应,否则编译报错
- 函数指针时指针,但不能指针运算,如p++等,没有实际意义
- 函数指针作为形参,可以形成回调
- 函数指针作为形参,函数调用时的实参只能是与之对应的函数名,不能带小括号()
- 函数指针的形参列表中的变量名可以省略
案例
#include <stdio.h>
/**
* 定义一个函数指针
*/
int max(int a,int b)
{
if(a > b)
return a;
return b;
}
int main(int argc,char *argv[])
{
// 定义测试数据
int a = 3,b = 2,c;
// 直接函数调用
c = max(a,b);
printf("%d,%d两个数中的最大值是%d\n",a,b,c);
// 定义一个函数指针
int (*p)(int,int) = max;
// 间接函数调用
c = p(a,b);
printf("%d,%d两个数中的最大值是%d\n",a,b,c);
c = (*p)(a,b);
printf("%d,%d两个数中的最大值是%d\n",a,b,c);
return 0;
}
回调函数(了解)
概念
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
为什么要用回调函数
因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。
简而言之,回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。
实现
#include <stdio.h>
/**
* 回调函数1
*/
int callback_1(int a)
{
printf("hello,this is callback_1:a=%d\n",a);
return 0;
}
/**
* 回调函数2
*/
int callback_2(int b)
{
printf("hello,this is callback_2:b=%d\n",b);
}
/**
* 实现回调函数
*/
int handle(int x,int (*callback)(int))
{
printf("开始执行!\n");
callback(x);
printf("执行结束!\n");
}
int main(int argc,char *argv[])
{
handle(100,callback_1);
handle(200,callback_2);
return 0;
}
指针函数
定义:本质上是函数,这个函数的返回值类型是指针,这个函数称为指针函数。
语法:
指针类型 函数名(形参列表)
{
函数体;
return 指针变量;
}
举例:
// int *get(int a)
int* get(int a)
{
int *b = &a;
return b;
}
int main()
{
int *a = get(5);
printf("%d\n",*a);
}
注意:
在函数中不要直接返回一个局部变量的地址,因为函数调用完毕后,局部变量会被回收,使得返回的地址就不明确,此时返回的指针就是野指针。
解决方案:
如果非要访问,可以给这个局部变量添加static ,可以延长它的生命周期,从而避免野指针(尽量少用,因为存在内存泄漏)
案例
#include <stdio.h>
/**
* 定义一个函数,传入学生的序号,返回这个学生的所有课程成绩
* @param p 二维数组
* @param n 学生索引(二维数组中行号)
* @return 学生成绩(行号对应的列数组)
*/
float* search(float (*p)[4],int n)
{
// 定义一个指针,用来接收查询到的某个学生的所有课程
float *pt;
pt = *(p+n);// *(p+n),*p[n],p[n]
return pt;
}
int main(int argc,char *argv[])
{
// 准备一个二维数组
float score[][4] = {{60,70,80,89},{55,66,77,88},{90,89,90,91}};
int m;
float *p;
printf("请输入学生序号(0~2):\n");
scanf("%d",&m);
printf("第%d个学生的成绩:\n",m);
// 用来接收某个学生的所有成绩
p = search(score,m);
// 遍历成绩
for(int i = 0;i < 4;i++)
printf("%5.2f\t",*(p+i));
printf("\n");
}
标签:return,函数,int,C语言,printf,函数指针,指针
From: https://blog.csdn.net/weixin_69851948/article/details/144403064