C语言之路第十七天:指针详解(二)

本文详细介绍了函数指针的概念,包括其定义格式、调用方式以及在数组和回调函数中的应用。通过实例解析了如何声明和使用函数指针,以及如何通过typedef简化类型定义。此外,还探讨了函数指针数组和指向函数指针数组的指针,并展示了如何利用函数指针实现简单的运算器。最后,提到了回调函数的概念及其在实际编程中的作用,例如通过qsort函数进行排序操作。
摘要由CSDN通过智能技术生成

一,函数指针:即指向函数的指针

函数指针定义格式:函数返回数据类型  (*指针名)(传入数据的数据类型) 

函数指针的类型是怎样的呢?去掉指针名就是类型,即:函数返回数据类型  (*)(传入数据的数据类型) 如上面这个函数指针的类型是 int(*)(int, int)

下面看两个代码:

1,(*(void (*)())0)()

首先void (*)()是一个函数指针,将0强制转化为函数指针的数据类型,之后前面的*对这个指针进行解引用,后面的括号是调用这个函数

2,void (*signal(int,void(*)(int)))(int)

首先要知道函数去掉函数名和传入参数就是函数返回类型

这个signal (int ,void(*)(int))是一个函数,其参数是int 和void(*)(int),原代码去掉这些是void (*)(int)说明这个函数的返回值是一个函数指针,参数是int 无返回值

综上:上面这个代码是一个函数,函数名是 signal,其参数是int 和void(*)int ,返回值void(*)int

解释:

signal是一个函数声明

signal有两个参数,一个是int,一个是函数指针,该函数指针指向的函数参数是int,返回类型是                void

signal函数的返回类型是一个函数指针,该函数指针指向的函数参数是int,返回值是void

这样看着是不是很复杂,还记得我们学过typedef对数据类型进行重新定义吗?

下面进行从新定义:

以往:typedef unsigned int unit :将unsigned int定义成 unit

但是对于函数指针的重命名有所不同

typedef void(*)(int) pfunt 这种重定义不对

正确的应该是:typedef void(* pfunt)(int) ,将void(*)(int)定义为pfunt

这样上面的复杂形式就可以写成:pfunt signal (int,pfunt)

函数指针的调用:

 上面这几个都可以调用函数指针p指向的函数,*有无和多少并无关系,可以不解引用直接使用

但是这里建议使用前两种,避免产生误解。

二,函数指针数组

是一个数组,存放的是函数指针

创建:函数返回类型  (*数组名 [数组元素个数])(传入参数类型)

注意,这些指针类型要相同,即都是:函数返回类型  (*)(传入参数类型)

看下面的运用

 利用函数指针数组实现简单的运算器

 

 这种算法将函数指针存在一个数组中,通过输入值来确定调用的函数运算,同时方便后期扩展,加入其他运算,只需要改一下菜单,将新加入的函数放到数组中,再改一下if判断条件。

上面这个程序可以通过switch语句实现,但是效果并不好。

三,指向函数指针数组的指针

是一个指针,指向一个数组,这个数组里面的元素都是函数指针

 总结:数组指针: 数组数据类型  (*指针名)[元素个数]

            函数指针:函数返回数据类型  (*指针名)(传入参数类型)

            函数指针数组:函数返回类型  (*数组名[元素个数])(传入参数类型)

            指向函数指针数组的指针:函数返回类型(*(*指针名)[元素个数])(传入类型)

 四,回调函数

通过函数指针调的函数,把一个函数的地址传给另外一个函数,,当这个指针被用来调用其所指的函数时,我们就说这是回调函数,回调函数不是由该函数的实现方直接调用,而是再特定的事件或条件发生时由另外的一方调用的

 

这个代码,通过test函数调用函数print,这里的print就被称为回调函数

接下来里了解一个库函数,qsort,这是一个对任意数据类型进行排序的函数

void* :无具体类型指针,可将任何数据类型用这个指针定义,都不出错 

void*类型的指针可以接受任何类型的地址

对于void*不可以进行解引用,因为没有数据类型,解引用不知道访问几个字节,也不可以进行+-

有关qsort的使用:

1,引头文件:#include<stdlib.h>

2,看写入的参数

void qsort(

 void *base,

size_t num,

 size_t width,

 int (__cdecl *compare )(const void *elem1, const void *elem2 )

 )前三的都很好理解,分别是:排序数组首元素地址,写数组名即可;排序数组元素个数;每个元素大小;

第四个是比较方法,需要自己根据不同数据类型自己写的一个函数,函数指针的两个参数是要比较的两个元素地址,返回值是int

 

之前写的冒号排序

 

 用qsort实现:

什么数据类型就要进行怎么样的强制类型转化

浮点数的排序

结构体进行排序: 

年龄:

 名字:

qsort内部逻辑: 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值