当一个参数为常量时更改 C 中函数指针的签名

Change signature of function pointer in C when one argument is constant

我想在 C 中使用快速排序,它的函数签名为 void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)),但我的比较函数的签名为 int (*compar)(const void *, const void*, const int),在一次调用快速排序期间第三个参数为常量。

举个例子,假设我想根据不同的范数(例如 L0、L1、L2 和 Linifinity 范数)对向量数组进行排序。它实际上是哪个范数,作为第三个参数传递给比较函数,但在 qsort 的调用期间保持不变。是否可以以

这样的形式进行分配
//Function declaration for parametric comparison
int cmp3(int* a_vec, int* b_vec, int x);

// Somewhere in main
int (*cmp2)(int, int);
cmp2 = cmp3(int*, int*, 2);//2 could mean L2 norm

能够调用类似

的东西
qsort(a, 100, sizeof(a), cmp2);

我知道这行不通,但我希望它能让我知道我想要完成什么。此外,由于不同比较方式的数量太多,因此无法进行不同的比较功能和对 qsort 的调用。

这叫做 partial function application,你只能用 C:

中的包装器实现这样的东西
int cmp3(int *a, int *b) {
    return cmp2(a, b, 2);
} 

如果您喜欢部分函数应用程序或映射或纯函数,您可能想研究函数式编程语言,例如 Haskell。

主要问题是函数签名在调用之前需要堆栈中的 3 个元素。旧的 C 编译器是 "smart",如果你没有传递足够的参数,那么它们 "complete" 堆栈有空变量(归零)。

现在,如果你这样做(假设编译器接受),它将在堆栈中有一个未定义值的第三个变量,而不是你期望的值。

你应该做一个 "proxy" 功能,正如之前的评论所说:

int cmp3(int *a, int *b) {
    return cmp2(a, b, 2);
}