问题描述
这是我的 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],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
不起作用
选择数字 4 菜单,该程序停止。
我尝试调试,发现 a 和 b 具有未知值。
而打印排序结果的printf语句出现EXC_BAD_ACCESS
错误。
我需要做的排序。
解决方法
比较函数不正确:它获取指向数组的指针,因此指向结构指针的指针。此外,如果减法溢出,则通过减法来比较整数不起作用,这在比较非常大的相反符号值时是可能的。
这是修改后的版本:
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 将指向数组中元素的指针传递给 compar 函数(在您的情况下,它们本身就是指针)。所以你想要:
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,sizeof( BOOK * ),comparePrice );
另一方面,他的函数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,comparePrice );
for ( size_t i = 0; i < count; i++ )
{
printf( "%d ",a[i]->price );
}
putchar( '\n' );
return 0;
}
程序输出为
10 20
20 10