回调函数的使用举例:
//字符排序
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
int char_cmp(const void *p1, const void *p2)
{
return (*(char *)p1 > *(char *)p2);
}
int main()
{
char arr[] = { 'a', 'd', 'c', 'b' };
qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(char), char_cmp);
int i = 0;
for (; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%c\n", arr[i]);
}
system("pause");
return 0;
}
//整型数字排序
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
int int_cmp(const void *p1, const void *p2)
{
return (*(int *)p1 > *(int *)p2);
}
int main()
{
int arr[] = { 1, 2, 3, 6, 5, 4 };
qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
int i = 0;
for (; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d\n", arr[i]);
}
system("pause");
return 0;
}
通过比较,我们发现每次比较不同的类型,我们只需写一个相应类型的比较大小方法(即写一个回调函数)即可,剩下的都交给库函数帮我们完成,那么现在我们来一起探究一下qsort库函数的实现原理,模拟该函数的实现吧~~~~
看上图,我们就可以知道:整体排序思路是利用冒泡排序的思想来进行,cmp函数每次需要比较的字节数,由我们自己在 (类型)_cmp 函数中定义,而_swap函数里面是定死的:每次交换一个字节,循环次数是数组的每个元素的字节数大小。
下面让我们一起来实现一下整型数字的qsort模拟排序代码
#include <stdio.h>
#include <windows.h>
int int_cmp(const void *p1, const void *p2)
{
return (*(int *)p1 > *(int *)p2);
}
void _swap(void *p1, void *p2, int size)
{
char *p11 = (char *)p1;
char *p22 = (char *)p2;
int i = 0;
for (; i < size; i++)
{
int tmp = *(p11+i);
*(p11 + i) = *(p22 + i);
*(p22 + i) = tmp;
}
}
void my_qsort(void *arr, int count, int size, int(*cmp)(void *, void *))
{
char *p = (char *)arr;//强转为字符指针(意思是每次以一个字节为单位进行操作)
int i = 0;
for (; i < count - 1; i++)
{
int j = 0;
for (; j < count - 1 - i; j++)
{
if (cmp(p + j*size, p + (j+1)*size) > 0)
{
_swap(p + j*size, p + (j + 1)*size, size);
}
}
}
}
int main()
{
int arr[] = { 1, 2, 3, 6, 5, 4 };
my_qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
int i = 0;
for (; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
printf("\n");
system("pause");
return 0;
}
下面让我们一起来实现一下字符的qsort模拟排序代码
#include <stdio.h>
#include <windows.h>
int char_cmp(const void *p1, const void *p2)
{
return (*(char *)p1 > *(char *)p2);
}
void _swap(void *p1, void *p2, int size)
{
char *p11 = (char *)p1;
char *p22 = (char *)p2;
int i = 0;
for (; i < size; i++)
{
int tmp = *(p11 + i);
*(p11 + i) = *(p22 + i);
*(p22 + i) = tmp;
}
}
void my_qsort(void *arr, int count, int size, int(*cmp)(void *, void *))
{
char *p = (char *)arr;//强转为字符指针(意思是每次以一个字节为单位进行操作)
int i = 0;
for (; i < count - 1; i++)
{
int j = 0;
for (; j < count - 1 - i; j++)
{
if (cmp(p + j*size, p + (j + 1)*size) > 0)
{
_swap(p + j*size, p + (j + 1)*size, size);
}
}
}
}
int main()
{
char arr[] = { 'a', 'c', 'b', 'g', 'e', 'f', 'd'};
my_qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(char), char_cmp);
int i = 0;
for (; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%c ", arr[i]);
}
printf("\n");
system("pause");
return 0;
}