qsort的比较功能无法正常工作

问题描述 投票:0回答:1

我正在尝试对结构的指针数组进行排序。该结构具有一个int成员val和一个字符串type

[数组需要按val降序排序,如果两个元素具有相同的val,则它们将按字典顺序升序排序。

但是,在编写一些调试行之后,我发现我用于qsort的比较函数将打印垃圾值,而不是正确的值。这是我的代码的相关部分:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct obj {
    char type[20];
    int val;
    struct obj *nextPtr;
} Object;

int cmpfun(const void* a, const void* b) { // used by qsort
    Object* x = (Object *) a;
    Object* y = (Object *) b;

    if(x == NULL) return 1;
    if(y == NULL) return -1;

    if (x->val > y->val) { // this doesn't work
        printf("%s %d > %d\n", x->type, x->val, y->val);
        return -1;
    }
    else if (x->val < y->val) { // this doesn't work
        printf("%d < %d\n", x->val, y->val);
        return 1;
    }

    if (strcmp((x)->type, (y)->type) > 0) // this doesn't work
        return 1;
    return -1;
}

int hash(char a[], int mod) {
    mod *= 2;

    int sum = 0;

    for(size_t i = 0; i < strlen(a); i++) {
        sum += (unsigned int) a[i];
    }

    return sum % mod;
}

Object *newNode(char *type, int val) {
    Object *newPtr = malloc(sizeof(Object));
    if(newPtr == NULL) exit(EXIT_FAILURE);

    strcpy(newPtr->type, type);
    newPtr->val = val;
    newPtr->nextPtr = NULL;

    return newPtr;
}

void hashedInsert(Object **lPtr, char *type, int val) {
    if(*lPtr == NULL) {
        *lPtr = newNode(type, val);
        return;
    }

    if(val > (*lPtr)->val)
        (*lPtr)->val = val;
}

int main() {
    int numObjects;

    scanf("%d", &numObjects); // get number of objects

    Object **dictionary = malloc(sizeof(Object*) * 2 * numObjects); // allocate memory for dictionary
    if(dictionary == NULL) return EXIT_FAILURE;

    for(size_t i = 0; i < (2*numObjects); i++) {
        dictionary[i] = malloc(sizeof(dictionary[i])); // allocate single rows
        if(dictionary[i] == NULL) return EXIT_FAILURE;

        dictionary[i] = NULL; // all lists are initialized as empty
    }

    char thisType[20];
    int thisVal, thisHashed;

    for(size_t i = 0; i < numObjects; i++) {
        while(getchar() != '\n');
        scanf("%s", thisType); // first line is object type
        scanf("%d", &thisVal); // second line is its val field

        thisHashed = hash(thisType, numObjects); // calculate position of insertion using hash function

        hashedInsert(&(dictionary[thisHashed]), thisType, thisVal); // update the dictionary
    }

    qsort(dictionary, numObjects*2, sizeof(Object), cmpfun); // sort the dictionary


    return EXIT_SUCCESS;
}

例如,如果我输入这两个对象作为输入:

a
1
b
2

我的比较功能输出:

21900 > 0
21900 > 0

而不是预期的2 > 1。我想念什么?

c arrays qsort
1个回答
-1
投票

由于您要排序的数组是[[指针到Object的数组,所以cmpfun的参数将是指针的指针(到Object对象)。因此,在该函数中,您应该替换以下行:

Object* x = (Object *) a; Object* y = (Object *) b;
with:

Object* x = *((Object**)(a)); Object* y = *((Object**)(b));

并且,相应地,您需要将调用中的“ size”参数从qsort的大小更改为Object

qsort(dictionary, numObjects*2, sizeof(Object), cmpfun); // Wrong size!

Object的大小

指针:

qsort(dictionary, numObjects * 2, sizeof(Object*), cmpfun); // Right size.
随时要求进一步的澄清和/或解释。
© www.soinside.com 2019 - 2024. All rights reserved.