首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Sorting ()的排序结构

使用Sorting ()的排序结构
EN

Stack Overflow用户
提问于 2014-04-01 17:46:12
回答 4查看 13.2K关注 0票数 0

在实现内置于C中的qsort()以通过存储的int值(hitCount)对结构数组进行排序时遇到困难。

我的结构:

代码语言:javascript
复制
typedef struct words {
    const char *word;
    int hitCount;
} words;

我正在尝试使用微软(http://support.microsoft.com/kb/73853)给出的例子。

所以我在上面:

代码语言:javascript
复制
typedef int (*compfn)(const void*, const void*);

比较方法:

代码语言:javascript
复制
int compare (words *a, words *b) {
    if (a->hitCount > b->hitCount) {
        return -1;
    } else if (a->hitCount < b->hitCount) {
        return 1;
    } else {
        return 0;
    }
}

然后,在另一个方法中,我用数组名和其他详细信息调用qsort来替换Microsoft示例:

代码语言:javascript
复制
qsort((void *) &output, outputLength, sizeof(words), (compfn)compare);

这就产生了分割错误。

我不完全理解如何使用qsort,所以我假设我从微软的例子中调整了它,我做得不对。

我希望我已经包括了错误,并能得到一些启示,我应该做什么,以使这一工作正确。

非常感谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-04-01 17:55:47

您必须将数组(而不是数组的地址)传递给qsort。

代码语言:javascript
复制
qsort( output, ... );

另外,您的比较函数必须返回一个int并接受两个const *参数。将函数int compare (words *a, words *b)转换为不同(但仍正确)类型,然后由qsort()调用,将导致未定义的行为。

比较功能必须是:

代码语言:javascript
复制
int compare (const void *a, const void *b)...

然后将a和b转换为正确的类型:

代码语言:javascript
复制
((words*)a)->hitCount < ((words*)b)->hitCount
票数 3
EN

Stack Overflow用户

发布于 2014-04-01 18:07:34

我怀疑outputLength计算错误。一个完整的工作示例:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

typedef struct words {
    const char *word;
    int hitCount;
} words;

int compare(const void * left, const void * right) {
    const words * a = (const words *) left;
    const words * b = (const words *) right;
    if (a->hitCount > b->hitCount) {
        return -1;
    } else if (a->hitCount < b->hitCount) {
        return 1;
    } else {
        return 0;
    }
}

int main() {
    struct words output[] = {
      { "hello", 314 },
      { "world", 42 },
      { "answer", 42 }
    };
    int outputLength = sizeof(output) / sizeof(output[0]);
    int i;

    output[0].word = "hello";
    output[0].hitCount = 314;
    output[1].word = "world";
    output[1].hitCount = 42;
    qsort(output, outputLength, sizeof(words), compare);

    for (i = 0; i < outputLength; ++i) {
        printf("%d %s\n", output[i].hitCount, output[i].word);
    }

    return 0;
}
票数 1
EN

Stack Overflow用户

发布于 2014-04-01 18:31:50

标准库函数qsort的原型是

代码语言:javascript
复制
void qsort(void *base, size_t nmemb, size_t size, 
           int (*compar)(const void *, const void *));

注意compare函数的签名。您无法键入指向不同签名的函数的指针并使其正确工作。因此,键入您的比较函数将无法工作。它必须具有与qsort原型中声明的相同的签名。将compare函数更改为-

代码语言:javascript
复制
int compare(const void *a, const void *b) {
    int c = ((words *) a)->hitCount;
    int d = ((words *) b)->hitCount;

    if(c > d) return -1;
    if(c < d) return 1;
    return 0;
}

第一个参数base of qsort是缓冲区的基址,它包含要排序的元素。而且,任何指针类型都是与void *变量兼容的赋值,因此不需要转换基址。因此,您应该将qsort函数调用为-

代码语言:javascript
复制
qsort(output, outputLength, sizeof output[0], compare);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22793123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档