2013-07-22 145 views
0

我想排序使用qsort()的結構數組,但令人沮喪的是,它不工作。我已閱讀qsort()的手冊頁,我認爲我有比較函數,它在語法上看起來不錯,但是當我在打印qsort()之後打印「sorted」數組時,我的數組中沒有排序。排序結構指針數組

代碼:

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

#define ARRAY_SZ 5 

typedef struct SingleChar 
{ 
    unsigned char Character; 
    unsigned int Weight; 
} *SingleCharPtr; 

int CompareWeights(const void *a, const void *b) 
{ 
    const SingleCharPtr p1 = (SingleCharPtr)a; 
    const SingleCharPtr p2 = (SingleCharPtr)b; 

    // printf("Weight1: %u\tWeight2: %u\n", p1->Weight, p2->Weight); 
    // return (p1->Weight - p2->Weight); 

    if (p1->Weight < p2->Weight) 
     return -1; 
    else if (p1->Weight > p2->Weight) 
     return 1; 
    else 
     return 0; 
} 


SingleCharPtr MakeChar(unsigned char c, unsigned int w) 
{ 
    SingleCharPtr scptr = malloc(sizeof(struct SingleChar)); 

    if (!scptr) 
    { 
     fprintf(stderr, "[Error] Out of memory\n"); 
     exit(1); 
    } 

    scptr->Character = c; 
    scptr->Weight = w; 

    return scptr; 
} 

int main(void) 
{ 
    SingleCharPtr *chars = malloc(ARRAY_SZ * sizeof(SingleCharPtr)); 

    chars[0] = MakeChar('B', 3); 
    chars[1] = MakeChar('E', 7); 
    chars[2] = MakeChar('A', 4); 
    chars[3] = MakeChar('D', 6); 
    chars[4] = MakeChar('C', 2); 

    qsort(chars, ARRAY_SZ, sizeof(SingleCharPtr), &CompareWeights); 

    int i; 
    for (i = 0; i < ARRAY_SZ; i++) 
    { 
     printf("Character: %c\tWeight: %u\n", chars[i]->Character, chars[i]->Weight); 
     free(chars[i]); 
    } 

    free(chars); 

    return 0; 
} 

此外,在比較器功能(CompareWeights()),我發現,當我打印由SingleCharPtr指向的結構的重量,我得到0爲他們所有。

任何指向正確的方向將非常感激。

+0

請不要張貼鏈接或代碼的截圖。將其粘貼到此處並進行格式化。 – 2013-07-22 08:22:43

+0

@ H2CO3,注意。謝謝! – hyde

回答

1

問題:qsort()遍在指針的元素進行比較的比較器的功能,而不是元素本身。所以,CompareWeights()函數的參數實際上是const SingleCharPtr *,僞裝成const void *。你應該在功能做的是:

const SingleCharPtr p1 = *(const SingleCharPtr *)a; 


圖片的標題說明:

一,如果你的假設一直有效的,那麼你就不會需要投:

const SingleCharPtr p1 = a; 

優於

const SingleCharPtr p1 = (SingleCharPtr)a; 

因爲this

二,比較功能不需要返回-101。它應該返回一個整數小於0,0或大於0。因此,所有CompareWeight()巨大if完全是多餘的,寫

return p1->Weight - p2->Weight; 

代替。

三, SingleCharPtr *chars = malloc(ARRAY_SZ * sizeof(SingleCharPtr)); - 爲什麼?你只能在main()函數中本地使用chars陣列,你不需要動態分配。爲什麼不寫

SingleCharPtr chars[ARRAY_SZ]; 

取而代之?

+0

三,這是一個測試程序來運行我正在創建的更大的程序。這就是爲什麼我想在本地測試'* chars'指針的原因。感謝您的回答和反饋。 – hyde

+0

@NullGeo不客氣。 – 2013-07-22 08:31:21

1

如果您看到例如this manual page,你會看到當qsort傳遞了一個指針數組(就像你有),那麼排序函數的參數實際上是指向指針的指針。這是因爲qsort傳遞指向元素的指針,而不是元素本身。

,以適應該相應地改變:

int CompareWeights(const void *a, const void *b) 
{ 
    const SingleCharPtr p1 = *(SingleCharPtr*)a; 
    const SingleCharPtr p2 = *(SingleCharPtr*)b; 

    return (p1->Weight - p2->Weight); 
}