C qsort无法正常工作

Ram*_*Ram 12 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;
}
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

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
Run Code Online (Sandbox Code Playgroud)

我的意思是,问题/必须/在我的比较功能中.有人注意到什么奇怪的吗?

Meh*_*dad 39

是的,你的"比较"溢出了.:(

原因:

当您从正数中减去负数时,结果不一定是正数; 如果它不能在数据类型中表示,它将"包围"另一方.

例:

如果你的整数只能保持-8到7(4位),那么当你比较4到-4时会发生什么?
好吧,你得到8,它是1000二进制的,即-8.所以4小于-4.

道德:

不要做减法而不是比较,即使他们在学校告诉你"这看起来有多酷"!


AnT*_*AnT 16

一般情况下,您不能使用减法来比较整数.或者,更确切地说,您可以,但仅在您确定减法不会溢出的情况下.在你的情况下,减法溢出,产生完全没有意义的结果(甚至没有提到当有符号整数减法溢出时,行为是未定义的).

用于产生值之间的三态C样式比较常见的成语ab(a > b) - (a < b)表达.它适用于几乎任何类似类型的数据.在您的情况下,比较函数可能如下所示

int compare(const void* a, const void* b)
{
  int va = *(const int*) a;
  int vb = *(const int*) b;
  return (va > vb) - (va < vb);
}
Run Code Online (Sandbox Code Playgroud)

  • 谁在谁之间?我更喜欢直截了当的`va <vb?-1:va> vb?1:0`,如果你有多个排序字段,它易于理解,易于反转,并且易于扩展.并且Mehrdad的评论是准确的 - 有许多语言中布尔值没有被隐式转换为整数(当然,这**是一个C问题,但是,他*做*咧嘴笑). (7认同)
  • @Jim Balter:我发现`(va> vb) - (va <vb)`明显更直接.它起初看起来有点新颖,但它的对称性很快使它比具有非明显分组的"?:"运算符的两级卷积更具可读性. (5认同)
  • 但是,不要用另一种语言用布尔语来试试这个.;) (2认同)