typedef void (*print_type) (const char*);

typedef void (*print_type) (const char*);

在探索一些代码时,我在头文件中发现了以下内容:

typedef void (*print_type) (const char*);

这行是什么意思?我知道 typedef 用于使特定词(在我们的例子中是 *print_type)来表示特定的类型(在我们的例子中是 const char*)。

但我的问题是为什么我们必须使用 void?

这是什么?

typedef void (*print_type) (const char*);

typedef 告诉编译器数据类型 print_type 是一个指向接受 const char* 作为参数但不 return 值的函数的指针。

...而且它与 DLL 无关


函数指针

我们声明一个函数如下:

ret-type identifier(parameters)

int f(double x)

鉴于对于声明为int a的东西,指向它的指针被声明为int *a(在数据类型后加一个*),自然会有人想出办法声明一个函数指针如下:

int *f(double);

这里有一个陷阱。这实际上是一个函数的声明,它接受一个 double 作为参数并且 return 是一个 int*.

我们需要明确地告诉编译器它不是一个函数 returning 一个指针;相反,它是一个指向函数的指针。我们通过在 *f.

周围放置括号(括号具有更高的优先级)来做到这一点

int (*f)(double);

再举个例子:

int* myfunc(int a[], char b);

要声明指向具有上述签名的函数的函数指针数组,我们这样写:

int* (*ptr[])(int[], char);

有一个叫做 Spiral Rule 的技巧,它在找出什么是复杂的数据类型时非常有用。


使用类型定义

函数指针会使事情变得相当复杂。为了保持代码的可读性和整洁性,我们更喜欢使用 typedef 为函数指针类型提供单个符号类型名称。

typedef int (*ptrFunc_t)(int, char);

这允许您声明一个指向接受 intchar 作为参数以及 return 和 int 的函数的指针,如下所示: ptrFunc_t myptr;

它正在创建指向函数的指针的类型定义,该函数采用 const char 指针参数并且不返回任何内容。

此类 typedef 在用于动态加载的库中很常见(即 LoadLibrary 等),因为您必须将函数指针加载到实际函数,而不是像 load 那样直接使用函数名-时间链接。

这个:

void foo(const char*);

foo 声明为一个接受 const char* 参数和 returns void 的函数(即,它不 return 任何东西)。 (必须在某处定义它才能调用它。)

这个:

void (*bar)(const char*);

定义bar为指针对象。它是指向与上面 foo 具有相同类型的函数的指针。

通过添加 typedef 关键字,这:

typedef void (*print_type)(const char*);

定义print_type,不是作为函数指针类型的对象,而是作为函数指针类型的别名。