1.回调函数
首先要明确什么是回调函数。所谓回调函数,就是一个通过函数指针来调用的函数。
如果你将一个函数的指针(即地址)作为参数传入另一个函数中,当这个指针被⽤来调⽤其所指向的函数时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。
以上一篇指针3中讲到的计算器的简单模拟实现中,我们写出了加减乘除四种运算的函数,让用户输出要计算的数字以及对应的运算方式即可得到结果。但是我们在具体实现过程中发现有很多相类似的代码,我们能不能通过某种方式来进行代码的简化呢?
大家很容易看见每种情况下面都有很多相似代码,无非是改了一个调用的函数名罢了。
这个时候我们就可以使用回调函数来简化代码,创立一个函数,参数为函数指针,其中放入上面代码相似的部分,这样每种情况下只需要调用新创立的函数,参数为对应运算方法的函数名即可。
大家可以把两者对比起来看,很明显使用回调函数的代码更优化,更简洁。
2.qsort函数
qsort函数就是快速排序函数,它不像冒泡排序一样只能将整型数据进行排序,它还可以将结构体数据进行排序。
2.1使用qsort函数排序整型数据
我们在使用qsort函数排序整型数据的时候,我们还需要写一个比较函数,方便qsort排序
2.2使用qsort函数排序结构数据
接下来让我们通过调试来看看qsort函数排序的结果。
使用前:
使用后:
其中需要注意的是strcmp函数是比较字符串大小函数,其实质就是比较对应位置上的字符的ascll码值的大小。
3.qsort函数的模拟实现
看完了qsort的使用,我们来看看qsort的模拟实现,尝试自己写一个qsort函数。
我们是参考冒泡排序的大致结构来实现。(非结构数据)
参数第一个指向需要排序的数据的起始地址,第二个参数是需要排序的数据个数,第三个参数是每个数据所占字节的大小,第四个参数是一个函数指针用来比较数据大小的函数。在我们的第二层循环中
有这样一句语句,因为我们不知道来比较的数据是什么类型的,可能是整型,也有可能是浮点型等等,所以我们采取字节指针来指向数据。以整型数据为例,width就是4,这样在我们两两比较数据完了以后方便直接跳过当前数据,到达下一个数据。我们不妨想想如果我们使用整型指针,一次跳过四个字节,而我们比较的是字符型的数据只占一个字节,将会导致一些数据根本就没有参加比较过程!!!而这个作为条件的语句就不难理解了,当j=0的时候就是第一个,第二个数据,当j=1的时候就是第二个,第三个数据...........
判断了两个数据大小之后,就需要进行交换操作了,我们将交换操作单独封装成一个函数。
我们直接上代码。还是一样,我们不知道比较的函数是什么类型,所以我们不能直接交换。但是我们可以通过一个字节一个字节的交换,交换过程可参照定义一个中间变量交换其他两个变量的值的交换过程。
写完以后直接定义一个数组来看看是否出现问题。
很好,没有问题,大家不妨多试几组。
接下来我们来写另一个函数来排序结构体数据。我们只需要改变一下比较函数。
大家可以自己尝试自己动手写一下。完整代码如下。