理解C函数回调的typedef语法

q09*_*987 5 c++

#include <iostream>

typedef char (*callback)(int *data);
typedef char (callback2)(int *data);
typedef char callback3(int *data);

char fun_a(int *d)
{
    if (*d == 10)
        return 'A';
    else
        return 'B';
}

int main()
{
    int num = 10;
    callback cb_1_a;
    cb_1_a = fun_a;
    std::cout << cb_1_a(&num) << std::endl;

    callback cb_1_b;
    cb_1_b = &fun_a;
    std::cout << cb_1_b(&num) << std::endl;

    callback cb_1_c;
    cb_1_c = &fun_a;
    std::cout << (*cb_1_c)(&num) << std::endl;

    /*
    callback2 cb2;
    cb2 = fun_a;    // wrong

    callback3 cb3;
    cb3 = fun_a;    // wrong
    */

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

C++ 编译器不会抱怨 和 的callback2typedef callback3

问题> 和 是什么typedef char (callback2)(int *data)意思typedef char (callback3)(int *data)?是否有我可以应用它们的用例?

Adr*_*ica 6

您的第一个typedef定义callback指向带有int*参数并返回char值的函数的指针。cb_1_a因此,作为指针,您可以将值(适当函数的地址)分配给该类型的变量,就像在,cb_1_bcb_1_c变量的情况下一样;在第一种情况 ( cb_1_a = fun_a;) 中,您使用函数的名称(但注意:不带括号)来代替显式&运算符(如果您在函数名称后添加括号,则您将调用该函数)。

您的第二个和第三个typedef语句将它们的类型定义为实际函数,并且您不能为函数赋值。callback2另外,由于除了中第一组括号内的名称之外没有其他任何内容typedef char (callback2)(int* data);,这些括号实际上是多余的,并且类型相当于下一行中定义的类型:typedef char callback3(int* data);

但是,您可以通过在相关变量声明中添加 来使用后两种类型(间接)来声明函数指针*,如下所示:

    //...
    callback2 *cb2; // cb2 is now a POINTER to a "callback2" type!
    cb2 = fun_a;    // So this is OK - We assign the ADDRESS of fun_a to the cb2 pointer
    callback3 *cb3; // And the same here...
    cb3 = fun_a;    // ...and here
    //...
Run Code Online (Sandbox Code Playgroud)

请随时要求进一步澄清和/或解释。另外,您可能会发现这篇文章在使用typedef和函数指针语法方面很有帮助:Typedef 函数指针?


cig*_*ien 5

这通过语法更容易理解using。这里有 2 个 using 语句:

using A = char (*) (int*);
using B = char (int*);
Run Code Online (Sandbox Code Playgroud)

(请注意,您的第二个和第三个示例是等效的)。

A是一种function-pointer类型。特别是,这种类型的对象可用于存储任何采用 anint*并返回 a的函数的地址char

char f(int*);
A a = f;
Run Code Online (Sandbox Code Playgroud)

af现在可以像您在示例中所示的那样使用。

Bint*是一个函数类型,即它声明一个接受 an并返回 a 的函数char。所以这一行:

B b;
Run Code Online (Sandbox Code Playgroud)

b与声明这样的函数相同:

char b(int*);
Run Code Online (Sandbox Code Playgroud)

至少在评估上下文中,您实际上无能为力,因为我认为没有任何方法可以为此函数声明提供定义。