以下是我的代码,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;
}
这个程序的输出是:
虽然它应该与输入相同。有人可以解释为什么会这样,以及我如何纠正它?
答案 0 :(得分:11)
return ( *(int*)a - *(int*)b );
如果基础“对象”为int
值,则不要比较char
值。
几乎可以肯定的是,比较是使用四个(取决于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, 0x04, 0x0b, 0x16, 0x24, 0x30, 0x6c, 0x48};
int compare (const void *a, const void *b) {
return *(signed char*)a - *(signed char*)b;
}
int main (void) {
int i;
qsort (values, 8, 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
(我交换了代码中最后两个元素的顺序,以表明它实际上正在对某些内容进行排序)。
答案 1 :(得分:4)
将比较功能更改为
int compare (const void * a, const void * b)
{
return ( *(char*)a - *(char*)b );
}