2017-10-22 142 views
0

对于类的赋值,我们正在编写一个程序,它接受输入,并用strcmp作为其比较函数对qsort的每一行进行排序。由于strcmp的类型与qsort所需的不同,因此需要构建一个包装函数来满足qsort。是否有可能在C函数中构建函数?

我并不满足于此,并希望写一个函数,它接受的类型的函数:

int (*cmp)(const char *, const char *) 

,并返回类型的函数:

int (*qsortcmp)(const void *, const void *) 

这是可能的?我是否写过太多的哈斯克尔?我想知道。

回答

1

C不支持lambda函数。您唯一的选择是创建一个qsort预期类型的​​函数,并从该函数内部调用strcmp

例如:

int qsort_cmp_str(const void *a, const void *b) 
{ 
    const char *s1 = a; 
    const char *s2 = b; 
    return strcmp(s1, s2); 
} 
+0

想象我的脑子太深入功能编程。谢谢你的回答! – Sam

+0

@ Sam很高兴我能帮到你。如果您觉得它有用,请随时[接受此答案](https://stackoverflow.com/help/accepted-answer)。 – dbush

0

有可能只与拥有真正的函数来调用一个全局变量。 (是的,那太可怕了。)

有一个原因:只有明显参数的函数指针不能代表关闭。有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 */ 
} 

我认为这是显而易见的,为什么在实践中人们更喜欢硬编码解决方案就足够了。 (真的,懒惰的程序员只是通过strcmp直接,工作于大部分的实现。)

C11的确与qsort_s支持这一点,但它是一个特殊的可选功能检查与添加怪异运行时错误。

+0

比你!似乎我被功能柯里化宠坏了。 – Sam

+0

@Sam:我会说这是捕获,而不是卷曲,你失踪了,但是,Haskell破坏我们。 –

相关问题