c – Qsort及其问题

以下是我的代码,Qsort产生奇怪的结果:
#include <stdio.h>
#include <stdlib.h>

char values[] = { 0x02,0x04,0x0b,0x16,0x24,0x30,0x48,0x6c};

int compare (const void * a,const void * b)
{
    return ( *(int*)a - *(int*)b );
}

int main ()
{

    int i;

    qsort (values,8,sizeof(char),compare);

    for (i = 0; i < 8; i++)
    {
       printf ("%0x ",values[ i ]);
    }
    return 0;
}

这个程序的输出是:

2 6c 48 30 24 4 b 16

虽然它应该与输入相同.有人可以解释为什么会这样,以及我如何纠正它?

解决方法

return ( *(int*)a - *(int*)b );

如果基础“对象”是char值,则不应该比较int值.

几乎可以肯定的是,比较是使用四个(取决于sizeof(int))字节来进行比较,例如第一个对象是0x02040b16(当然取决于你的字节序).这将极大地填补这个过程.

将其更改为:

return ( *(char*)a - *(char*)b );

然后再试一次.

请注意,char的签名是一个实现问题.您可能会发现0x80最终小于0x7f.如果那不是您想要的,请明确使用unsigned char提取值,然后在进行减法之前将它们升级为有符号整数(使用另一个转换).

实际上,为了便于移植,您可能还希望明确地将signed char用于其他情况.

以下程序显示了它如何使用正确的基础数据类型:

#include <stdio.h>
#include <stdlib.h>

signed char values[] = {0x02,0x6c,0x48};

int compare (const void *a,const void *b) {
    return *(signed char*)a - *(signed char*)b;
}

int main (void) {
    int i;

    qsort (values,sizeof (char),compare); // char okay here.
    for (i = 0; i < 8; i++)
       printf ("%0x ",values[i]);
    putchar ('\n');

    return 0;
}

这个的输出是:

2 4 b 16 24 30 48 6c

(我交换了代码中最后两个元素的顺序,以表明它实际上是在排序某些东西).

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...