C进阶:指针(2),qsort函数,模拟实现冒泡算法(上)

简介: C进阶:指针(2),qsort函数,模拟实现冒泡算法

一.回调函数

要想理解回调函数,就要先知道什么是函数指针,函数指针详见:http://t.csdn.cn/oYiuC

1.回调函数的定义

函数指针作为某个函数的参数

函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。

简单讲:回调函数是由别人的函数执行时调用你实现的函数。

2.来自知乎作者常溪玲的解说

  你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。

我们来看一个实例:

1. #include <stdlib.h>  
2. #include <stdio.h>
3. 
4. void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
5. {
6. for (size_t i=0; i<arraySize; i++)
7.         array[i] = getNextValue();
8. }
9. 
10. // 获取随机值
11. int getNextRandomValue(void)
12. {
13. return rand();
14. }
15. 
16. int main(void)
17. {
18. int myarray[10];
19. /* getNextRandomValue 不能加括号,否则无法编译,因为加上括号之后相当于传入此参数时传入了 int , 而不是函数指针*/
20. populate_array(myarray, 10, getNextRandomValue);
21. for(int i = 0; i < 10; i++) 
22.     {
23. printf("%d ", myarray[i]);
24.     }
25. printf("\n");
26. return 0;
27. }

实例中 populate_array() 函数定义了三个参数,其中第三个参数是函数的指针,通过该函数来设置数组的值。

实例中我们定义了回调函数 getNextRandomValue(),它返回一个随机值,它作为一个函数指针传递给 populate_array() 函数。

populate_array() 将调用 10 次回调函数,并将回调函数的返回值赋值给数组。

二.qsort函数

顾名思义, quick sort  快排,就是快速排序的意思,它是一个库函数,包含在头文件 <stdlib.h> 中,我们来看看它在库函数里是怎么定义的:

由定义可知,qsort 函数一共有 4 个参数:

 

1. 第一个参数是 类型为 void * ,名为 base 的变量;

2.第二个参数和第三个参数都是 一个无符号整型;

3.第四个参数是一个两个参数类型为 const void * ,返回值类型为 int 的函数指针。

那这些都代表的是什么意思呢?

我们来看官方的解释:

翻译版本:

由此可知:

1.第一个参数是指向要排序的数组的第一个元素的指针,所以实参应该传一个数组过来;

2.第二个参数是数组中元素的个数;

3.第三个参数是数组中每个元素的大小;

4.第四个参数是一个函数指针,且需要我们自己写。

所以我们需要传一个数组,数组中元素的个数,每个元素的大小,和一个函数;

因为 qsort 函数在设计的时候,作者并不知道你要比较什么,且也不知道你想要怎么比较,所以这个函数就需要我们自己来完成,我们写这个函数时,应把函数的两个参数的两个参数类型设计成 void *,返回值类型设计成 int 。

补充: void * 就像一个垃圾桶,你往里边放什么类型的指针都行,但不能对他进行解引用操作,因为不知道是什么类型的指针,如果解引用就不知道要访问几个字节

再来看看 qsort 函数的返回值:

有了以上这些,我们就可以尝试使用这个函数

下面来看一个实例:

1. #include <stdio.h>
2. #include <stdlib.h>
3. 
4. int cmp_int (const void * e1, const void * e2)   //这个函数的解释请参看下面的图解
5. {
6. return ( *(int*)e1 - *(int*)e2 );
7. }
8. 
9. int main()
10. {
11. int i;
12. int arr[] = { 88, 56, 100, 2, 25 };
13. printf("排序之前的列表:\n");
14. for( i = 0 ; i < 5; i++ ) {
15. printf("%d ", arr[i]);
16.    }
17. 
18. qsort(arr, 5, sizeof(int), cmp_int);  //调用 qsort 函数
19. 
20. printf("\n排序之后的列表:\n");
21. for( i = 0 ; i < 5; i++ )
22.    {
23. printf("%d ", arr[i]);
24.    }
25. 
26. return 0;
27. }

结果:


目录
相关文章
|
2月前
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
138 67
|
2月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
60 4
|
3月前
|
存储 C语言 C++
如何通过指针作为函数参数来实现函数的返回多个值
在C语言中,可以通过将指针作为函数参数来实现函数返回多个值。调用函数时,传递变量的地址,函数内部通过修改指针所指向的内存来改变原变量的值,从而实现多值返回。
|
3月前
|
存储 搜索推荐 C语言
如何理解指针作为函数参数的输入和输出特性
指针作为函数参数时,可以实现输入和输出的双重功能。通过指针传递变量的地址,函数可以修改外部变量的值,实现输出;同时,指针本身也可以作为输入,传递初始值或状态。这种方式提高了函数的灵活性和效率。
|
3月前
|
C++
指针中的回调函数与qsort的深度理解与模拟
本文详细介绍了回调函数的概念及其在计算器简化中的应用,以及C++标准库函数qsort的原理和使用示例,包括冒泡排序的模拟实现。
26 1
|
3月前
利用指针函数
【10月更文挑战第2天】利用指针函数。
22 1
|
3月前
|
算法 搜索推荐 C语言
【C语言篇】深入理解指针4(模拟实现qsort函数)
【C语言篇】深入理解指针4(模拟实现qsort函数)
30 2
|
4月前
|
算法 索引 容器
双指针算法详解
本文介绍了双指针算法及其应用。双指针算法是在数组或字符串中常用的高效技术,通过维护两个指针遍历数据结构以解决特定问题。根据指针移动方向,可分为同向双指针、相向双指针和快慢指针。同向双指针如移动零和复写零问题;快慢指针如快乐数问题;相向双指针如盛水最多的容器、有效三角形数量及多数之和等问题。通过合理运用双指针技巧,可简化代码并提高效率。
81 4
|
4月前
|
XML JavaScript 前端开发
学习react基础(1)_虚拟dom、diff算法、函数和class创建组件
本文介绍了React的核心概念,包括虚拟DOM、Diff算法以及如何通过函数和类创建React组件。
42 3
|
3月前
|
数据可视化 搜索推荐 Python
Leecode 刷题笔记之可视化六大排序算法:冒泡、快速、归并、插入、选择、桶排序
这篇文章是关于LeetCode刷题笔记,主要介绍了六大排序算法(冒泡、快速、归并、插入、选择、桶排序)的Python实现及其可视化过程。
25 0

热门文章

最新文章