【发布时间】:2015-11-03 17:48:02
【问题描述】:
我正在编写一个函数,它接收一个指向比较函数的指针和一个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*)。这可以编译但未定义行为(请参阅this SO question)。
选项 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)。问题在于 icky 全局变量。
选项 3
重新实现qsort。这在功能上是安全的,但却是非常糟糕的做法。
有没有神奇的完美第四选择?
编辑
我无法更改 myStructSort 的 API,我正在使用 gcc c99 -Wall -Wextra -Wvla 编译我的代码。
【问题讨论】:
-
在这种情况下,像您在选项 2 中提出的包装函数是最好的方法。顺便说一句,我不太了解您提到的全局变量。它们是干什么用的?
-
HighPredator@,
delegatingComp需要知道调用哪个函数并且不能作为参数传递给它,因为它需要匹配qsort的参数。 -
如果您使用
gcc,gnu 扩展允许您在函数内部定义子函数。它模拟基于堆栈的闭包。如果您不介意便携性损坏,可以尝试一下。 -
@BenjyKessler,啊,现在我明白了。
-
qsort API基本坏了,这个问题没有好的解决办法。
标签: c function-pointers qsort