了解如何使用指针作为参数的 typedef void 函数
Understanding how to use typedef void function with pointers as params
我正在尝试了解一个用 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_local_data_t 并包含一些变量,包括这个奇怪的 dwt_cb_t类型。
在.h文件中dwt_cb_t命名为
// Call-back type for all events
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
其中dwt_cb_data_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_cb_t 指向一个接收常量结构 dwt_cb_data_t[=19= 作为输入的函数]
我不知道我的推理是否正确,因为我不明白为什么dwt_cb_data_t的末尾有一个*
。是不是说函数的输入就是结构体的指针呢?在这种情况下,为什么不写 typedef void (*dwt_cb_t)(const *dwt_cb_data_t);
呢?
别再考虑 typedef void
了。您正在以这种方式截断定义。
定义的符号是 dwt_cb_t
并且是类型 void (*)(const dwt_cb_data_t *)
的别名,它是:指向采用 const dwt_cb_data_t *
参数并返回 void
的函数的指针。
在 C++ 中你会这样写:
using dwt_cb_t = void (*)(const dwt_cb_data_t *);
这就清楚多了。
Does it mean that the input of the function is the pointer of the
structure?
是的,说明函数的参数是指向struct的指针。
In this case, why don't write
typedef void (*dwt_cb_t)(const*dwt_cb_data_t);
instead?
这是因为指针符号*
必须放在标识符之前,而不是标识符类型之前。
在这种情况下,您可以看到函数如下:
typedef void (*dwt_cb_t)(const dwt_cb_data_t *var);
唯一就是省略了var
Now, I'm trying to understand the meaning of typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
意味着,定义一个类型dwt_cb_t
,它是一个指向returnsvoid
函数的指针,并接受一个const dwt_cb_data_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;
}
程序输出为
x = 0
x = 1
注意你也可以通过以下方式声明函数别名
void typedef Func( int * );
现在让我们为指向函数类型的函数指针声明一个别名。
你可以简单地写
typedef void Func( int * );
和
typedef Func *FuncPtr;
这是一个演示程序。
#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 <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 ( *FuncPtr )( int * );
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
唯一的区别是参数的类型。在第一个声明中参数的类型是 int *
而在第二个声明中参数的类型是 const dwt_cb_data_t *
.
在 C++ 中,您可以将 using 声明与 typedef(s) 一起使用,例如
using dwt_cb_t = void (*)(const dwt_cb_data_t *);
在 C++ 中使用别名声明更加灵活,因为您可以使用模板别名声明。
这是一个演示程序。
#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;
}
程序输出为
x = 1
c = B
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
这只是意味着 dwt_cb_data_t
是一种数据类型,而 dwt_cb_data_t *
只不过是指向它的指针。
函数原型只是缺少它的正式参数名称,这很好。
这个的降级版本是:
int myFunc(int, char*); // no formal parameter name, just its datatype
稍后,在它的实现中,您会看到
int myFunc(int var1, char* var_ptr){
//function body
}
只是没有参数名更容易阅读。
我正在尝试了解一个用 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_local_data_t 并包含一些变量,包括这个奇怪的 dwt_cb_t类型。
在.h文件中dwt_cb_t命名为
// Call-back type for all events
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
其中dwt_cb_data_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_cb_t 指向一个接收常量结构 dwt_cb_data_t[=19= 作为输入的函数]
我不知道我的推理是否正确,因为我不明白为什么dwt_cb_data_t的末尾有一个*
。是不是说函数的输入就是结构体的指针呢?在这种情况下,为什么不写 typedef void (*dwt_cb_t)(const *dwt_cb_data_t);
呢?
别再考虑 typedef void
了。您正在以这种方式截断定义。
定义的符号是 dwt_cb_t
并且是类型 void (*)(const dwt_cb_data_t *)
的别名,它是:指向采用 const dwt_cb_data_t *
参数并返回 void
的函数的指针。
在 C++ 中你会这样写:
using dwt_cb_t = void (*)(const dwt_cb_data_t *);
这就清楚多了。
Does it mean that the input of the function is the pointer of the structure?
是的,说明函数的参数是指向struct的指针。
In this case, why don't write
typedef void (*dwt_cb_t)(const*dwt_cb_data_t);
instead?
这是因为指针符号*
必须放在标识符之前,而不是标识符类型之前。
在这种情况下,您可以看到函数如下:
typedef void (*dwt_cb_t)(const dwt_cb_data_t *var);
唯一就是省略了var
Now, I'm trying to understand the meaning of
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
意味着,定义一个类型dwt_cb_t
,它是一个指向returnsvoid
函数的指针,并接受一个const dwt_cb_data_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;
}
程序输出为
x = 0
x = 1
注意你也可以通过以下方式声明函数别名
void typedef Func( int * );
现在让我们为指向函数类型的函数指针声明一个别名。
你可以简单地写
typedef void Func( int * );
和
typedef Func *FuncPtr;
这是一个演示程序。
#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 <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 ( *FuncPtr )( int * );
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
唯一的区别是参数的类型。在第一个声明中参数的类型是 int *
而在第二个声明中参数的类型是 const dwt_cb_data_t *
.
在 C++ 中,您可以将 using 声明与 typedef(s) 一起使用,例如
using dwt_cb_t = void (*)(const dwt_cb_data_t *);
在 C++ 中使用别名声明更加灵活,因为您可以使用模板别名声明。
这是一个演示程序。
#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;
}
程序输出为
x = 1
c = B
typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
这只是意味着 dwt_cb_data_t
是一种数据类型,而 dwt_cb_data_t *
只不过是指向它的指针。
函数原型只是缺少它的正式参数名称,这很好。 这个的降级版本是:
int myFunc(int, char*); // no formal parameter name, just its datatype
稍后,在它的实现中,您会看到
int myFunc(int var1, char* var_ptr){
//function body
}
只是没有参数名更容易阅读。