C++ 了解如何使用带有指针的typedef void函数作为参数

C++ 了解如何使用带有指针的typedef void函数作为参数,c++,c,pointers,typedef,function-declaration,C++,C,Pointers,Typedef,Function Declaration,我试图理解一个用C语言编写的固件,它驱动一个超宽带连接芯片 固件大量使用typedef和指针。我已经理解了固件背后的大部分想法,但是有一个typedef void函数我不理解 基本上,固件创建一个结构来保存设备数据 typedef struct { //some data dwt_cb_t cbTxDone; // Callback for TX confirmation event //some other data } dwt_local_data_t ; 我知道这

我试图理解一个用C语言编写的固件,它驱动一个超宽带连接芯片

固件大量使用
typedef
和指针。我已经理解了固件背后的大部分想法,但是有一个
typedef void
函数我不理解

基本上,固件创建一个结构来保存设备数据

typedef struct
{
   //some data
   dwt_cb_t    cbTxDone; // Callback for TX confirmation event
   //some other data
} dwt_local_data_t ;
我知道这个结构名为dwt\u local\u data\u t,包含一些变量,包括这个奇怪的dwt\u cb\u t类型

在.h文件中,dwt\u cb\u t被命名为

// Call-back type for all events    
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
其中,dwt\u cb\u data\u t是以下形式的另一种结构:

typedef struct
{
    uint32 status;      //initial value of register as ISR is entered
    uint16 datalength;  //length of frame
    uint8  fctrl[2];    //frame control bytes
    uint8  rx_flags;    //RX frame flags, see above
} dwt_cb_data_t;
现在,我试图理解
typedef void(*dwt_cb_t)(const dwt_cb_data_t*)的含义

据我所知,
typedef void
是指向函数类型的指针。它定义了一个变量dwt\u cb\u t,该变量指向一个函数,该函数接收一个常量结构dwt\u cb\u data\u t


我不知道我的推理是否正确,因为我不明白为什么在dwt\u cb\u data\u t的末尾有一个
*
。这是否意味着函数的输入是结构的指针?在这种情况下,为什么不写
typedef void(*dwt\u cb\t)(const*dwt\u cb\u data\t)取而代之?

停止思考
typedef void
。您正以这种方式截断定义

定义的符号是
dwt\u cb\u t
,是类型
void(*)(const dwt\u cb\u data\u t*)
的别名,即:指向函数的指针,该函数取
const dwt\u cb\u data\u t*
参数并返回
void

在C++中你会写:

使用dwt_cb_t=void(*)(常量dwt_cb_data_t*);
这是非常清楚的

这是否意味着函数的输入是 结构

是的,它表示函数的参数是指向结构的指针

在这种情况下,为什么不写呢

typedef void (*dwt_cb_t)(const*dwt_cb_data_t);
相反

这是因为指针符号
*
必须放在标识符之前,而不是标识符类型之前。 在这种情况下,您可以看到如下功能:

typedef void (*dwt_cb_t)(const dwt_cb_data_t *var);
唯一的问题是,
var
被省略了

现在,我试图理解
typedef void(*dwt_cb_t)(const dwt_cb_data_t*)的含义

表示定义一个类型
dwt\u cb\u t
,该类型是指向函数的指针,该函数返回
void
,并接受一个类型为
const dwt\u cb\u data\u t*
的参数

如果你有一个函数,比如

 void func(const dwt_cb_data_t * data); // func accepts argument type 
                                           const dwt_cb_data_t * , returns void 
你可以写

 dwt_cb_t f = func;

为了更清楚,我们假设有一个函数

void f( int *x );
函数的类型是
void(int*)

可以为该函数类型引入别名,如

typedef void Func( int * );
并使用别名声明(但不定义)函数

这是一个演示程序

#include <stdio.h>

typedef void Func( int * );

Func f;

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    f( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}
#include <stdio.h>

typedef void Func( int * );

Func f;

typedef Func *FuncPtr;

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    FuncPtr fp = f;

    fp( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}
#include <iostream>

template <typename T>
using FuncPtr = void ( * )( T * );

template <typename T>
void f( T *t )
{
    ++*t;
}

int main() 
{
    FuncPtr<int>  fp1 = f;
    FuncPtr<char> fp2 = f;
    
    int x = 0;
    char c = 'A';
    
    fp1( &x );
    fp2( &c );
    
    std::cout << "x = " << x << '\n';
    std::cout << "c = " << c << '\n';
    
    return 0;
}
请注意,您也可以通过以下方式声明函数别名

void typedef Func( int * );
现在,让我们为指向函数类型的函数指针声明一个别名

#include <stdio.h>

typedef void Func( int * );

Func f;

typedef void ( *FuncPtr )( int * );

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    FuncPtr fp = f;

    fp( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}
你可以写得很简单

typedef void Func( int * );

这是一个演示程序

#include <stdio.h>

typedef void Func( int * );

Func f;

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    f( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}
#include <stdio.h>

typedef void Func( int * );

Func f;

typedef Func *FuncPtr;

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    FuncPtr fp = f;

    fp( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}
#include <iostream>

template <typename T>
using FuncPtr = void ( * )( T * );

template <typename T>
void f( T *t )
{
    ++*t;
}

int main() 
{
    FuncPtr<int>  fp1 = f;
    FuncPtr<char> fp2 = f;
    
    int x = 0;
    char c = 'A';
    
    fp1( &x );
    fp2( &c );
    
    std::cout << "x = " << x << '\n';
    std::cout << "c = " << c << '\n';
    
    return 0;
}
唯一的区别是参数的类型。在第一个声明中,参数的类型是
int*
,而在第二个声明中,参数的类型是
const dwt\u cb\u data\u t*

C++中与TyPuff(s)一起,可以使用声明作为例如< /P>

using dwt_cb_t = void (*)(const dwt_cb_data_t *);

使用C++中的别名声明更为灵活,因为您可以使用模板别名声明。

这是一个演示程序

#include <stdio.h>

typedef void Func( int * );

Func f;

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    f( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}
#include <stdio.h>

typedef void Func( int * );

Func f;

typedef Func *FuncPtr;

int main(void) 
{
    int x = 0;
    
    printf( "x = %d\n", x );
    
    FuncPtr fp = f;

    fp( &x );

    printf( "x = %d\n", x );
    
    return 0;
}

void f( int *x )
{
    ++*x;
}
#include <iostream>

template <typename T>
using FuncPtr = void ( * )( T * );

template <typename T>
void f( T *t )
{
    ++*t;
}

int main() 
{
    FuncPtr<int>  fp1 = f;
    FuncPtr<char> fp2 = f;
    
    int x = 0;
    char c = 'A';
    
    fp1( &x );
    fp2( &c );
    
    std::cout << "x = " << x << '\n';
    std::cout << "c = " << c << '\n';
    
    return 0;
}
这仅仅意味着
dwt\u cb\u data\u t
是一种数据类型,
dwt\u cb\u data\u t*
不过是指向它的指针

函数原型只是缺少它的形式参数名,这很好。 这方面的一个降级版本是:

int myFunc(int, char*);  // no formal parameter name, just its datatype
然后,在它的实现中,您将看到

int myFunc(int var1, char* var_ptr){
//function body 
}

不使用参数名称更容易阅读。

因为
const*dwt\u cb\u data\u t
不是参数的有效声明?为什么您认为这应该等同于常量dwt\u cb\u data\u t*
?typedef从不定义变量,而是定义类型。关于参数的含义,您是对的,但我不明白您为什么认为
const*dwt\u cb\u data\t
是合法语法。指向
T
的指针总是被写入
T*
而不是
*T
@UnholySheep@john我忽略了一个事实,即变量类型是
const dwt\u cb\u data\T
,而不仅仅是
const
。现在将
*
放在最末尾是有意义的,因为
const dwt\u cb\u data\u t
是实际类型,并且省略了变量;现在它变得更有意义了