return (*(int*)a - *(int*)b);
Bạn nên không được so sánh int
giá trị nếu tiềm ẩn "đối tượng" là char
giá trị. Điều này gần như chắc chắn xảy ra là so sánh đang sử dụng bốn byte (tùy thuộc vào sizeof(int)
) để so sánh, chẳng hạn như đối tượng đầu tiên là 0x02040b16
(tùy thuộc vào kết thúc của bạn). Điều này sẽ rất nhiều thứ lên quá trình.
Thay đổi nó để:
return (*(char*)a - *(char*)b);
và thử lại.
Và chỉ cần lưu ý rằng chữ ký số char
là sự cố triển khai. Bạn có thể thấy rằng 0x80
kết thúc lên dưới 0x7f
. Nếu đó không phải là những gì bạn muốn, hãy sử dụng unsigned char
một cách rõ ràng để trích xuất các giá trị, sau đó nâng cấp chúng lên các số nguyên đã ký (với một dàn diễn viên khác) trước khi thực hiện phép trừ.
Thực tế, đối với tính di động, bạn có thể muốn sử dụng signed char
một cách rõ ràng cho trường hợp khác.
Chương trình sau đây cho thấy cách thức hoạt động với đúng kiểu dữ liệu cơ bản:
#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;
}
Các ouput của việc này là:
2 4 b 16 24 30 48 6c
(tôi hoán đổi thứ tự của hai yếu tố cuối cùng trong mã để hiển thị nó đã thực sự sắp xếp thứ gì đó).
Tôi không thể tin rằng đây. Một ** hoàn toàn khép kín, ví dụ compilable **! Bạn, thưa bạn, xứng đáng với một * huy chương * cho điều này! 1, và nhiều hơn nữa nếu tôi có thể. – DevSolar
Điểm tốt, @DevSolar, chúng tôi _should_ tặng các câu hỏi như thế này. – paxdiablo