【问题标题】:qsort with typedef structs in Cqsort 与 C 中的 typedef 结构
【发布时间】:2020-02-24 15:15:37
【问题描述】:

在搜索了很多帖子后,我无法解决我的问题。我想根据一个字段(截止日期)订购一组结构:

typedef struct{
    int ident;
    int computation;
    int period;
    int deadline;
}task_t;
task_t *tasks;

int compare(const void *a, const void *b) {

        task_t *ia = *(task_t**)a;
        task_t *ib = *(task_t**)b;
        //task_t *ia = (task_t *)a;
        //task_t *ib = (task_t *)b;

        return (ia->deadline - ib->deadline);
}

//Randomly generation of parameters of tasks

fprintf(stderr,"before:\n");
    for (i=0;i<nT;i++){
            fprintf(stderr,"%d;%d;%d;%d\n", tasks[i].ident, tasks[i].computation, tasks[i].deadline,tasks[i].period);
        }

size_t size = sizeof(tasks) / sizeof(task_t*);

qsort(tasks, size, sizeof(task_t *), compare);


    fprintf(stderr,"\after:\n");
    for (i=0;i<nT;i++){
            fprintf(stderr,"%d;%d;%d;%d\n", tasks[i].ident, tasks[i].computation, tasks[i].deadline,tasks[i].period);
        }

在qsort之前和之后,结果是一样的。我认为问题是指针,但我不知道如何解决它。我尝试了很多组合 qsort(&tasks, size, sizeof(task_t *), &compare); 还有比较功能,但结果没有改变。你可以帮帮我吗?对不起,如果这个问题重复了这么多。

【问题讨论】:

  • 我认为应该是sizeof(task_t)(没有指针)
  • 这是task_t *ia = (task_t*)a;,而不是task_t *ia = *(task_t**)a;
  • 当您的比较只能使用 a 和 b 的类型时,为什么要使用 void* ?您对 qsort 的调用是完全错误的。 tasks 是指向要排序的多个元素的指针,您的比较应该采用 const tast_t* a, const task_t* b,内部忘记转换您的比较 a->deadline - b->deadline;
  • @רועיאבידן:根本不可能是 sizeof,因为 tasks 是一个指针,而不是一个数组。

标签: c struct typedef qsort


【解决方案1】:
size_t size = sizeof(tasks) / sizeof(task_t*);

仅当taskstask_t* 的数组时才有效。不是,它是指向task_t 的指针(可能指向task_t 的数组,但不是具有编译时大小的数组)。在这种情况下你不能使用sizeof,你只需要以其他方式知道数组有多大。照原样,您基本上要求qsort 对包含一个元素的数组进行排序。

你的比较器也写错了;如果数组属于task_ts,那么它接收到的void*s 实际上是指向task_t 的指针,而不是指向task_t 的双指针。所以你需要改变:

    task_t *ia = *(task_t**)a;
    task_t *ib = *(task_t**)b;

到:

    const task_t *ia = a;
    const task_t *ib = b;

最后,您需要将sizeof(task_t) 传递给qsort,而不是sizeof(task_t *);同样,数组是task_t,而不是task_t*

【讨论】:

  • sizeof(task_t*) 会给你指针的大小而不是类型。
  • @ryyker:这是有争议的。 void* 将转换为任何类型,而无需在 C 中进行转换,并且在某些情况下转换它绝对不是惯用的(例如don't cast the return from malloc)。在这种情况下,我可以看到任何一种方式,但这不是必需的,所以我选择了最简单的形式。
  • @SPlatten:已修复(或者更准确地说,添加了;有很多错误,而且我在第一遍时没有全部捕捉到)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-30
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
相关资源
最近更新 更多