2013-04-11 53 views
6

問題以下是我的代碼和的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分配

雖然它應該和輸入一樣。有人可以解釋爲什麼它是如此以及我如何糾正它?

+3

我不能相信這一點。 **完全獨立,可編輯的例子**!先生,您值得獲得*獎章*! +1,還有更多,如果我可以。 – DevSolar 2013-04-11 06:13:26

+1

好點,@DevSolar,我們應該回報這樣的問題。 – paxdiablo 2013-04-11 06:19:42

回答

10
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, 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 

(I交換在最後兩個元素的順序代碼以顯示它實際上正在排序的東西)。

+0

「這將大大地填滿整個過程。」 - 是的......在排序過程中排序的值實際上會改變! – 2013-04-11 06:12:52

+0

謝謝!它直接工作。 – Daylite 2013-04-11 06:23:26

+0

如果OP對無符號字符進行排序,會返回*(無符號字符*)a - *(無符號字符*)b'是否錯誤,因爲減法永遠不會產生負面結果? – 2013-04-11 07:18:36

4

更改比較功能

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