认识函数指针

本文详细介绍了C++中的函数指针,包括其声明、类型、使用方法及在回调函数中的应用。通过实例解析了如何使用函数指针进行排序,并探讨了函数指针数组的概念。内容涵盖函数地址理解、函数指针声明、回调函数的实现以及函数指针在排序算法qsort中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数指针:一个用于存放一个函数地址的指针,可以用于回调函数的实现。


        目录

1、认识函数地址

2、认识函数指针

(1) 函数指针的声明

(2) 函数指针的指针类型

(3) 函数指针的使用方法

(4) 函数指针的应用 —— 回调函数

3、拓展:函数指针数组


1、认识函数地址

假设有一个数组int arr[10],arr 代表首元素的地址,而 &arr 代表整个数组的地址

假设有一个函数void Add(int x, int y),Add就是函数的地址,&Add也是函数的地址,和数组不一样,这两者是等价的。

2、认识函数指针

(1) 函数指针的声明

函数指针的声明和数组指针的声明比较类似,我们要让一个指针指向一个数组,需要知道所指向数组的大小、数组元素类型。同理,要让一个指针指向一个函数,那就需要知道函数形参(包括形参类型、形参个数) 和 函数返回值

假设我们要保存下面这个函数的地址

int Add(int x, int y)
{
    return x + y;
}

声明的步骤如下:

  • 先用一个变量去接收函数的地址:ptr = &Add;
  • 因为这个变量是一个指针,所以:*ptr = &Add;
  • 这个指针所指向的函数形参类型是两个int类型:(*ptr)(int , int) = &Add
  • 这个指针指向的函数返回值是int类型:int (*ptr)(int , int) = &Add

因此,完整的函数声明方式是

int (*ptr)(int , int) = &Add;

 

(2) 函数指针的指针类型

数组如果将数组名和数组大小去掉,剩下的的就是数组元素的类型;

指针如果将指针名去掉,剩下的就是指针类型;

因此,函数指针的指针类型为

int (*)(int , int)

(3) 函数指针的使用方法

函数指针保存了一个函数的地址,通过解引用,我们可以找到这个函数,因此调用方式如下:

(*ptr)(2 , 3);    //等同于调用Add(2 , 3)
// ptr(2 , 3);    —— 这种写法是等价的

注意:上面的 * 是一个摆设,只是便于初学者知道,函数指针解引用可以找到对应的函数,但是实际上不解引用也是可以的,即便是多几个 * 也是一样的。

(4) 函数指针的应用 —— 回调函数

=================== 提出问题 ===================

下面是qsort函数的声明,qsort函数用于给一组数据排序,这组数据可以是任意类型。

那么问题来了,既然是排序,必然要比较两个数据的大小,如果传入的是自定义类型,该怎么比较大小呢?

================ 分析问题 ================

qsort函数的第三个参数需要传入一个函数指针, 这个参数其实就是在告诉qsort函数,如果我传入一个结构体类型,我是希望通过结构体大小比较,还是通过结构体中的某个成员比较。

我们可以实际调用试试。假设我们要给一个结构体数组排序,排序方式是通过结构体中的 name 成员来比较大小。

struct Person
{
	char name[20];
	int age;
};

int main() {
	struct Person arr[3] = { { "张三",15 },{ "李四",30 },{ "王五",10 } };

	return 0;
}

第三个参数已经明确了函数的返回值和形参类型,返回值为int,形参2个,都是const void* 类型,实际声明和调用如下:

struct Person
{
	char name[20];
	int age;
};

int my_compare(const void* e1, const void* e2)
{
	return strcmp(((Person*)e1)->name, ((Person*)e2)->name);
}

int main() {
	struct Person arr[3] = { { "张三",15 },{ "李四",30 },{ "王五",10 } };

	qsort(arr, 3, sizeof(Person), my_compare);

	for (size_t i = 0; i < 3; i++)
	{
		printf("%s\n", arr[i].name);
	}
	return 0;
}

打印结果如下:

 

3、拓展:函数指针数组

函数指针数组其实就是一个保存函数指针的数组,去掉数组名和数组大小就是函数指针的类型。假设我们要保存的函数指针类型为

int (*)(int,int)

 我们加上数组名和数组大小,即ptrArr[10],那么函数指针数组为

int (*ptrArr[10])(int,int)

上述函数指针数组 ptrArr 保存的函数必须满足:

  • 返回值是int
  • 形参有两个,均为int类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值