目录
一.回调函数
二.qsort函数
三.void*指针
四.用qsort函数进行升序排序
1.整形数组排序
2.结构体数组排序
3.字符数组排序
五.使用冒泡排序模拟实现qsort函数
一.回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个
函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数
的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进
行响应。
二.qsort函数
qsort是一个函数,基于快速排序算法实现的一个排序函数。
这是MSDN上面的介绍:
void qsort(void* base, //待排序数据的起始位置size_t num, //数组的元素个数size_t width, //一个元素的字节大小int(*cmp)(const void* elem1, const void* elem2)//cmp是一个函数指针,指向一个比较函数,需 //要自己编写,elem1,elem2是两个待比较元素的地址
返回值大小 注意:排序整形数据可以用> <,但排序结构体数据可能不方便用> <比较了。
三.void*指针
相当于通用的指针类型,可以存放指向任何类型的指针,当你的函数参数类型不确定时,可以使用 void *,不能解引用和+-整数运算。
四.用qsort函数进行升序排序
1.整形数组排序
int i_cmp (const void* e1, const void* e2) //qsort默认升序排序,想要降序排序只需要调 换e1和e2即可
{return *((int*)e1) - *((int*)e2); //void*指针不能解引用,需要强制类型转换为int*型
}
void print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}
}
int main()
{int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), i_cmp);print(arr, sz);return 0;
}
2.结构体数组排序
struct Stu
{char name[20];int age;double score;
};
int j_cmp_by_age(const void* e1, const void* e2)
{return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//int j_cmp_by_name(const void*e1,const void* e2)
//{
// return strcmp( ((struct Stu*)e1)->name , ((struct Stu*)e2)->name) //字符串比较大小要使 用strcmp函数
//}
int main()
{struct Stu stu[3] = { {"lisi",20,70.2},{"wangwu",23,88.5},{"zhangsan",18,90.2}};int sz = sizeof(stu) / sizeof(stu[0]);qsort(stu, sz, sizeof(stu[0]), j_cmp_by_age); //通过年龄来排序//qsort(stu,sz,sizeof(stu[0]), j_cmp_by_name); //通过姓名来排序printf("%s %d\n", stu[0].name, stu[0].age);printf("%s %d\n", stu[1].name, stu[1].age);printf("%s %d\n", stu[2].name, stu[2].age);return 0;
}
strcmp返回值大小和qsort函数返回值恰好一样,srtcmp函数比较2个字符串大小,一个字符一个字符进行比较,按ASCII值比较大小。
3.字符数组排序
int f_cmp(const void* e1, const void* e2)
{return *((char*)e1) - *((char*)e2);
}
void print(char arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%c ",arr[i]);}
}
int main()
{char arr[] = "dfesagc";int sz = strlen(arr);qsort(arr, sz, sizeof(arr[0]), f_cmp);print(arr, sz);return 0;
}
五.使用冒泡排序模拟实现qsort函数
int cmp(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}
void Swap(char* buff1, char* buff2, int width)
{int i = 0;for (i = 0; i < width; i++){char tmp = *buff1;*buff1 = *buff2;*buff2 = tmp;buff1++;buff2++;}
}
//因为交换的时候是传地址,所以要知道元素的宽度,一个字节一个字节的交换 ,这样也证明了使用char*指 //针的好处!
void bubble_sort(void* base, int num, int width, int (*cmp)(void* e1, void* e2))
{int i = 0;for (i = 0; i < num - 1; i++) //趟数{int j = 0;for (j = 0; j < num - 1 - i; j++){if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) //升序排序//j = 0时,比较的是第一个元素和第二个元素// j = 1时,比较的是第二个元素和第三个元素{Swap((char*)base + j * width, (char*)base + (j + 1) * width, width); //交换}}}
}
void test()
{int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;bubble_sort(arr, sz, sizeof(arr[0]), cmp);for (i = 0; i < sz; i++){printf("%d ", arr[i]);}
}
int main()
{test();return 0;
}