0

我的英语很差,所以如果有任何错误,请原谅我。谢谢 !

当我使用 qsort 对这个结构进行排序时,我遇到了这个问题:

    typedef struct 
{
    double cost,earn;
}ac;

我想这样排序:

int cmp(const void *a,const void *b)
{
    ac this_a=*(ac*)a;
    ac this_b=*(ac*)b;
    return (this_b.earn/this_b.cost-this_a.earn/this_a.cost)>0.0;
}

但它没有用。当我改成这个时,它起作用了:

int cmp(const void *a,const void *b)
{
    ac this_a=*(ac*)a;
    ac this_b=*(ac*)b;
    return (this_a.cost*this_b.earn-this_a.earn*this_b.cost);
}

为什么会发生这种情况?这两个功能之间有什么不同吗?或者代码的另一部分可能是错误的?

4

3 回答 3

1

比较函数必须返回一个小于零、等于零或大于零的整数,具体取决于您希望这两个项目如何排序。

在您的第一个示例中,您返回 > 操作的结果。这是 0 或 1。

于 2013-10-08T04:14:01.083 回答
1

正如您很容易看到的那样,这两个功能之间存在差异。第一个包含> 0.0return语句中的表达式的末尾。(此外,第一个使用除法,而第二个使用乘法。但是,如果值是非负的,则应用于公式的转换实际上执行等效比较,而不会遭受被零除的危险。)

请注意,这两种实现都不好。正如您已经注意到的,第一个甚至没有远程执行三态比较函数qsort应该执行的操作。只要double值相对较小,第二个就可以正常工作。但是随着这些值变大,从doubleto的转换int可能会开始溢出,从而导致未定义的行为。

因此,永远不要使用直接减法来生成三态比较结果(可能除了小于 的类型int)。如果您需要比较两个值,例如ab,请使用return (a > b) - (a < b)成语。这就是你的情况

double lhs = this_a.cost * this_b.earn;
double rhs = this_a.earn * this_b.cost;
return (lhs > rhs) - (lhs < rhs);
于 2013-10-08T04:29:03.357 回答
0

第一个函数只会返回 0 或 1。

第二个函数将返回“负数”、0 或“正数”,这可能是您想要表示的“小于”、“等于”和“大于”

于 2013-10-08T04:14:27.657 回答