从C中为qsort的struct数组中检索struct

时间:2014-12-29 13:46:30

标签: c arrays struct

我正在尝试从struct数组中的结构中检索两个值,但我不知道我做错了什么。我需要 qsort

以下是我的代码示例:

typedef struct test {
    int data1;
    int data2;
} *test;

然后我创建一个struct数组并返回一个指向数组的指针:

test* foo(**some args**)
    test* array = malloc(sizeof(proc));
    int currentElement = 0;
    while(...){
        // get some data
        // and make space for struct
        array[currentElement] = malloc(sizeof(struct test));
        // add data to struct
        array[currentElement] -> data1 = ...;
        array[currentElement] -> data2 = ...;
        // resize array for the next wave of structs
        array = realloc(array, (currentElement + 1) * sizeof(struct proces));
        currentElement++;
    }
    return array

当我尝试访问并打印数组中的结构时,它可以工作(numberOfElement是一个全局变量):

void printData(test* a) {
    printf("%s\n", "Data");
    int i;
    for (i = 0; i < numberOfElements; i++) {
        printf("%5d\n",
                a[i]->data1
                );
    }
}

但是如果我尝试为 qsort 编写一个comperator函数,它会给我一个错误(在某个结构或联合的东西中请求成员'data1'):

int comp (test* first, test* second){
    return first->data1 - second->data1;
}

编辑:添加返回结构数组指针的函数foo。 谢谢你dasblinkenlight!

我还有另一个问题:

这有效!

int comp (void *a, void* b){
    test* first = (test*)a;
    test* second = (test*)b;
    return (*first)->data1 - (*second)->data1;
}

当我尝试按如下方式对数组进行排序时:

test* a = foo(...);
qsort(a, numberOfElements, sizeof(test), comp);
printData(a);

它给了我一个错误:

warning: passing argument 4 of ‘qsort’ from incompatible pointer type [enabled by default]
In file included from Naloga2.c:2:0:
/usr/include/stdlib.h:765:13: note: expected ‘__compar_fn_t’ but argument is of type ‘int (*)(void *, void *)’
 extern void qsort (void *__base, size_t __nmemb, size_t __size,

编辑2 :最终解决方案

int comp (const void *a, const void* b){
        test* first = (test*)a;
        test* second = (test*)b;
        return (*first)->data1 - (*second)->data1;
    }

2 个答案:

答案 0 :(得分:3)

问题是你的typedeftest定义为指针类型,而不是普通类型。然后test*成为双指针,即struct test**。当您编写first->data1时,您正在将->运算符应用于指向struct test的指针,该指针不是指向struct的指针。

由于test*是双指针,因此您需要在获取成员之前重写comp以取消引用它,如下所示:

int comp (const void *a, const void* b){
    const test* first = (const test*)a;
    const test* second = (const test*)b;
    return (*first)->data1 - (*second)->data1;
}

你需要在内部传递void*并强制转换为test*,因为qsort需要一个带有一对常量void指针的函数指针;简单地转换函数指针将编译甚至可能工作,但行为将是未定义的。

答案 1 :(得分:1)

typedef struct test *test;

这也可以写成

typedef struct test* test;

所以现在测试已经是一个指针。所以当你写

test *first;

变成

struct test **first;

你应该有类似

的东西
typedef struct test test;

然后

test *first ;

first作为指向您结构的指针。

这可以确保参数comp()期望的是单个指针,并且访问也很好。

first->data1