2012-01-04 48 views
2

我有以下結構如何排序在C中的結構數組?

typedef struct _my_data_ 
{ 
    unsigned int id; 
    double latitude; 
    double longitude; 
    unsigned int content_len; 
    char* name_dyn; 
    char* descr_dyn; 
} mydata; 

的數組,並想對它進行排序升序由ID。我讀過可以使用qsort函數對數組進行排序,但我不確定如何在排序結構時正確使用它。

任何幫助,將不勝感激。

+5

你寫過一個函數,可以告訴你哪個給定的結構體有更大或更小的'id'字段? – sarnold 2012-01-04 02:09:37

回答

16

你需要通過qsort()預期函數的原型相匹配的結構比較功能,即:

int md_comparator(const void *v1, const void *v2) 
{ 
    const mydata *p1 = (mydata *)v1; 
    const mydata *p2 = (mydata *)v2; 
    if (p1->id < p2->id) 
     return -1; 
    else if (p1->id > p2->id) 
     return +1; 
    else 
     return 0; 
} 

如果你有機會到更復雜的排序標準,這仍然是一個很好的基礎,因爲你可以添加使用相同的骨架二級標準:

int md_comparator(const void *v1, const void *v2) 
{ 
    const mydata *p1 = (mydata *)v1; 
    const mydata *p2 = (mydata *)v2; 
    if (p1->latitude < p2->latitude) 
     return -1; 
    else if (p1->latitude > p2->latitude) 
     return +1; 
    else if (p1->longitude < p2->longitude) 
     return -1; 
    else if (p1->longitude > p2->longitude) 
     return +1; 
    else 
     return 0; 
} 

顯然,這將重複多個標準,你所需要的。 (?strcmp())如果您需要調用一個函數來比較值,調用它一次,但分配返回一個局部變量,並使用兩次:

int md_comparator(const void *v1, const void *v2) 
{ 
    const mydata *p1 = (mydata *)v1; 
    const mydata *p2 = (mydata *)v2; 
    int rc; 
    if (p1->latitude < p2->latitude) 
     return -1; 
    else if (p1->latitude > p2->latitude) 
     return +1; 
    else if (p1->longitude < p2->longitude) 
     return -1; 
    else if (p1->longitude > p2->longitude) 
     return +1; 
    else if ((rc = strcmp(p1->name_dyn, p2->name_dyn)) < 0) 
     return -1; 
    else if (rc > 0) 
     return +1; 
    else 
     return 0; 
} 

此外,當數據成員是無符號整數此模板工程,它在比較有符號整數時避免了溢出問題。需要注意的是捷徑,你有時可能會看到,在分別變化:

int md_comparator(const void *v1, const void *v2) /* BAD */ 
{             /* BAD */ 
    const mydata *p1 = (mydata *)v1;    /* BAD */ 
    const mydata *p2 = (mydata *)v2;    /* BAD */ 
    return(p1->id - p2->id);      /* BAD */ 
}             /* BAD */ 

是壞的,如果id是無符號(兩個無符號整數的差異從不爲負),並受溢出如果整數簽署和大幅度和相反的跡象。

+0

謝謝你的評論和+1的方式! – 2012-01-04 02:21:32

+0

非常感謝您的回答,我現在要嘗試此代碼。 – beta 2012-01-04 02:37:38

+1

'if'id'是無符號'的沉思:因爲返回值是'int','unsigned'值將被轉換爲'int',所以它可能變爲負值。但是,如果'id'是'unsigned long'或'unsigned long long',並且'sizeof(long)> sizeof(int)''那麼你會很容易受到一些非常奇怪的行爲的影響。顯性迴歸±1機制總是有效的觀察依然準確;如果兩個無符號數量的比較不是嚴格精確的,那麼掃描「減法不起作用」。 – 2012-01-04 02:52:02