2012-05-04 6 views
4

私はソート(構造体へのポインタの配列)が私が比較しているもの(文字列)ではないので、qsortでできるかどうかはわかりません。ここでqsort()を使用して文字列を含む構造体へのポインタを並べ替える

は私のプログラムの要約版は、(我々はqsort関数(呼び出す前に、すべての生徒データがコアであると仮定)とnソートするレコードの数である)である:

struct student { 
     char lname[NAMESIZE + 1]; 
     char fname[NAMESIZE + 1]; 
     short mid; 
     short final; 
     short hmwks; 
}; 

int cmp(const void *, const void *); 

int 
main(int argc, char **argv) 
{ 
     int n; 
     struct student *data[MAX]; 

     qsort(data, n, sizeof(struct student *), cmp); 

     return 0; 
} 

int 
cmp(const void *p0, const void *p1) 
{ 
     return strcmp((*(struct student *) p0).lname, 
         (*(struct student *) p1).lname); 
} 

答えて

3

それは何かをする必要がありますこのように:

cmp()に渡されます何
int 
cmp(const void *p0, const void *p1) 
{ 
     // pn is a pointer to an element of the array, 
     // so, it's effectively a pointer to a pointer to a struct. 
     // Therefore, we need to cast it appropriately to struct student **. 
     // To get a pointer to a struct from it, we dereference it once, 
     // hence the "*". Then we need to extract a pointer to the beginning 
     // of a string, hence the "->". 
     return strcmp((*(struct student **) p0)->lname, 
         (*(struct student **) p1)->lname); 
} 
+0

ありがとうございました。 – Derek

4

は(void*を装って)struct student**パラメータです。だから、そのようcmp()を変更:

int 
cmp(const void *p0, const void *p1) 
{ 
     struct student* ps0 = *(struct student**) p0; 
     struct student* ps1 = *(struct student**) p1; 

     return strcmp(ps0->lname, ps1->lname); 
} 
0

他の回答には、一つの小さなディテールが、すべてに正しいです。私はちょうどこれを打ったので、他の誰かが非常にペタニックなコンパイラで苦労している場合に備えて、ここに残しておきます。

qsort()コンパレータは2つのconst void *パラメータを受け入れます。これは、実際の構造体へのポインタを取得するために参照を外すときには、const -nessを保持する必要があることを意味します。あなたがC言語の一つ一つのルールに従っていたのであれば、あなたのコードは次のようになります。

int 
cmp(const void *p0, const void *p1) 
{ 
    const struct student* ps0 = *(const struct student* const*) p0; 
    const struct student* ps1 = *(const struct student* const*) p1; 

    return strcmp(ps0->lname, ps1->lname); 
} 

注構築「のconstへのconstポインタ」 - それはあなたがそのノーポイントであなたの元のポインタをコンパイラに伝えるです(p0p1)は、const -nessを失います。まず、それらをconst * const *に参照解除してから、const *に参照してください。 const **を単に使用すると、元のconstの - 度がconst void *であることを破棄するconst *から*(非const)のポインタです。

関連する問題