回调函数的理解及qsort函数各种类型的排序

什么是回调函数?

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

接下来让我们运用qsort函数来加深对回调函数的理解;

 

qsort是编译器函数库自带的快速排序函数。

使用qsort()排序并用 bsearch()搜索是一个比较常用的组合,使用方便快捷。

qsort 的函数原型是

void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));

各参数:1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针 其中base是排序的一个集合数组,num是这个数组元素的个数,width是一个元素的大小,comp是一个比较函数。比如:对一个长为1000的数组进行排序时,int a[1000]; 那么base应为a,num应为 1000,width应为 sizeof(int),comp函数随自己的命名qsort(a,1000,sizeof(int),comp);

 

int comp(const void*a,const void*b)

{

return *(int*)a-*(int*)b;

}

Comp 函数编写作用是由小到大排序,这里只是需要comp函数返回正值、负值或者零即可。

前面介绍了qsrot函数,我们知道了我们知道qsort是通过回调函数来实现其功能,故而我们通过回调函数可以排序各种类型的数据;

代码实现:

#include    
#include
int cmp1(const void *a,const void *b)
{
	return *(int*)a - *(int*)b;//a>b返回正值
}
int cmp2(const void *a,const void *b)
{
	return *(char*)a - *(char*)b;
}
int cmp3(const void *a, const void *b)
{
	return strcmp(*(char **)a,*(char **)b);
}
int cmp4(const void *a, const void *b)
{
	return *(double*)a - *(double*)b;
}
int main()
{
	int a[] = { 0,1,9,3,4,5,6,7,8,2 };//整形
	char b[] = { 'b','a','c','d','e' };//字符
	char *str[] = { "bbbb","aaaa","dddd","cccc" };//字符串
	double arr[] = { 1.0,6.0,2.0,3.3,5.5 };//浮点型
	qsort(a, 10, sizeof(int), cmp1);
	qsort(b, 5, sizeof(char), cmp2);
	qsort(str, 4, sizeof(char*), cmp3);
	qsort(arr, 5, sizeof(double), cmp4);
	int i = 0;
	for (i = 0;i < 10;i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	for (i = 0;i < 5;i++)
	{
		printf("%c ", b[i]);
	}
	printf("\n");
	for (i = 0;i < 4;i++)
	{
		printf("%s ", str[i]);
	}
	printf("\n");
	for (i = 0;i < 5;i++)
	{
		printf("%f ", arr[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}

运行结果如下:

回调函数的理解及qsort函数各种类型的排序_第1张图片

通过以上这些回调函数,我们可以得出写这些回调函数的规律: 
1)返回类型 int ,其实是将两个参数比较完的结果返回; 
2)参数类型 void*,void *可以接受任意类型的实参; 
3)比较两个参数的大小时,需将其转换成相应的类型,例如数组是 int,此时参数需强转成(int *); 

4)注意:在比较字符串大小时,不能将其直接比较,在这里需要使用strcmp函数

模仿qsort的功能实现一个通用的冒泡排序。

代码如下:

#include 
#include
int cmp2(const void *x,const void *y)
{
	return *(int *)x - *(int *)y;
}
int cmp1(const void *a, const void *b)
{
	return strcmp(*(char **)a, *(char **)b);
}
void Swap(void *p1, void *p2, int size)
{
	int i = 0;
	for (i = 0; i < size; i++)
	{
		char tmp = *((char *)p1 + i);
		*((char *)p1 + i) = *((char *)p2 + i);
		*((char *)p2 + i) = tmp;
	}
}
void Bubble(void *base, int count, int size, int(*cmp)(void *, void *))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < count - 1; i++)
	{
		for (j = 0; j < count - 1; j++)
		{
			if (cmp((char *)base + j * size, (char *)base + (j + 1)*size)>0)
			{
				Swap((char *)base + j * size, (char *)base + (j + 1)*size, size);
			}
		}
	}
}
int main()
{
	int i = 0;
	int a[] = { 4,5,6,7,8,9,1,2,0,3 };
	char *s[5] = { "aaaa", "dddd", "iiii", "cccc", "ffff" };
	Bubble(a, sizeof(a) / sizeof(a[0]), sizeof(int), cmp2);
	Bubble(s,sizeof(s)/sizeof(*s), sizeof(char *), cmp1);
	for (i = 0; i 

结果如下:

回调函数的理解及qsort函数各种类型的排序_第2张图片

你可能感兴趣的:(C语言)