导读:本期聚焦于小伙伴创作的《C语言中排序算法怎么编写C语言qsort函数的自定义比较方法》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C语言中排序算法怎么编写C语言qsort函数的自定义比较方法》有用,将其分享出去将是对创作者最好的鼓励。

在C语言的标准库中,qsort函数是实现通用排序的核心工具,它支持对任意类型的数据数组进行排序,而排序的核心逻辑就依赖用户传入的自定义比较方法。理解比较方法的编写规则,就能应对各种排序需求。

C语言中排序算法怎么编写C语言qsort函数的自定义比较方法

qsort函数的基本参数

qsort函数定义在<stdlib.h>头文件中,其函数原型如下:

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

各个参数的含义如下:

  • base:指向待排序数组首元素的指针
  • nmemb:数组中元素的个数
  • size:数组中每个元素的字节大小
  • compar:指向自定义比较函数的指针,这个函数就是我们需要编写的核心部分

自定义比较方法的编写规则

比较函数需要接收两个const void *类型的参数,这两个参数分别指向待比较的两个数组元素。函数返回值的规定如下:

返回值含义
小于0第一个参数指向的元素应该排在第二个参数指向的元素前面
等于0两个元素相等,排序顺序无要求
大于0第一个参数指向的元素应该排在第二个参数指向的元素后面

编写比较函数的核心步骤是:先将void *类型的参数转换为对应数据类型的指针,再解引用获取元素值进行比较,最后返回比较结果。

不同场景的自定义比较方法示例

场景1:整数数组升序排序

对int类型数组进行升序排序时,比较函数实现如下:

#include <stdio.h>
#include <stdlib.h>

// 整数升序比较函数
int int_compare_asc(const void *a, const void *b) {
    // 将void*转换为int*,再解引用获取值
    int num1 = *(const int *)a;
    int num2 = *(const int *)b;
    // 升序:前小后大返回负数,相等返回0,前大后小返回正数
    if (num1 < num2) {
        return -1;
    } else if (num1 == num2) {
        return 0;
    } else {
        return 1;
    }
}

// 简化写法,直接返回两数差值
int int_compare_asc_simple(const void *a, const void *b) {
    return *(const int *)a - *(const int *)b;
}

int main() {
    int arr[] = {5, 2, 8, 1, 9};
    int n = sizeof(arr) / sizeof(arr[0]);
    // 调用qsort排序
    qsort(arr, n, sizeof(int), int_compare_asc_simple);
    // 打印排序结果
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("n");
    return 0;
}

场景2:整数数组降序排序

降序排序只需要调整比较结果的逻辑,把两个元素的顺序调换即可:

#include <stdio.h>
#include <stdlib.h>

// 整数降序比较函数
int int_compare_desc(const void *a, const void *b) {
    // 降序:前大后小返回负数,相等返回0,前小后大返回正数
    return *(const int *)b - *(const int *)a;
}

int main() {
    int arr[] = {5, 2, 8, 1, 9};
    int n = sizeof(arr) / sizeof(arr[0]);
    qsort(arr, n, sizeof(int), int_compare_desc);
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("n");
    return 0;
}

场景3:结构体数组按指定字段排序

假设我们有一个学生结构体,需要按学生的成绩升序排序,比较函数需要处理结构体指针:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义学生结构体
typedef struct {
    char name[20];
    int score;
} Student;

// 按成绩升序比较结构体
int student_compare_by_score(const void *a, const void *b) {
    // 转换为Student*类型指针
    const Student *s1 = (const Student *)a;
    const Student *s2 = (const Student *)b;
    // 按score字段比较
    return s1->score - s2->score;
}

int main() {
    Student students[] = {
        {"张三", 85},
        {"李四", 92},
        {"王五", 78}
    };
    int n = sizeof(students) / sizeof(students[0]);
    qsort(students, n, sizeof(Student), student_compare_by_score);
    for (int i = 0; i < n; i++) {
        printf("姓名:%s,成绩:%dn", students[i].name, students[i].score);
    }
    return 0;
}

场景4:字符串数组排序

排序字符串数组时,需要比较字符串内容,可以使用标准库的strcmp函数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 字符串升序比较函数
int str_compare_asc(const void *a, const void *b) {
    // 注意:数组元素是char*类型,所以a和b指向的是char*,需要转换为char**再解引用
    const char *str1 = *(const char **)a;
    const char *str2 = *(const char **)b;
    return strcmp(str1, str2);
}

int main() {
    char *arr[] = {"apple", "banana", "cherry", "date"};
    int n = sizeof(arr) / sizeof(arr[0]);
    qsort(arr, n, sizeof(char *), str_compare_asc);
    for (int i = 0; i < n; i++) {
        printf("%s ", arr[i]);
    }
    printf("n");
    return 0;
}

注意事项

  • 比较函数的两个参数必须是const void *类型,不能随意修改参数指向的内容
  • 转换指针类型时要匹配数组实际的元素类型,否则会出现数据读取错误
  • 当比较返回值使用两数相减的方式时,要注意数据溢出问题,比如对很大的整数做减法可能超出int范围,此时建议使用分支判断的写法
  • 如果排序需求是降序,只需要把两个比较参数的位置互换即可,不需要修改其他逻辑

C语言qsort函数排序算法自定义比较方法修改时间:2026-06-30 18:06:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。