函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结

函数指针

首先引入函数指针的定义:函数指针是一个用来存放函数地址的指针变量,

<>一.下面引入一个例子:

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第1张图片

对于上述例子中新建立的函数Add(),有以下几个需要注意的地方:

1.&Add 与 Add在数组中代表不同的意义,但在函数指针中,两者代表的意义相同,即Add以及--->> &Add的形式均代表函数的地址,输出的结果相同。

2.注意函数指针的书写方法,以Add函数为例:,其函数的指针表达形式为:  int(*pa)(int,int)=Add;  其中,和数组指针的表达方式相类似,(*pa)表示其为一个指针,(int,int)是传入函数的参数类型,最前面的 int 为该函数的返回值类型;

3.对于函数指针的解引用操作来说, (*pa)()代表函数的调用,上述例子中(*pa)(2,4)即代表将2,4两个参数传入到函数Add中去;

 <>二.下面讲解两个代码的含义:

1.  (*(void(*)())0)()

//把0强制类型转换成: void(*)()函数指针类型;0就是一个函数的地址;-->调用0地址出的该函数;

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

//建立一个函数signal,其包含两个参数,类型分别为int类和一个函数指针,该函数指针指向的参数类型为int,返回值为void;而这个函数的返回类型同样是一个函数指针,该函数指针指向的参数为int,返回类型为void;

-->>下面对该函数类型进行简化:  typedef void(* pfun_t)(int),原式可以转换为void pfun_t(int,pfun_t);

<>三.函数指针的解引用

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第2张图片

 ->>以上四种调用方法均可以输出相同的效果,但不建议后面两种;此处的*没有用处;

函数指针数组

-->>存放函数指针的数组

先引入一个例子:

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第3张图片

 -->>下面建立一个函数指针数组来存放并调用:

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第4张图片

->>如上图,建立的函数指针数组为  int(*parr[4])(int, int) = {Add,Sub,Mul,Div};

则parr[i](2,3)中当i取0,1,2,3时,会分别调用上述四个函数,并打印返回值;

下面是一个例子,加强理解;函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第5张图片

-->>函数指针数组的用途:--转移表--,实现一个计算器,大致代码如下:

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第6张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第7张图片

 指向函数指针数组的指针

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第8张图片

 了解完指向函数指针的数组的定义,我们再来了解回调函数的含义:函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第9张图片

 回调函数通过其收到的地址,去回调其地址对应的函数,仍然以上题为例:

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第10张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第11张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第12张图片

 

 其中的Calc就是一个回调函数,其通过接收函数的地址,在函数的内部通过调用这个函数,下面先演试下库函数qsort的内容;该函数的头文件为:#include ;

->>qsort是一个库函数,其包含的四个参数分别为:  传入的数组首元素地址,待排序数组元素的个数,待排序数组每个元素的大小-单位是字节,函数指针:比较两个元素的所用函数的地址(由函数使用者自己创建);其中,void* e1,以及void* e2为无类型指针,既可以接收int类型变量的地址,又可以接收char类型变量的地址;int(*cmp)(const void*e1,const void*e2)为一个函数指针;

#cmp_int函数的比较对返回值有规定:

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第13张图片

 

#void*类型的指针不可以进行解引用操作,原因是:无法确定具体指针的类型;同样也不能进行加减整数的操作;

-->>下面是对利用qsort进行排序的几个例子:

例1:对一个整形数组arr进行排序

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第14张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第15张图片

例2:对一个浮点型数组f进行排序;

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第16张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第17张图片 例3:对一个结构体数组s进行排序

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第18张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第19张图片

 #重点关注结构体数组在进行比较时的操作方法,与整形和浮点型数组的比较方法不同。

补充:若要比较名字name的大小,不可以直接使用<>=,应该用strcmp函数,记得引用头文件#include;具体如下:

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第20张图片

 例4:对于结构体数组按不同属性进行排序的一个综合:

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第21张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第22张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第23张图片

例5:建立一个可以排序任何类型参数的冒泡排序函数

创建一个程序,可以进行整形数组,浮点型数组,以及结构体数组的冒泡排序,并打印最终结果; 

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第24张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第25张图片函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第26张图片

函数指针,函数指针数组, 指向函数指针数组的指针,qsort函数部分知识点总结_第27张图片##其中,对于if (cmp((char*)base + j * width, (char*)base + (j + 1) * width)>0) {Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);}的操作,由于不同类型的比较方法不同,所以要将比较方法抽离出来,放一个函数指针,把能进行比较方法的函数地址传进来,根据地址去调用比较函数;其要接收两个参数,即为要进行比较的那两个元素的地址;在函数内部比较结束后,返回值大于0则说明第一个元素大于第二个元素,则进行交换;

你可能感兴趣的:(c++,开发语言,c语言,算法,数据结构)