指针(三)

函数指针

函数指针:存储函数的地址,可以通过这个地址来调用函数。函数指针的声明需要指定函数返回值的类型、函数名(这里用指针名代替)以及函数的参数列表(包括参数的类型和数量)。但是,在声明函数指针时,我们不会给出函数名,而是使用指针名来代替。

函数指针数组

现在先回忆一下指针数组,它是多个相同变量的地址组成一个指针数组,与函数指针数组有点相像。函数指针数组就是多个相同类型且参数类型也一致的函数组成的函数指针数组。举两个例子吧:

第一个:下面有fun1和fun2两个函数且返回类型和参数相同,这两个函数的函数指针是这样写的void (*pf)(void) ,把变量(pf)抛开剩下的就是函数指针的类型【void (*) (void)】。接着说说函数指针数组:它就是再函数指针上加一个方括号[]【数组的表示符】即void (*pf[])(void),它的类型【void (*) (void)[]】。函数的地址和&函数名一个意思,所以加不加都无所谓。最后就是打印,函数指针数组说到底是函数组成的所以调用它是还是需要函数调用符()。

第二个:整数的加减乘除,将加减乘除放在pf[5]函数指针数组里然后直接调用函数指针数组就可以。

指向函数指针数组的指针

指向函数指针数组的指针是一个指针,它指向一个数组,而这个数组的每个元素都是一个函数指针且每个函数指针具有相同的返回类型和参数列表。

复制代码
void fun1()
{
	printf("i like father\n");
}
void fun2()
{
	printf("i like mother\n");
}
int main()
{
	void (*pf[2])(void) = { fun1, fun2 };//函数指针数组
	void (*(*ppf)[2])(void) = &pf;//指向函数指针数组的指针
	int i = 0;
	for (i = 0; i < 2; i++)
	{
		(*ppf)[i]();//*ppf等价于ppf[0]
	}
	return 0;
}

下面总结函数指针,函数指针数组和指向函数指针数组的指针三者之间的联系 :

复制代码
void test(const char* str)
{
 printf("%s\n", str);
}
int main()
{
 //函数指针pfun
 void (*pfun)(const char*) = test;
 //函数指针的数组pfunArr
 void (*pfunArr[5])(const char* str);
 pfunArr[0] = test;
 //指向函数指针数组pfunArr的指针ppfunArr
 void (*(*ppfunArr)[5])(const char*) = &pfunArr;
 return 0;
}

回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个 函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数 的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进 行响应。

下面是整数的加减乘除的计算,中间运用了回调函数,对于相同操作且重复使用的可以使用回调函数解决问题。

下面讲通过函数 实现库函数qsort的排序(升序为例)

qsort对任何类型的数组都能进行排序,由于qsort是库函数所以直接使用就行,但是作为一个计算机专业的学生需要对它有所了解,下面详细说说:

对于整型数组来说

将数组、数组大小、数组一个元素的字节、一个函数(copy比较相邻元素的大小)这四个参数都写进函数my_sort_int里,这个函数和冒泡排序原理相同,不一样的类型都换成无符号类型,所以可以使用整型或结构体。【my_sort_int(函数名可改变不影响原理)是通用函数】

函数指针将参数强制转换成char*,原因是内存中存放的是十六进制,一个整型是四个字节,对比每个字节的大小。在这个copy函数中返回值分三类(大于、小于、等于0),大于0(说明两个元素为:左>右)为真则进入if语句中,要求为升序则两相邻元素进行交换。

交换则是将内存中的所有数据进行交换,每个字节交换,所以需要知道一个元素有多少个字节(即size)。

对于结构体数组来说

道理与整型数组相同,就不说了看一下运行的流程。 (my_sort_struct就是通用函数)

最后讲一个:void*什么类型的可以使用,但是不能对这个指针进行与运算【例:假设void* p,不能进行p++(元素的大小不知道,加一不知道跳多远)等】

相关推荐
小莞尔3 天前
【51单片机】【protues仿真】基于51单片机的篮球计时计分器系统
c语言·stm32·单片机·嵌入式硬件·51单片机
小莞尔3 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
liujing102329293 天前
Day03_刷题niuke20250915
c语言
第七序章3 天前
【C++STL】list的详细用法和底层实现
c语言·c++·自然语言处理·list
l1t3 天前
利用DeepSeek实现服务器客户端模式的DuckDB原型
服务器·c语言·数据库·人工智能·postgresql·协议·duckdb
l1t3 天前
利用美团龙猫用libxml2编写XML转CSV文件C程序
xml·c语言·libxml2·解析器
Gu_shiwww4 天前
数据结构8——双向链表
c语言·数据结构·python·链表·小白初步
你怎么知道我是队长4 天前
C语言---循环结构
c语言·开发语言·算法
程序猿编码4 天前
基于 Linux 内核模块的字符设备 FIFO 驱动设计与实现解析(C/C++代码实现)
linux·c语言·c++·内核模块·fifo·字符设备
mark-puls4 天前
C语言打印爱心
c语言·开发语言·算法