对qsort的一些理解
首次发布,大佬轻点喷。
首先是冒泡排序
这个初学者一般都会很了解所以就
冒泡排序如下
void mppx(int arr[],int n) {//这个函数没有返回类型
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}//这样就形成了一个冒泡排序。
所以猜测qsort也类似与这个排序
这就是qsort的函数就是
#include<stdlib.h>
void qsort(void*basic , int sum, int width ,int(*compare)(void*e1 ,void*e2))
我们就可以看到qsort的函数参数类型为
数组首元素地址,元素数量,各个元素的大小,函数指针
先体验一下qsort的强大功能
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu {
char name[20];
int age;
};
int cmp_by_name(const void* p1, const void* p2) {
int pan = strcmp(((struct stu*)p1)->name, ((struct stu*)p2)->name);
return pan;
}
void exam3() {
struct stu s[3] = { {"yangyx",20},{"chengjs,18"},{"gaoyr",250} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_by_name);//其实函数名就是函数地址。
}
int main() {
exam3();
return 0;
}
以下是关于qsort内部实现的猜测 亲测有效
void swap(char* p1, char* p2 , int width) {//字节交换方式,这种一个字节一个字节交换的方法很好使
int i = 0;
for (i = 0; i < width; i++) {
char tmp=*p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2++;
}
}
void qsort(void*base, int sum, int width, int(*compare)(void* e1, void* e2)) {
for (int i = 0; i < sum - 1; i++) {
for (int j = 0; j < sum - 1 - i; j++) {
if (compare((char*)base + j * width, (char*)base + (j + 1) * width) ){
swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
//交换
}
}
}
}
这里再演示一下比较函数的设计,强制转换运算符在这里用地比较多。
int cmpare_int(void* e1, void* e2) {
if (*(int*)e1 > *(int*)e2) {
return 1;
}
if (*(int*)e1 == *(int*)e2) {
return 0;
}
if (*(int*)e1 < *(int*)e2) {
return -1;
}
}
//比较函数的设计
//这里是以整形为例强制转换运算符在这里用的比较多主要是方便指针加减的跨度