return ( *(int*)a - *(int*)b );
基礎となる「オブジェクト」が値である場合、値を比較するべきではありません。int
char
ほぼ確実に起こっているのはsizeof(int)
、最初のオブジェクトが0x02040b16
(もちろんエンディアンネスに応じて)存在するなど、比較が4(に応じて)バイトを使用して比較を行うことです。これはプロセスを大幅に詰め込みます。
次のように変更します。
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
(実際に何かをソートしていることを示すために、コードの最後の 2 つの要素の順序を入れ替えました)。