我的英语很差,所以如果有任何错误,请原谅我。谢谢!
当我使用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);
}
为什么会发生这种情况?两种功能有什么不同吗?或者代码的其他部分可能是错误的?
答案 0 :(得分:1)
compare函数必须返回一个小于零的整数,等于零或大于零,具体取决于您希望这两个项目的排序方式。
在第一个示例中,您返回>的结果操作。这是0或1。
答案 1 :(得分:1)
您可以很容易地看到自己,这两个功能之间存在差异。第一个在> 0.0
语句的表达式的末尾包含return
。 (另外,第一个使用除法,而第二个使用乘法。但是,如果值是非负的,则应用于公式的转换实际上执行等效比较而不会遭受除零的危险。)
请注意,两种实现都不是很好。正如您已经注意到的那样,第一个甚至不会远程执行qsort
的三态比较功能。只要double
值相对较小,第二个就可以正常工作。但随着这些值变大,从double
到int
的转换可能会开始溢出,从而导致未定义的行为。
因此,不要使用直接减法来生成三态比较结果(除了,可能是小于int
的类型)。如果您需要比较两个值,例如a
和b
,请使用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);
答案 2 :(得分:0)
第一个函数只会返回0或1。
第二个函数将返回“负数”,0或“正数”,这可能是您要表示的“小于”,“相等”和“大于”