C++ 了解如何使用带有指针的typedef void函数作为参数
我试图理解一个用C语言编写的固件,它驱动一个超宽带连接芯片 固件大量使用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 ; 我知道这
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
是实际类型,并且省略了变量;现在它变得更有意义了