函数指针的 Typedef
我们可以使用 typedef
来简化函数指针的使用。想象一下,我们有一些函数,都具有相同的签名,使用他们的参数以不同的方式打印出来:
#include<stdio.h>
void print_to_n(int n)
{
for (int i = 1; i <= n; ++i)
printf("%d\n", i);
}
void print_n(int n)
{
printf("%d\n, n);
}
现在我们可以使用 typedef
来创建一个名为 printer 的命名函数指针类型:
typedef void (*printer_t)(int);
这将创建一个名为 printer_t
的类型,用于指向函数的指针,该函数接受单个 int
参数并且不返回任何内容,这与我们上面的函数的签名相匹配。要使用它,我们创建一个创建类型的变量,并为其指定一个有问题的函数:
printer_t p = &print_to_n;
void (*p)(int) = &print_to_n; // This would be required without the type
然后调用函数指针变量指向的函数:
p(5); // Prints 1 2 3 4 5 on separate lines
(*p)(5); // So does this
因此,typedef
在处理函数指针时允许更简单的语法。当函数指针用于更复杂的情况时,例如函数的参数,这一点就变得更加明显。
如果你使用的函数将函数指针作为参数而未定义函数指针类型,则函数定义将是,
void foo (void (*printer)(int), int y){
//code
printer(y);
//code
}
但是,使用 typedef
它是:
void foo (printer_t printer, int y){
//code
printer(y);
//code
}
同样,函数可以返回函数指针,并且再次使用 typedef
可以使语法更简单。
一个典型的例子是 <signal.h>
的 signal
功能。它的声明(来自 C 标准)是:
void (*signal(int sig, void (*func)(int)))(int);
这是一个带有两个参数的函数 - 一个 int
和一个指向函数的指针,该函数将 int
作为参数并且不返回任何内容 - 并返回一个指向函数的指针,就像它的第二个参数一样。
如果我们将类型 SigCatcher
定义为指向函数类型的指针的别名:
typedef void (*SigCatcher)(int);
然后我们可以使用以下方式声明 signal()
:
SigCatcher signal(int sig, SigCatcher func);
总的来说,这更容易理解(即使 C 标准没有选择定义类型来完成工作)。signal
函数有两个参数,一个 int
和一个 SigCatcher
,它返回一个 SigCatcher
- 其中 SigCatcher
是一个指向一个函数的指针,该函数接受一个 int
参数并且什么都不返回。
虽然使用 typedef
名称作为指向函数类型的指针可以使生活更轻松,但它也可能导致后来维护代码的其他人感到困惑,因此请谨慎使用并使用适当的文档。另请参见功能指针 。