c - QSort 在 cmp 函数中返回错误(乱序?)的数字

标签 c sorting qsort

我想在程序中使用 QSort 对指向结构体指针的指针中的元素进行排序。第一个元素没问题,但随后就变得困惑了。该函数似乎读取了一些元素,但顺序/位置错误。

这是我的代码

...

typedef struct Date {
    int day;
    int month;
    int year;
} Date;

...

// Sorts the date date_num - the number of entered dates, dates - pointer to pointers to structs of dates
void sort_dates(int* date_num, Date** dates){

    // Normalize the year
    int d; // The date
    for(d=0;d<*date_num;d++){
        if(dates[d]->year >= 90 && dates[d]->year <= 99){
            dates[d]->year = (dates[d]->year)+1900;
        } else{
            dates[d]->year = (dates[d]->year)+2000;
        }
    }

    qsort(dates[0], *date_num, sizeof(Date), compare);

}

int compare(const void* a, const void* b){

    Date* date1 = (Date*)a;
    Date* date2 = (Date*)b;

    // Concatenate year, month and day
    long num1 = date1->year;
    long num2 = date2->year;

    // Concatenate month
    num1 = num1*100+(date1->month);
    num2 = num2*100+(date2->month);

    // Concatenate day
    num1 = num1*100+(date1->day);
    num2 = num2*100+(date2->day);

    printf("num1 = %d %d %d, num2 = %d %d %d\n", date1->year, date1->month, date1->day, date2->year, date2->month, date2->day);

    //return (num2 - num1);
    return 0; // Sorting Temporarily disabled

}

输入后:

January 1 01
January 1 00
February 28 99
July 17 12
September 10 12
July 1 00
June 30 90
August 25 06
May 27 08
October 1 03

程序将月份名称转换为数字并将日期存储在 Date** 日期 中。执行此操作后,我期望格式如下 num1=年月日,num2=年月日:

num1 = 2001 1 1, num2 = 2012 9 10
num1 = 2012 9 10, num2 = 2000 7 1
...

但它实际上返回类似的东西:

num1 = 2001 1 1, num2 = 0 0 0
num1 = 0 2000 1, num2 = 33 0 0
num1 = 1 0 33, num2 = 0 2000 1
num1 = 2001 1 1, num2 = 1 0 33
num1 = 0 0 0, num2 = 1 0 33
num1 = 2 28 0, num2 = 0 0 1999
num1 = 2012 7 17, num2 = 0 0 0
num1 = 0 33 0, num2 = 2012 7 17
num1 = 2 28 0, num2 = 0 33 0
num1 = 0 0 1999, num2 = 0 33 0
num1 = 2001 1 1, num2 = 2 28 0
num1 = 0 0 0, num2 = 2 28 0
num1 = 1 0 33, num2 = 2 28 0
num1 = 0 2000 1, num2 = 2 28 0
num1 = 33 0 0, num2 = 2 28 0

我怀疑要排序的每个 block 的大小可能存在问题。年在某些元素中的位置错误(与第一个不同),但从逻辑上讲它似乎是正确的。

最佳答案

这个:

qsort(dates[0], *date_num, sizeof(Date), compare);

是错误的,如果你想对日期进行排序,那么将日期传递给qsort(),而不是它的第一个元素。此外,您想要排序的大小是指针的大小,即 sizeof (Date *),或者更好的 sizeof *dates

此外,您的比较函数未能考虑到它将传递指向 dates 元素的指针,即指向 Date 的指针。这意味着它应该开始:

static int compare(const void* a, const void* b){
    const Date * const date1 = *(const Date**) a;
    const Date * const date2 = *(const Date**) b;

同样,需要进行此更改,因为 qsort() 的比较函数传递了两个指向正在排序的数组中的元素的指针。这是一个合理的传递方式,它不能传递元素本身(它不知道它们的类型),但是 const void * 可以指向任何类型的数据。由于数组元素的类型为 Date *(指向 Date 的指针),这意味着发送到 compare() 的实际值是指向指针的指针到日期(即日期**)。

最后,将 const 放入其中是没有意义的,所以不要这样做。

关于c - QSort 在 cmp 函数中返回错误(乱序?)的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42810022/

相关文章:

c - 为什么需要在 C 中的字符串数组中声明字符串的长度?

c - 如何实现 qsort() 来处理结构数组?

c - 我对这个函数做错了什么,它没有结束

c++ - 这个检测整数加法溢出的函数真的有用吗?

c++ - C 项目 O 文件在 make 期间删除后仍在寻找 Cpp 文件

javascript - .sort 函数是否会更改原始数组?

javascript - ES6方式 - 按键从嵌套数组中获取唯一值

android - 使用两个不同字段对列表进行排序的最佳方法

callback - luajit qsort回调示例内存泄漏

c - CHAR_BIT=4 是 C 标准授权的可能值吗?