函数指针指向C中具有不同参数的不同函数

我有两个函数,可变数量和参数类型

double my_func_one(double x, double a, double b, double c) { return x + a + b + c } double my_func_two(double x, double p[], double c) { return x + p[0] + p[1] + c } 

我希望使用一个指向函数的指针来实现我上面定义的函数,这些函数基于某些条件变为真,例如

 if (true == condition_1) pfunc = my_func_one; else if (true == condition_2) pfunc = my_func_two; // The function that will use the function I passed to it swap_function(a, b, pfunc); 

我的问题是,对于这种情况,我可以定义一个函数指针吗? 如果有,怎么样?
我的理解是函数指针的原型应该与它可以指向的所有函数相同。

 typedef double (*pfunction)(int, int); 

就我而言,他们不一样。 有没有其他方法可以做到这一点?

语言

我正在用C语言开发,我正在使用gcc 4.4.3编译器/链接器

我的问题是,对于这种情况,我可以定义一个函数指针吗?

没有。(除了肮脏的类型转换。)

有没有其他方法可以做到这一点?

最好的办法是为现有的一个函数创建一个包装函数。 例如:

 double my_func_one_wrapper(double x, double p[], double c) { return my_func_one(x, p[0], p[1], c); } 

这样,您有两个具有相同签名的函数,因此具有相同的函数指针类型。

最简洁的方法是使用联合:

 typedef union { double (*func_one)(double x, double a, double b, double c); double (*func_two)(double x, double p[], double c); } func_one_two; 

然后,您可以初始化union的实例,并将信息包含在swap_function函数中,以说明哪个字段有效:

 func_one_two func; if (condition_1) func.func_one = my_func_one; else if (condition_2) func.func_two = my_func_two; // The function that will use the function I passed to it swap_function(a, b, func, condition_1); 

这假设swap_function可以基于condition_1知道它应该假设condition_2 。 请注意,union按值传递; 它毕竟只是一个大小的函数指针,所以它并不比传递指针更昂贵。

你的理解是真的。
函数指针的签名必须与相应的函数匹配。

考虑learncpp.com :

就像可以声明一个指向变量的非常量指针一样,也可以>声明一个指向函数的非常量指针。 这样做的语法是你将看到的最丑陋的事情之一:

 // pFoo is a pointer to a function that takes no arguments and returns an integer int (*pFoo) (); 

出于优先级原因,* pFoo周围的括号是必需的,因为int *pFoo()将被解释为名为pFoo的函数,该函数不接受任何参数并返回指向整数的指针。

在上面的代码片段中, pFoo是一个指向没有参数并返回整数的函数的指针。 pFoo可以“指向”任何与此签名匹配的函数。

请注意,函数指针的签名(参数和返回值)必须与函数的签名匹配。

你想要什么是可能的,但有点脏。 函数指针可以相互转换而不会丢失信息。 重要的是你总是必须通过这样的指针调用一个函数,只有一个与其定义相对应的签名。 因此, 如果你在调用函数之前强制转换并使用正确的参数调用,那么一切都应该没问题。

一个类型转换方法的示例,用于为不同原型的不同function使用相同的函数指针。 <>

 #include  typedef void (*myFuncPtrType) (void); typedef int (*myFunc2PtrType)(int, int); typedef int * (*myFunc3PtrType)(int *); static void myFunc_1 (void); static int myFunc_2 (int, int); static int* myFunc_3 (int *); const myFuncPtrType myFuncPtrA[] = { (myFuncPtrType)myFunc_1, (myFuncPtrType)myFunc_2, (myFuncPtrType)myFunc_3 }; static void myFunc_1 (void) { printf("I am in myFunc_1 \n"); } static int myFunc_2 (int a, int b) { printf("I am in myFunc_2\n"); return (a+b); } static int* myFunc_3 (int *ptr) { printf("I am in myFunc_3\n"); *ptr = ((*ptr) * 2); return (ptr+1); } int main(void) { // your code goes here int A[2],C; int* PTR = A; (*(myFuncPtrA[0]))(); A[0]=5; A[1]=6; C = ((myFunc2PtrType)(*(myFuncPtrA[1])))(A[0],A[1]); printf("Value of C: %d \n", C); printf("Value of PTR before myFunc_3: %p \n", PTR); printf("Value of *PTR before myFunc_3: %d \n", *PTR); PTR = ((myFunc3PtrType)(*(myFuncPtrA[2])))(&A); //Lets look how PTR has changed after the myFunc_3 call printf("Value of PTR after myFunc_3: %p \n", PTR); printf("Value of *PTR after myFunc_3: %d \n", *PTR); return 0; }