C 语言杂谈(一):typedef 在函数指针上的使用

我们都知道在 C 语言中,typedef 的作用是给已有的类型重新定义一个新的名字,今天在这里我们主要探讨一下使用 typedef 来简化函数指针的用法。


Example print

首先我们来看一个例子:

#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_t 的函数指针类型,如下:

typedef void (*printer_t)(int);

这个 typedef 创建了一个名叫 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 在处理函数指针时可以有一个更简单的语法形式,当使用环境很复杂时,这种 typedef 定义函数指针的方式会更加显眼。

接下来我们可以对比一下当我们想把一个函数指针当做一个参数时,使用 typedef 和不使用的区别:

  • 不使用 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 后程序更简洁了,我们这样可以直接简便的返回函数指针。

Example signal

我们还可以看一个经典的例子。这个例子来自于 <signal.h>,其中的声明如下:

void (*signal(int sig, void (*func)(int)))(int);

这是一个带有两个参数的函数:一个 int 和一个指向以 int 作为参数并且不返回任何内容的函数的指针,然后返回一个指向函数的指针,如同第二个参数。

如果我们将类型 SigCatcher 定义为函数类型指针的别名:

typedef void (*SigCatcher)(int);

then we could declare signal() using:

SigCatcher signal(int sig, SigCatcher func);

这样的话更方便我们理解。signal 函数采用两个参数,即 int 和 SigCatcher,并返回 SigCatcher:其中SigCatcher 是指向具有 int 参数且不返回任何内容的函数的指针。

注:尽管使用 typedef 名称来指向函数类型的指针使工作变得更轻松,但也可能导致其他人在以后维护您的代码时感到困惑,因此请谨慎使用并提供适当的文档。

发布了53 篇原创文章 · 获赞 21 · 访问量 8368

猜你喜欢

转载自blog.csdn.net/zztiger123/article/details/103541060