(套娃篇下)C:奇妙的指针 回调函数机制+qsort函数排序(很强大)+qsort函数的模拟实现

目录

一.回调函数

二.qsort函数排序法

三.通用冒泡排序法的实现以及qsort函数的模拟实现


一.回调函数

先来了解一下回调函数的机制

回调函数就是一个函数通过函数指针调用的函数,如果你把函数的指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就称这个函数为回调函数

回调函数不是由该函数的实现方直接调用,而是提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者,当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。

上一篇里面计算器的实现使用了函数指针数组的方法

我们来看一看用回调函数的机制怎么实现它。 

 回调函数机制图示:

 

二.qsort函数排序法

引入:

还记得我们之前学习的冒泡函数吗?

冒泡函数排序源代码:

//冒泡函数
void Bubble_sort(int arr[], int sz)
{
	int i = 0;
	int j = 0;

	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}

int main()
{
	int arr[10] = { 9, 8, 7, 6, 4, 5, 3, 2, 1, 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

 

 所以,我们来看一下qsort函数。

先来了解一下这个函数的原型是什么样子的:

void qsort(

void* base,

size_t num,

size_t size,

int(*compare)(const void *e1, const void *e2)  //这个函数需要我们自己实现

);//它有四个参数,一起向下面看~

那都是什么意思呢?

打开cplusplus.com搜索查阅一下

 我们挑重要的内容读:

(我们在这里先学会使用qsort函数,先不考虑qsort函数内部的机制是怎么运行的。)

写代码感受一下qsort函数的实际应用

 

“void*”的解释

1.void*可以接受任意类型的地址

2.void*不能进行解引用操作


3.void*不能进行加减整数操作

再来理解一下这段代码:

 理解之后,我们再来试试能不能对结构体排个序呢?

一起来验证一下:

三.通用冒泡排序法的实现以及qsort函数的模拟实现

前面我们说,常规的冒泡函数是有局限性的,我要是想排序个浮点型,结构体类型,该怎么排序呢?

接下来我们一起来看看。

 

 

 

 

 


//定义一个结构体
struct stu
{
	char name[10];
	int age;
};

//
//根据结构体名字来排序
int cmp_struct_by_name(const void *e1 , const void *e2)
{
	return strcmp(  ((struct stu*)e1) -> name , ((struct stu*)e2) -> name  ); //字符串的比较需要用到strcmp函数
}

//根据结构体年龄来排序
int cmp_struct_by_age(const void *e1, const void *e2)
{
	return ((struct stu*)e1)->age - ((struct stu*)e2)->age; //字符串的比较需要用到strcmp函数
}

//浮点型数组排序
int cmp_float(const void *e1, const void *e2)
{
	return *(float*)e1 - *(float*)e2;
}


//交换
void Swap(char *buf1, char *buf2 , int width) //char能不能写成int呢?   不可以
{
	int i = 0;
	for (i = 0; i < width; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}



//通用版冒泡排序
void bubble_sort(void *base, int sz, int width, int(*cmp)(const void *e1, const void  *e2))
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if ( cmp( (char*)base + j*width, (char*)base + (j + 1)*width) > 0  ) //要升序排列
			{
				Swap( (char*)base + j * width, (char*)base + (j + 1)*width , width );
			}
		}
	}
}


void test1()
{

	struct stu s[3] = { { "zhangsan", 20 }, { "lisi", 30 }, { "wangwu", 10 } };
	int sz = sizeof(s) / sizeof(s[0]);

	bubble_sort(s, 3, sizeof(stu), cmp_struct_by_name);
	for (int i = 0; i < 3; i++)
	{
		printf("%s ", s[i].name);
	}
}


void test2()
{
	float p[] = { 9.0, 8.0, 7.0, 6.0, 5.0, 4.0 }; //浮点型数组

	int sz = sizeof(p) / sizeof(p[0]);

	bubble_sort(p, sz, sizeof(p[0]), cmp_float);

	for (int i = 0; i < sz; i++)
	{
		printf("%f ", p[i]);
	}
}


int main()
{
	//test1();
	test2();

	return 0;
}

这里的代码还加入了一个结构体的比较,大家可以看一看

去自己的编译器里面跑一跑,验证一下,一定要去自己学习验证一下。

套娃结束!!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值