C QSORT无法正常工作[英] C qsort not working correctly

本文是小编为大家收集整理的关于C QSORT无法正常工作的处理方法,想解了C QSORT无法正常工作的问题怎么解决?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

我的意思是,问题/必须/在我的比较函数中.任何人都注意到了什么奇怪的?

推荐答案

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

原因:

当您从正数减去负数时,您的结果不一定是积极的;如果无法在数据类型中表示,它将"缠绕"另一侧.

示例:

如果您的整数只能从-8到7(4位),那么将4到-4比较时会发生什么?
嗯,你得到8,它在二进制中是1000,它是-8.所以4小于-4.

道德:

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

其他推荐答案

通常情况下,您无法使用减法来比较整数.或者,更确切地说,您可以,但仅在某些情况下,当您确定减法不会溢出时.在您的案例中减去溢出,产生完全无意义的结果(甚至不提到当签名的整数减法时溢出行为未定义).

用于在值a和b之间产生三态C样式比较的常见成语是(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);
}

其他推荐答案

要添加到Mehrad的正确答案,这是一种自动查找代码中的错误的方法,使用 sortchecker :

$ LD_PRELOAD=$HOME/sortcheck-master/bin/libsortcheck.so ./a.out
a.out[38699]: qsort: comparison function is not transitive (comparison function 0x40057d (/home/iuriig/a.out+0x40057d), called from 0x400693 (/home/iuriig/a.out+0x400693), cmdline is "./a.out")
-919238029
-889150029
...

此警告说compare报告x < y, y < z而不是x < z的一些输入.要进一步调试此问题,请使用

运行
export SORTCHECK_OPTIONS=raise=1

并检查生成的codedump.

本文地址:https://www.itbaoku.cn/post/359173.html