使用 qsort 进行错误排序 - C

Posted

技术标签:

【中文标题】使用 qsort 进行错误排序 - C【英文标题】:Getting wrong sort with qsort - C 【发布时间】:2021-12-31 04:50:37 【问题描述】:

我正在尝试使用 qsort 函数对指向结构的指针数组进行排序,代码如下:

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


struct hotel 
    char *address;
    _Bool full;
    int nrooms;
;


/* compare based on the value of nrooms */
int roomcomp(const void *p1, const void *p2)

    return (
        ((struct hotel *)p1)->nrooms - 
        ((struct hotel *)p2)->nrooms
    );



/* compare based on the alphabetic value of address */
int addcomp(const void *p1, const void *p2)

    return strcmp(
        ((struct hotel *)p1)->address,
        ((struct hotel *)p2)->address
    );



int main()

    struct hotel *p1 = malloc(sizeof(struct hotel));
    struct hotel *p2 = malloc(sizeof(struct hotel));
    struct hotel *p3 = malloc(sizeof(struct hotel));
    struct hotel *p4 = malloc(sizeof(struct hotel));
    
    p1->address = strdup("aaaa");
    p1->nrooms = 100;

    p2->address = strdup("bbbb");
    p2->nrooms = 200;

    p3->address = strdup("cccc");
    p3->nrooms = 300;

    p4->address = strdup("dddd");
    p4->nrooms = 400;

    struct hotel *arr[] = p1, p2, p3, p4;
    size_t size = sizeof(arr) / sizeof(*arr);

    for (int i = 0; i < size; i++) 
        printf("address: %s - nrooms: %d\n", arr[i]->address, arr[i]->nrooms);
    

    putchar('\n');
    qsort(arr, size, sizeof(struct hotel *), roomcomp);

    for (int i = 0; i < size; i++) 
        printf("address: %s - nrooms: %d\n", arr[i]->address, arr[i]->nrooms);
    

这是我得到的结果:

address: aaaa - nrooms: 100
address: bbbb - nrooms: 200
address: cccc - nrooms: 300
address: dddd - nrooms: 400

address: aaaa - nrooms: 100
address: cccc - nrooms: 300
address: dddd - nrooms: 400
address: bbbb - nrooms: 200

我尝试了很多不同的方法,但我一直得到相同的结果... 当我尝试在roomcomp 中打印 nrooms 的值时,我得到了指针值,所以如果我不得不猜测我会说我投错了方式......

【问题讨论】:

【参考方案1】:
struct hotel *arr[]

是一个指针数组,所以迭代器是指向指针的指针。

int roomcomp(const void *p1, const void *p2) 
    const struct hotel *const *x = p1;
    const struct hotel *const *y = p2;
    return (*x)->nrooms - (*y)->nrooms;

【讨论】:

感谢您的回答,希望您不介意回答其他三个问题: 1. 迭代器是什么意思? 2.你能分享一下如何正确地转换*p1以便能够将函数缩短到一行(不是说这是好的做法,我只是想知道怎么做)? 3. 你能解释一下双 const 关键字是如何工作的吗? what do you mean by iterators? 嗯,嗯,iterator。允许通过数组中的元素的东西。 ould you share how to correctly cast *p1 to be able to shorten the function to a single line 我建议多写几行。只需将类型替换为变量即可。我想(* ((const struct hotel *const *)p1) )-&gt;Could you explain how the double const keyword works?javatpoint.com/const-pointer-in-c【参考方案2】:

作为 KamilCuk 答案的替代方案,您可以避免首先创建一个指针数组:

const size_t n_hotels = 4;
struct hotel *arr = malloc(n_hotels * sizeof(struct hotel));
arr[0].address = /* ... */;
arr[0].nrooms = /* ... */;
/* ... */
qsort(arr, n_hotels, sizeof(struct hotel), roomcomp);

现在传递给比较函数的内容将是struct hotel *,而您的roomcomp 将按原样工作。

【讨论】:

以上是关于使用 qsort 进行错误排序 - C的主要内容,如果未能解决你的问题,请参考以下文章

c语言重要库函数解读 和模拟实现————Qsort

C/C++sort/qsort使用详解

qsort()函数(C)

在 qsort 比较函数上出现错误

怎么样才能做到对多种数据类型排序?C语言快速排序——qsort函数及其模拟实现

使用 stdlib 的 qsort() 对字符串数组进行排序