我正在编写一个函数,它接收一个指向比较函数的指针以及一个MyStructs
的数组,并且应该根据比较函数对数组进行排序:
void myStructSort(
struct MyStruct *arr,
int size,
int (*comp)(const struct MyStruct *, const struct MyStruct *)) {
qsort(arr, size, sizeof(struct MyStruct), comp);
}
很遗憾,这段代码无法编译,因为qsort
期望比较函数接收void *
类型的参数而不是const struct MyStruct *
类型的参数。我想到了一些不好的解决方案,并且想知道正确的解决方案。
选项1
将comp
强制转换为int (*)(const void *, const void*)
。虽然它可以编译通过,但这是未定义行为(参见此stackoverflow问题)。
选项2
创建一个全局变量int (*global_comp)(const struct MyStruct *, const struct MyStruct *)
,并在myStructSort
内设置global_comp=comp
。然后创建一个函数:
int delegatingComp(const void *a, const void *b) {
return globalComp((const struct MyStruct *)a, (const struct MyStruct *)b);
}
在myStructSort
中调用qsort(arr, size, sizeof(struct MyStruct), delegatingComp)
。这样做的问题是全局变量不好。
选项3
重新实现qsort
。这样做功能上是安全的,但是非常不好的做法。
有没有神奇完美的第四个选项?
编辑
我不能更改myStructSort
的API,并且使用gcc c99 -Wall -Wextra -Wvla
编译我的代码。
delegatingComp
需要知道调用哪个函数,但不能将其作为参数传递给它,因为它需要与qsort
的参数匹配。 - Benjy Kesslerstatic
变量设置为第二个参数中的任何内容(您可以使用struct
或union
传递函数指针)... 这将允许您将全局移动到函数中(作为static
变量),但我确定这不是您想要的,而且它仍然非常丑陋! - autistic