[英]qsort() in array of structure in C [duplicate]
这个问题已经在这里有了答案:
我正在尝试对需要20个输入的结构数组进行排序,并使用C的标准库函数qsort()对它们进行排序,但没有得到正确的排序输出。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma pack(1)
struct player{
char name[4];
short age;
short match;
float average;
};
#pragma pack()
int comp(const void *p,const void *q){
float *a=(float*)p;
float *b=(float*)q;
if(*b-*a>0)return 1;
if(*b-*a<0)return 1;
if(*b-*a==0)return 0;
}
int main(){
struct player list[20];
for(int i=0;i<20;i++){
scanf("%s",list[i].name);
scanf("%hu %hu %f",&list[i].age,&list[i].match,&list[i].average);
}
qsort((void*)list,20,sizeof(struct player),comp);
for(int i=0;i<20;i++){
printf("%2.2f %10s %4hu %4hu\n",list[i].average,list[i].name,list[i].age,list[i].match);
}
return 0;
}
可以使用以下测试用例来检查输出。
aaa 21 22 34
qsd 33 21 44
qqq 1 2 55.2
www 33 22 12.2
ewe 22 11 13.3
qaz 22 33 12.33
aaa 21 22 34
qsd 33 21 44
qqq 1 2 54.2
www 33 22 12.2
eee 22 11 16.3
qaz 22 33 18.33
aaa 21 22 34
qsd 33 21 49
qqq 1 2 52.2
www 33 22 12.2
eee 22 11 10.3
qaz 22 33 11.33
eee 22 11 14.3
qaz 22 33 11.33
使用如下比较函数:
int comp(const void *p, const void *q) {
struct player *p1 = (player*)p;
struct player *p2 = (player*)q;
if (p1->average > p2->average) return 1;
if (p1->average < p2->average) return -1;
return 0;
}
您的自定义比较方法应如下所示:
int comp(const void *p, const void *q) {
struct player *a = (struct player*)p;
struct player *b = (struct player*)q;
if(b->average > a->average)
return 1;
else if (b->average < a->average)
return -1;
else
return 0;
}
作为@EugeneSh。 和@WeatherVane注释,该方法的参数是指向结构的指针-例如,在一定的比较下,数组的第一个元素将由p
指向,第二个元素由q
指向。
因此,您首先需要强制转换为指向该结构的指针,然后使用其字段执行实际比较。
现在,该比较具有@Gereon的逻辑缺陷,我评论说:在少而大的情况下返回1,这肯定不是您想要的。 在一种情况下返回1,在另一种情况下返回-1。
return 0;
在这种情况下,可以确保排序稳定 。
提示:请勿尝试使用return p1->average - p2->average
,如ref的示例中通常说明的那样,因为您正在处理float
,并且您需要的至少是数值不稳定性,因为它可能会溢出。 而且,该差可以小于1,但随后将其转换为int
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.