qsort一个动态数组

时间:2015-07-08 22:58:02

标签: c vector qsort

我正在使用我在网上找到的动态数组,其头文件如下所示:

    typedef struct {
    int size;      // slots used so far
    int capacity;  // total available slots
    void **data;     // array of data we're storing
    } Vector;

    void vector_init(Vector *vector);

    void vector_append(Vector *vector, void* value);

    void* vector_get(Vector *vector, int index);

    void vector_set(Vector *vector, int index, void* value);

    void vector_double_capacity_if_full(Vector *vector);

    void vector_free(Vector *vector);

我有另一个看起来像这样的结构:

typedef struct _item{
    char name[MaxNameSize];
    float price;
} Item;

我使用

创建了一个矢量
Vector vector;
vector_init(&vector);

并使用

添加了许多项目
vector_append(&vector, item);

项目属于Item的多次。我现在想按物品价格对动态数组进行排序。我试过这个没有用的

qsort(vector.data, vector.size, sizeof(Item*), compare);

我的比较功能是

int compare(const void* a, const void* b){
Item* first = (Item*)a;
Item* second = (Item*)b;
    return first.price - second.price;
}

我出错的地方有什么想法吗?我想这可能是我在qsort中提出的论点。现在它似乎只是跳过了qsort。

2 个答案:

答案 0 :(得分:3)

您对Vector的声明包括数据床(void**)指向空的指针。在没有看到其余代码的情况下,我必须假设这意味着您正在管理一个指针向量,其中每个指针引用一个不同的对象by-address。您在compare中收到的地址是data指针数组中的偏移地址。即实际类型void**传递为void*

因此,您缺少一个间接级别。您的语法错误(例如:first->price,而不是first.price)无效,但即使这是正确的,您目前拥有的前提是Item*传递为void*是错误的。

你的比较器应该是这样的,假设你的其余代码是正确的:

int compare(const void* a, const void *b)
{
    const Item * first = *(const void * const *)a;
    const Item * second = *(const void * const *)b;
    return first->price < second->price ? -1 : second->price < first->price;
}

同样,这是对你提供的代码做出相当大的假设,并且除非该代码是可靠的并且满足上述假设,否则无法保证这将有效。但如果您正如上所述管理此向量,它应该可以工作。

我也自由地修正了比较本身。减去值似乎适用于整数类型,但是当转换为最终int结果时,轮子会快速下降为浮点,如果引入下溢潜力,则轮子会快速下降。对于一个简单的例子:

#include <stdio.h>

int main()
{
    printf("%d\n", (int)(1.1f - 1.0f)); // wrong
    printf("%d\n", (1.1f < 1.0f ? -1 : 1.0f < 1.1f)); // better
    return 0;
}

<强>输出

0
1

如果转换较大的整数类型值(假设您减去long long且结果而不是INT_MIN,它也可能最终出现在实现定义的土地上)。坚持我展示的形式避免了陷阱

if (a < b) return -1;
return (b < a); // will be 1 or 0, depending on whether b < a or not.

因此,比较器总是返回-1,0或1,并且在执行此操作时符合qsort的要求,并避免浮点到int转换或潜在下溢/溢出的不准确。 / p>

祝你好运。

答案 1 :(得分:1)

编辑:正如WhozCraig指出的那样,数据是一个指针数组。因此:

第一个和第二个是指向指针的指针,因此您必须获得对Item的指针的引用,然后使用->来引用结构的字段。总之,它应该看起来像:

Item* first = *(Item**)a;
Item* second = *(Item**)b;
return first->price - second->price;