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

时间:2022-06-05 16:02:59

I have two functions with variable number and types of arguments

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

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 }

I want to use a pointer to a function to the functions I defined above based on a some condition getting true e.g.

我希望使用一个指向函数的指针来实现我在上面定义的函数,这是基于一些条件得到的,例如

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);

My question is, for this scenario, Can I at all define a function pointer? If yes, how?
My understanding is that the prototype of function pointer should be the same for all those functions it CAN be pointed to.

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

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

In my case they are not the same. Is there any other way to do this?

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

Language

I am developing in C and I am using gcc 4.4.3 compiler/linker

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

5 个解决方案

#1


10  

My question is, for this scenario, Can I at all define a function pointer?

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

No. (Other than by dirty typecasting.)

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

Is there any other way to do this?

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

Your best bet is to create a wrapper function for one of your existing functions. For example:

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

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

That way, you have two functions with the same signature, and therefore the same function-pointer type.

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

#2


16  

The cleanest way to do it is to use a union:

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

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;

Then you can initialize an instance of the union, and include information to the swap_function function to say which field is valid:

然后,您可以初始化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);

This assumes that swap_function can know based on condition_1 being false that it should assume condition_2. Note that the union is passed by value; it's only a function pointer in size after all so that's not more expensive than passing a pointer to it.

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

#3


1  

Your understanding is true.
The signature of your function-pointer must match the corresponding function(s).

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

Consider learncpp.com:

Just like it is possible to declare a non-constant pointer to a variable, it’s also possible to >declare a non-constant pointer to a function. The syntax for doing so is one of the ugliest things >you will ever see:

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

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

The parenthesis around *pFoo are necessary for precedence reasons, as int *pFoo() would be interpreted as a function named pFoo that takes no parameters and returns a pointer to an integer.

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

In the above snippet, pFoo is a pointer to a function that has no parameters and returns an integer. pFoo can “point” to any function that matches this signature.

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

...

Note that the signature (parameters and return value) of the function pointer must match the signature of the function.

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

#4


1  

What you want is possible, but a bit dirty. Function pointers can be cast to one another without losing information. The important thing is that you'd always have to call a function through such a pointer only with a signature that corresponds to its definition. So if you cast back before calling the function(s) and call with the correct arguments, all should be fine.

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

#5


-2  

A sample of Typecasting approach for using a same function pointer for different functions of different prototypes. <>

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

#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


10  

My question is, for this scenario, Can I at all define a function pointer?

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

No. (Other than by dirty typecasting.)

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

Is there any other way to do this?

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

Your best bet is to create a wrapper function for one of your existing functions. For example:

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

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

That way, you have two functions with the same signature, and therefore the same function-pointer type.

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

#2


16  

The cleanest way to do it is to use a union:

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

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;

Then you can initialize an instance of the union, and include information to the swap_function function to say which field is valid:

然后,您可以初始化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);

This assumes that swap_function can know based on condition_1 being false that it should assume condition_2. Note that the union is passed by value; it's only a function pointer in size after all so that's not more expensive than passing a pointer to it.

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

#3


1  

Your understanding is true.
The signature of your function-pointer must match the corresponding function(s).

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

Consider learncpp.com:

Just like it is possible to declare a non-constant pointer to a variable, it’s also possible to >declare a non-constant pointer to a function. The syntax for doing so is one of the ugliest things >you will ever see:

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

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

The parenthesis around *pFoo are necessary for precedence reasons, as int *pFoo() would be interpreted as a function named pFoo that takes no parameters and returns a pointer to an integer.

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

In the above snippet, pFoo is a pointer to a function that has no parameters and returns an integer. pFoo can “point” to any function that matches this signature.

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

...

Note that the signature (parameters and return value) of the function pointer must match the signature of the function.

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

#4


1  

What you want is possible, but a bit dirty. Function pointers can be cast to one another without losing information. The important thing is that you'd always have to call a function through such a pointer only with a signature that corresponds to its definition. So if you cast back before calling the function(s) and call with the correct arguments, all should be fine.

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

#5


-2  

A sample of Typecasting approach for using a same function pointer for different functions of different prototypes. <>

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

#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;
}