【C语言】指针之函数指针(回调函数)

文章目录

一、函数指针的概念

二、函数指针的应用

(1)调用函数

(2)将函数的地址作为函数参数传入其他函数。

三、实例演示


一、函数指针的概念

函数指针的定义

若在程序中定义了一个函数,编译时,编译器会为函数代码分配一段存储空间,这段空间的起始地址(又称入口地址)称为这个函数的指针。

与普通变量相同,可以定义一个指针指向存放函数代码的存储空间的起始地址,这样的指针就是函数指针

函数指针的定义格式如下:

返回值类型 (*变量名)(参数列表)

返回值类型是指针指向函数的返回值类型,*表示一个指针变量,参数列表是指针指向函数的形参列表。

【注释】因为*的优先级较高,所以要将*和变量名括起来

实例:

int func(int a,int b);//函数声明

int (*p) (int , int );//定义一个参数列表为两个int型的变量,返回值类型为int型的函数指针p

p=func;//函数指针p指向函数func的起始地址 


二、函数指针的应用

(1)调用函数

使用函数指针调用对应函数,方法和使用函数名调用函数类似,只需将函数名替换成(*指针名)

调用函数指针p指向的函数

(*p)(3,5);

(2)将函数的地址作为函数参数传入其他函数。

将函数的地址传入其他参数,就可以在被调函数中使用实参函数。

将func的地址作为参数传入func2函数

void func2(int(*p)(int,int),int b,int c);


三、实例演示

#include <stdio.h>

void sum_row(int(*arr)[4], int raw, int* sum);//行求和函数声明
void sum_col(int(*arr)[4], int raw, int* sum);//列求和函数声明

//行求和函数定义
void sum_row(int(*arr)[4], int raw, int* sum) {
	int i = 0;
	*sum = 0;
	for (; i < 4; i++) {
		*sum += (*(*(arr + raw-1) + i));
	}
}

//列求和函数定义
void sum_col(int(*arr)[4], int col, int* sum) {
	int i = 0;
	*sum = 0;
	for (; i < 3; i++) {
		*sum += (*(*(arr +i ) + (col-1)));
	}
	
}

int main() {
	int matrix[3][4];
	int i, j;
	
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			matrix[i][j] = i * 4 + j;
		}
	}
	printf("输出初始矩阵:\n");
	int(*p)[4];//定义数组指针p
	p = matrix;
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("%-5d", *(*(p + i) + j));
		}
		printf("\n");
	}

	int sum;
	void (*q)(int(*arr)[4], int raw, int* sum);//定义函数指针
	printf("计算第一行的和:\n");
	q = sum_row;
	(*q)(matrix, 1, &sum);//调用行求和函数
	printf("sum=%d\n",sum);

	printf("计算第一列的和:\n");
	q = sum_col;
	(*q)(matrix, 1, &sum);//调用列求和函数
	printf("sum=%d\n", sum);
}

运行结果:

四、回调函数

程序通过参数把该函数的函数指针传递给了其它函数,在那个函数里面调用这个函数指针就相当于调用这个函数,这样的过程就叫回调,而被调用的函数就叫回调函数。

C语言回调函数的使用

#include <iostream>
using namespace std;

//1.定义回调函数
void print(int n)
{
	for (int i = 0; i < n; i++) {
		cout << "hello world" << endl;
	}
}

//2.定义回调函数原型(函数指针)
typedef void (*CallbackFun)(int);

//3.定义注册回调函数
void registCallback(CallbackFun callback,int n)
{
	callback(n);
}

int main()
{
	//4.将print函数指针作为参数传入注册函数registerCallback中调用callback,即执行了print函数。
	registCallback(print, 10);
}

 许多情况下,并不会再注册的时候调用回调函数,此时可以定义一个CallbackFun全局指针变量,在注册时将函数赋值给它,需要的时候调用它即可。

//1.定义回调函数
void print(int n)
{
	for (int i = 0; i < n; i++) {
		cout << "hello world" << endl;
	}
}

//2.定义回调函数原型(函数指针)
typedef void (*CallbackFun)(int);

CallbackFun myCallback = nullptr;

//3.定义注册回调函数
void registCallback(CallbackFun callback)
{
	myCallback=callback;
}

//4.定义调用回调函数的函数
void exec(int n)
{
	myCallback(n);
}

int main()
{
	//5.注册回调函数
	registCallback(print);
	exec(10);
}

C++回调函数的使用:

在C++中可以使用全局函数和静态函数作为回调函数。考虑到全局函数会破坏封装性,所以一般使用静态成员函数。即通过静态成员函数调用(访问)非静态成员函数的方法,以此来获取静态成员函数中的数据。