当我阅读其他人的代码时,我总是有点困惑,这些代码为带有参数的函数指针提供了typedefs。我记得,当我试图理解不久前用C语言编写的数值算法时,我花了一段时间才得到这样的定义。那么,关于如何为函数指针编写良好的typedef (Do's和Do's),以及它们为什么有用以及如何理解其他人的工作,您能分享一下您的技巧和想法吗?谢谢!


当前回答

A function pointer is like any other pointer, but it points to the address of a function instead of the address of data (on heap or stack). Like any pointer, it needs to be typed correctly. Functions are defined by their return value and the types of parameters they accept. So in order to fully describe a function, you must include its return value and the type of each parameter is accepts. When you typedef such a definition, you give it a 'friendly name' which makes it easier to create and reference pointers using that definition.

例如,假设你有一个函数:

float doMultiplication (float num1, float num2 ) {
    return num1 * num2; }

然后是下面的类型定义:

typedef float(*pt2Func)(float, float);

可以用来指向这个doMulitplication函数。它只是定义一个指向函数的指针,该函数返回一个浮点数,并接受两个参数,每个参数都是float类型。这个定义有一个友好的名字pt2Func。请注意,pt2Func可以指向返回一个浮点数并接受2个浮点数的任何函数。

所以你可以创建一个指针指向doMultiplication函数,如下所示:

pt2Func *myFnPtr = &doMultiplication;

你可以使用这个指针调用函数,如下所示:

float result = (*myFnPtr)(2.0, 5.1);

这是一个很好的阅读:http://www.newty.de/fpt/index.html

其他回答

A function pointer is like any other pointer, but it points to the address of a function instead of the address of data (on heap or stack). Like any pointer, it needs to be typed correctly. Functions are defined by their return value and the types of parameters they accept. So in order to fully describe a function, you must include its return value and the type of each parameter is accepts. When you typedef such a definition, you give it a 'friendly name' which makes it easier to create and reference pointers using that definition.

例如,假设你有一个函数:

float doMultiplication (float num1, float num2 ) {
    return num1 * num2; }

然后是下面的类型定义:

typedef float(*pt2Func)(float, float);

可以用来指向这个doMulitplication函数。它只是定义一个指向函数的指针,该函数返回一个浮点数,并接受两个参数,每个参数都是float类型。这个定义有一个友好的名字pt2Func。请注意,pt2Func可以指向返回一个浮点数并接受2个浮点数的任何函数。

所以你可以创建一个指针指向doMultiplication函数,如下所示:

pt2Func *myFnPtr = &doMultiplication;

你可以使用这个指针调用函数,如下所示:

float result = (*myFnPtr)(2.0, 5.1);

这是一个很好的阅读:http://www.newty.de/fpt/index.html

使用typedef定义更复杂的类型,如函数指针

我将以用C定义状态机为例

    typedef  int (*action_handler_t)(void *ctx, void *data);

现在我们已经定义了一个名为action_handler的类型,它接受两个指针并返回一个int

定义状态机

    typedef struct
    {
      state_t curr_state;   /* Enum for the Current state */
      event_t event;  /* Enum for the event */
      state_t next_state;   /* Enum for the next state */
      action_handler_t event_handler; /* Function-pointer to the action */

     }state_element;

指向动作的函数指针看起来像一个简单的类型,typedef主要用于此目的。

我的所有事件处理程序现在都应该遵循action_handler定义的类型

    int handle_event_a(void *fsm_ctx, void *in_msg );

    int handle_event_b(void *fsm_ctx, void *in_msg );

引用:

Linden编写的C语言编程专家

Cdecl是一个很好的工具,可以用来破译奇怪的语法,比如函数指针声明。您也可以使用它来生成它们。

至于使复杂的声明更容易解析以便将来维护(自己或他人)的技巧,我建议创建小块的typedef,并将这些小块用作更大更复杂表达式的构建块。例如:

typedef int (*FUNC_TYPE_1)(void);
typedef double (*FUNC_TYPE_2)(void);
typedef FUNC_TYPE_1 (*FUNC_TYPE_3)(FUNC_TYPE_2);

而不是:

typedef int (*(*FUNC_TYPE_3)(double (*)(void)))(void);

Cdecl可以帮助你解决这些问题:

cdecl> explain int (*FUNC_TYPE_1)(void)
declare FUNC_TYPE_1 as pointer to function (void) returning int
cdecl> explain double (*FUNC_TYPE_2)(void)
declare FUNC_TYPE_2 as pointer to function (void) returning double
cdecl> declare FUNC_TYPE_3 as pointer to function (pointer to function (void) returning double) returning pointer to function (void) returning int
int (*(*FUNC_TYPE_3)(double (*)(void )))(void )

这(事实上)正是我如何产生上面那个疯狂的混乱。

一个非常简单的方法来理解函数指针的typedef:

int add(int a, int b)
{
    return (a+b);
}

typedef int (*add_integer)(int, int); //declaration of function pointer

int main()
{
    add_integer addition = add; //typedef assigns a new variable i.e. "addition" to original function "add"
    int c = addition(11, 11);   //calling function via new variable
    printf("%d",c);
    return 0;
}

宏呢?我已经看到,使用类型定义,我不能将一些东西强制转换为函数指针。所以我为它做了这个小宏,它能够做我到目前为止需要的所有事情(不知道它不能用于什么-我认为它基本上是一个类型定义,但有一个可选参数,使它在类型转换中可用):

#define funcptr_t(sym_name) void (*sym_name)(void)

// Declare a function pointer-returning function, and declare a function pointer variable.
funcptr_t (randomFunction(funcptr_t (func_ptr_variable)));
// Cast a variable to a function pointer
(funcptr_t()) some_variable;

PS:我做这个通用用途,不确定它是否可以修改为特定的功能使用。