2013-07-22 105 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); 
}