2013-05-27 37 views
9

我有可变数目的两种功能和类型的参数函数指针在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编译器/连接

+1

使函数指针成为一个'void *',然后在调用时做适当的类型转换?尽管如此,你仍然放松了所有的安全类型。 –

回答

9

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

号(除脏类型转换。)

是否有任何其他方式做到这一点?

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

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

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

+0

感谢@Oli Charlesworth和其他人对他们的真正快速回复。 – fahad

1

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

考虑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可以“指向”与此签名匹配的任何函数。

...

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

+1

这并没有真正回答这个问题... –

+0

更正了我的帖子 –

1

你想要什么是可能的,但有点脏。函数指针可以互相投射而不会丢失信息。重要的是,你总是必须通过调用函数通过这样一个指针,只有一个符合其定义的签名。所以如果你在调用函数和调用正确的参数之前退回,所有应该没问题。

14

做最彻底的方法是使用工会:

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; 

然后你就可以初始化工会的一个实例,包括信息的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_1false知道它应该假设condition_2。请注意,联合会按值传递;它毕竟只是一个函数指针,所以这并不比传递指针更昂贵。

-2

对于不同原型的不同功能使用相同函数指针的类型转换方法的示例。 <>

#include <stdio.h> 
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; 
} 
+1

请问您可以添加一个你已经完成的描述吗?而不是仅仅粘贴代码。 – kaldoran