【问题标题】:qsort array of structs descending orderqsort 结构降序数组
【发布时间】:2017-02-23 22:16:39
【问题描述】:

我有一个看起来像这样的结构

typedef struct id_score{
   int id;
   int score;
} pair;

一个大小为 50 的数组保存指向这些对的指针

pair* array[50]

我的比较器函数如下所示

int struct_cmp(const void *a, const void* b) {
    pair* ia = (pair*)a;
    pair* ib = (pair*)b;
    printf("ia's score: %d ib's score: %d??? \n", ia->score, ib->score);
    return ib->score - ia->score;
}

我的 qsort 函数在这里

size_t arr_len = sizeof(array) / sizeof(pair);
qsort(array, arr_len, sizeof(pair), struct_cmp);

现在我的问题是,在struct_cmp 函数中,我的printf 显示我认为应该是数组中每个结构中的计数的值都被解释为0,因此没有对数组进行排序全部。当我通过数组打印时,在函数之外,结构具有它应该具有的分数。

有什么建议吗??谢谢!

【问题讨论】:

  • 是不是a在指向元素的指针中?数组元素是pair* 类型所以pair** ia = (pair**)a;?
  • 你正在对一个指针数组进行排序;您的比较器传递了一对指向指针的指针,而不是单级指针。如果您对int 的数组进行排序,您的函数将传递两个int *。由于您正在对pair * 的数组进行排序,因此您的函数将传递两个pair **
  • 注意:当您调用qsort() 时,请考虑qsort(array, arr_len, sizeof *array, struct_cmp); 这比qsort(..., ..., sizeof(pair), ...) 更容易编码、审查和维护

标签: c arrays struct comparator qsort


【解决方案1】:

一个人

size_t arr_len = sizeof(array) / sizeof(pair);

以上是错误的,因为您的数组包含pair 指针,而不是pairs。以更惯用的方式和更少的重复来做到这一点是:

size_t arr_len = sizeof(array) / sizeof(array[0]);

另外需要注意的是,您的比较函数转换为错误的指针类型,因此您的程序的行为是未定义的。

记住回调函数会接收指向数组元素的指针,所以如果数组包含指针,它应该将参数转换为指向指针的指针:

int struct_cmp(const void *a, const void* b) {
    pair* const * ia = (pair* const *)a;
    pair* const * ib = (pair* const *)b;
    printf("ia's score: %d ib's score: %d??? \n", ia->score, ib->score);
    return (*ib)->score - (*ia)->score;
}

与您的原始函数不同,我还努力使其 const 正确。比较回调接受指向 const 的指针,因此转换后的指针也应该指向 const(将 const 应用于元素类型,即pair*)。


正如 chux 所指出的,作为避免减法溢出的一种方法,主要改进是返回以下内容:

return ((*ib)->score > (*ia)->score) - ((*ib)->score < (*ia)->score);

它还具有总是返回 -1、0 或 1 而不是任意数字的好特性。

【讨论】:

  • 为避免减法溢出,可以使用(a&gt;b) - (a&lt; b) idiom。
  • @chux - 已添加。谢谢你让我知道成语的存在:)
  • 我的理解是编译器也会寻找它,因此有合理的机会发出紧凑的代码。然而对我来说,它与return a-b 相比,是一个功能漏洞。关于const 正确的一点。 LSNED
  • 我猜我最大的错误来自return ib-&gt;score - ia-&gt;score; } ??
  • @namesake22 IMO 最大的问题是那些不太可能立即破坏您的程序的问题。比如数组大小问题。错误的指针转换会让你很烦恼,直到你解决它。
猜你喜欢
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多