我在用C为qsort
函数编写比较函数时遇到麻烦。这是我目前拥有的:
int cmpfunc(const void *a, const void *b) {
return (*(Individual*)a->fitness - *(Individual*)b->fitness);
}
我知道比较函数的工作原理,但不了解如何在我的名为Individual
的结构中引用整数值。这是个人的结构。
typedef struct {
PPM_IMAGE image;
double fitness;
} Individual;
我想比较结构中的适应度值。
答案 0 :(得分:5)
这部分
*(Individual*)a->fitness
是错误的。您尝试使用fitness
访问->
,但同时使用*
取消引用指针。你不能两者都做!
这是两种解决方法。
解决方案A:使用*
解引用并使用fitness
访问.
(*(Individual*)a).fitness
解决方案B:使用fitness
访问->
((Individual*)a)->fitness
这两种解决方案都需要将void*
转换为Individual*
。
对于变量b
如果您是C语言的初学者,我建议您避免在发生多种情况的情况下使用紧凑型语句。而是将压缩语句拆分为多个单独的语句。这将使代码更易于理解和调试。喜欢:
int cmpfunc (const void * a, const void * b){
Individual* pA = a;
Individual* pB = b;
double fitnessA = pA->fitness;
double fitnessB = pB->fitness;
return fitnessA - fitnessB;
}
您无需担心性能。编译器会将代码优化为与单语句代码一样高效。
那是-由@chqrlie发现-请注意比较代码是错误的!
该函数返回一个整数,但是fitnessA - fitnessB
是将被转换为整数的双精度型。因此0.1 - 0.0
最终将返回0
-这不是您想要的。
您可以从@chqrlie看到此答案https://stackoverflow.com/a/53466034/4386427,以获取更多详细信息。
代码也可以像这样更改:
int cmpfunc (const void * a, const void * b){
Individual* pA = a;
Individual* pB = b;
double fitnessA = pA->fitness;
double fitnessB = pB->fitness;
if (fitnessA > fitnessB) return 1;
if (fitnessA < fitnessB) return -1;
return 0;
}
答案 1 :(得分:2)
假设您使用qsort
结构数组调用Individual
,则应将compare函数收到的参数强制转换为Individual
结构的指针,最好是const Individual *
以避免警告。
然后可以比较fitness
个成员并返回订购值。请注意,您不能只返回值的差,因为它们可能不是整数,并且差甚至可能溢出类型int
的范围。
这是执行此操作的经典方法:
int cmpfunc(const void *a, const void *b) {
const Individual *aa = a;
const Individual *bb = b;
/* return -1, 0 or 1 depending on the comparison results */
return (aa->fitness > bb->fitness) - (aa->fitness < bb->fitness);
}