对于类赋值,我们正在编写一个接受输入的程序,并用qsort对每行输入进行排序,并使用strcmp作为比较器函数。因为strcmp的类型与qsort所需的类型不同,所以需要构建一个包装函数来满足qsort。
我对此并不满意,并希望编写一个函数,它具有类型的函数:
int (*cmp)(const char *, const char *)
并返回类型为的函数:
int (*qsortcmp)(const void *, const void *)
这可能吗?我写过太多haskell了吗?我想知道。
答案 0 :(得分:1)
C不支持lambda函数。您唯一的选择是创建storagereference.get(10)
所需类型的函数,并从该函数内部调用qsort
。
例如:
strcmp
答案 1 :(得分:0)
只有全局变量可以保存真正的函数才能调用。 (是的,那太可怕了。)
有一个原因:只有明显参数的函数指针不能代表闭包。如果struct declaration
接受了类型为
qsort
和int (*)(void *closure, const void*, const void*)
为每次比较传递它,可以写一个转换器:
void*
我认为很明显为什么在实践中人们更喜欢硬编码的解决方案。 (实际上,懒惰的程序员只是直接传递struct char_qsorter {
int (*function)(void*, const char*, const char*);
void *param;
};
struct qsorter {
int (*function)(void*, const void*, const void*);
void *param;
};
int char_qsort_wrapper(void *closure, const void *a, const void *b) {
const char_qsorter *const cq=closure;
return cq->function(cq->param, a, b);
}
qsorter convert(const char_qsorter *cq) {
const qsorter ret={char_qsort_wrapper, cq};
return ret;
}
/* Convert a plain function pointer: */
int trivial_wrapper(void *closure, const char *a, const char *b) {
return (*(int (*const *)(const char*, const char*))closure)(a, b);
}
char_qsorter trivial_closure(int (*const *f)(const char*, const char*)) {
const char_qsorter ret={trivial_wrapper, f};
return ret;
}
void sort_strings(const char *const *ss, size_t n) {
int (*const f0)(const char*, const char*)=strcmp;
const char_qsorter cq=trivial_closure(&f0);
const qsorter q=convert(&cq);
qsort_closure(ss, n, sizeof(*ss), q.function, q.param);
/* or just pass q if the library used the struct */
}
,这适用于大多数实现。)
C11确实支持qsort_s
,但它是一个特殊的可选函数,添加了奇怪的运行时错误检查。