簡體   English   中英

如何使用 qsort 對結構指針數組進行排序

[英]how to Sorting an array of struct pointers with qsort

這是我的Book結構,這是我的代碼:

typedef struct book {
   char title[100];
   char author[20];
   int price;
} BOOK;

#define MAX_SIZE 10

int comparePrice(const void *bookA, const void *bookB);

int count = 0;

int main() {    
    BOOK *books[MAX_SIZE];    // here is  array of struct pointers
    while (1) {   
        char title[100] = "";
        char author[20] = "";
        int price = -1;
        //////////// printf select menu ////////////
        int selector = -1;
        scanf("%d", &selector);
        switch (selector) {
          case 1:
            while (getchar() != '\n');
            printf("--------input book data--------\n");
            printf("title :");
            gets(title);
            printf("author :");
            gets(author);

            printf("price :");
            scanf("%d", &price);

            books[count] = (BOOK *) malloc(sizeof(BOOK));
            memset(books[count], 0, sizeof(BOOK));
            strcpy(books[count]->title, title);
            strcpy(books[count]->author, author);
            books[count]->price = price;
            count++;
            break;
          case 4:
            printf("--------sorting price--------\n");
            qsort(books, count, sizeof(BOOK), comparePrice);
            for (int i = 0; i < count; ++i) {
                printf("%d. title: %s author: %s price: %d\n", i + 1, books[i]->title, books[i]->author, books[i]->price);
            }
            break;
          default:
            for (int i = 0; i < MAX_SIZE; ++i) {
                free(books[i]);
                books[i] = NULL;
            }
            return 0;
        }
    }
}

int comparePrice(const void *bookA, const void *bookB) {
    const BOOK *a = (const BOOK *)bookA;
    const BOOK *b = (const BOOK *)bookB;
    return b->price - a->price;
}

qsort不工作 select 4 號菜單,該程序停止。 我嘗試調試,發現 a 和 b 有未知值。 並且打印排序結果的printf語句出現EXC_BAD_ACCESS錯誤。 我需要做些什么來進行排序。

比較 function 是不正確的:它獲取指向數組的指針,因此指向結構指針。 此外,如果減法溢出,則通過減去它們來比較整數不起作用,這在比較非常大的相反符號值時是可能的。

這是修改后的版本:

int comparePrice(const void *aa, const void *bb) {
    const BOOK *a = *(const BOOK * const *)aa;
    const BOOK *b = *(const BOOK * const *)bb;
    /* sort in decreasing order of price */
    return (b->price > a->price) - (b->price < a->price);
}

qsort()調用也不正確。 它應該是:

qsort(books, count, sizeof(*books), comparePrice);

代碼中還有其他問題:

  • 數組books未初始化,因此您應該只free已分配的指針:將最后一個循環更改為

     while (count > 0) { free(books[--count]); }
  • 不要使用gets()

  • 當心潛在的無限循環: while (getchar();= '\n'); 始終測試EOF

     int c; while ((c = getchar());= EOF && c != '\n') continue;

qsort 將指向數組中元素的指針傳遞給比較 function (在您的情況下,它們本身就是指針)。 所以你要:

int comparePrice(const void *bookA, const void *bookB) {
    const BOOK *a = *(const BOOK **)bookA;
    const BOOK *b = *(const BOOK **)bookB;
    return b->price - a->price;
}

數組books應該被初始化

BOOK *books[MAX_SIZE] = { NULL };

否則這個循環

for (int i = 0; i < MAX_SIZE; ++i) {
    free(books[i]);
    books[i] = NULL;
}

將調用未定義的行為。

因為你有一個指針數組,所以qsort的調用應該至少看起來像

qsort( books, count, sizeof( BOOK * ), comparePrice );

另一方面,他 function comparePrice應該定義如下

int comparePrice( const void *bookA, const void *bookB ) 
{
    const BOOK *a = *( const BOOK * const * ) bookA;
    const BOOK *b = *( const BOOK * const * ) bookB;
    
    return ( a->price < b->price ) - ( b->price < a->price );
}

這是一個簡化的演示程序。

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

typedef struct book
{
    int price;
} BOOK;

int comparePrice( const void *bookA, const void *bookB ) 
{
    const BOOK *a = *( const BOOK * const * ) bookA;
    const BOOK *b = *( const BOOK * const * ) bookB;
    
    return ( a->price < b->price ) - ( b->price < a->price );
}

int main(void) 
{
    BOOK b1 = { 10 }, b2 = { 20 };
    BOOK *a[] = { &b1, &b2 };
    const size_t count = sizeof( a ) / sizeof( *a );
    
    for ( size_t i = 0; i < count; i++ )
    {
        printf( "%d ", a[i]->price );
    }
    
    putchar( '\n' );

    qsort( a, count, sizeof( BOOK * ), comparePrice );
    
    for ( size_t i = 0; i < count; i++ )
    {
        printf( "%d ", a[i]->price );
    }
    
    putchar( '\n' );
    
    return 0;
}

程序 output 是

10 20 
20 10

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM