C qsort 无法正常工作
我不知道我做错了什么,但以下代码无法正确对数组进行排序。
#include <stdio.h>
#include <stdlib.h>
int compare(const void* a, const void* b)
{
return (*(int*)a - *(int*)b);
}
int main()
{
int x[] = { -919238029,
-889150029,
-826670576,
-579609061,
-569653113,
-305140505,
-216823425,
-193439331,
-167683147,
-49487019,
-45223520,
271789961,
275570429,
444855014,
559132135,
612312607,
664554739,
677860351,
1005278191,
1031629361,
1089012280,
1115952521,
1521112993,
1530518916,
1907515865,
1931470931,
-1631034645,
-1593702794,
-1465300620,
-1263094822
};
int i;
qsort(x, 30, sizeof(int), compare);
for(i = 0; i < 30; i ++)
printf("%d\n", x[i]);
return 0;
}
产生以下输出:
1521112993
1530518916
1907515865
1931470931
-1631034645
-1593702794
-1465300620
-1263094822
-919238029
-889150029
-826670576
-579609061
-569653113
-305140505
-216823425
-193439331
-167683147
-49487019
-45223520
271789961
275570429
444855014
559132135
612312607
664554739
677860351
1005278191
1031629361
1089012280
1115952521
我的意思是,问题/必须/出现在我的比较函数中。有人注意到有什么奇怪的吗?
I don't know what I'm doing wrong but the following code does not sort the array properly.
#include <stdio.h>
#include <stdlib.h>
int compare(const void* a, const void* b)
{
return (*(int*)a - *(int*)b);
}
int main()
{
int x[] = { -919238029,
-889150029,
-826670576,
-579609061,
-569653113,
-305140505,
-216823425,
-193439331,
-167683147,
-49487019,
-45223520,
271789961,
275570429,
444855014,
559132135,
612312607,
664554739,
677860351,
1005278191,
1031629361,
1089012280,
1115952521,
1521112993,
1530518916,
1907515865,
1931470931,
-1631034645,
-1593702794,
-1465300620,
-1263094822
};
int i;
qsort(x, 30, sizeof(int), compare);
for(i = 0; i < 30; i ++)
printf("%d\n", x[i]);
return 0;
}
produces the following output:
1521112993
1530518916
1907515865
1931470931
-1631034645
-1593702794
-1465300620
-1263094822
-919238029
-889150029
-826670576
-579609061
-569653113
-305140505
-216823425
-193439331
-167683147
-49487019
-45223520
271789961
275570429
444855014
559132135
612312607
664554739
677860351
1005278191
1031629361
1089012280
1115952521
I mean, the problem /must/ be in my compare function. Anybody notice anything strange?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,你的“比较”溢出了。 :(
原因:
当你用正数减去负数时,你的结果不一定是正数;如果它不能用数据类型表示,它会“环绕”另一边。
示例:
如果你的整数只能保存-8到7(4位),那么当你比较4和-4时会发生什么?
好吧,你得到 8,即二进制的
1000
,也就是 -8。所以 4 小于 -4。寓意:
不要用减法代替比较,即使他们在学校告诉你“看看这有多酷”!
Yeah, your "comparison" overflows. :(
Reason:
When you subtract a negative number from a positive number, your result is not necessarily positive; if it can't be represented in the data type, it'll "wrap around" the other side.
Example:
If your integer can only hold from -8 to 7 (4 bits), then what happens when you compare 4 to -4?
Well, you get 8, which is
1000
in binary, which is -8. So 4 is less than -4.Moral:
Don't do subtraction instead of comparison, even if they tell you "look how cool this is" at school!
一般情况下,不能使用减法来比较整数。或者,更准确地说,您可以,但前提是您确定减法不会溢出。在您的情况下,减法溢出,产生完全无意义的结果(甚至没有提到当有符号整数减法溢出时,行为是未定义的)。
在值
a
和b
之间生成三态 C 风格比较的常见习惯用法是(a > b) - (a < b)< /代码> 表达式。它几乎适用于任何类似类型的数据。在您的情况下,比较函数可能如下所示
In general case you can't use subtraction to compare integers. Or, more precisely, you can, but only in situations when you are sure that the subtraction will not overflow. In your case subtraction overflows, producing totally meaningless results (not even mentioning that when signed integer subtraction overflows the behavior is undefined).
The common idiom for generating tri-state C-style comparisons between values
a
andb
is the(a > b) - (a < b)
expression. It works for data of virtually any comparable types. In your case the comparison function might look as follows为了添加 Mehrad 的正确答案,这里有一种使用 SortChecker 查找代码中错误的自动方法:
此警告表示
compare
报告x
y,y< z
而不是x
z
对于某些输入。要进一步调试此问题,请运行并检查生成的代码转储。
To add to Mehrad's correct answer, here's an automated way to find bug in your code using SortChecker:
This warning says that
compare
reportsx < y, y < z
and notx < z
for some inputs. To further debug this issue, run withand examine generated codedump.
我使用上面的信息给出了一个代码示例。在我的编译器和系统中,我得到了与提出问题的 Ram 相同的结果。这表明我的整数类似于 Ram 的整数。我按照 Mehrdad 建议的方式修改了代码,使用比较运算符而不是减法。然后我对数字进行了正确排序。
这是代码:
我得到这个输出:
I'm giving a code example using the information above. In my compiler and system, I get the same results as Ram who asked the question. This indicates that my integers are something like Ram's integers. I modified my code along the lines suggested by Mehrdad to use comparison operators instead of a subtraction. Then I got the numbers sorted properly.
Here is the code:
And I get this output: