zoukankan      html  css  js  c++  java
  • 《征服 C 指针》笔记6:练习——挑战那些复杂的声明

    应该是小试牛刀的时候了。

    在 ANSI C 的标准库中,有一个 atexit()函数。如果使用这个函数,当程序正常结束的时候,可以回调一个指定的函数。

    atexit()的原型定义如下:

    int atexit(void (*func)(void));

    1、首先着眼于标识符。

    int atexit(void (*func)(void));

    英语的表达为:

    atexit is

    2、解释用于函数的()。

    int atexit(void (*func)(void));

    英语的表达为:

    atexit is function() returning

    3、函数的参数部分比较复杂,所以先解析这部分。同样地, 先着眼于标识符。

    int atexit(void (*func)(void));

    英语的表达为:

    atexit is function(func is) returning

    4、因为有括号, 所以这里解释*。

    int atexit(void (*func)(void));

    英语的表达为:

    atexit is function(func is pointer to) returning

    5、解释用于函数的()。这里的参数还是比较简单的, 是 void(无参数) 。

    int atexit(void (*func)(void));

    英语的表达为:

    atexit is function(func is pointer to function (void) returning) returning

    6、解释类型指定符 void。这样就结束了 atexit 的参数部分的解释。

    int atexit(void (*func)(void));

    英语的表达为:

    atexit is function(func is pointer to function(void) returning void) returning

    7、解释数据类型修饰符 int。

    int atexit(void (*func)(void));

    英语的表达为:

    atexit is function (func is pointer to function (void) returning void) returning int

    8、翻译成中文……

    atexit 是返回 int 的函数(参数是,指向返回 void 没有参数的函数的指针) 。

    下面是一个更加复杂的例子。

    标准库中有一个 signal()函数,它的原型声明如下,

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

    1、首先着眼于标识符。

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

    英语的表达为:

    signal is

    2、相比*, ()的优先顺序更高,所以先解释这部分。

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

    英语的表达为:

    signal is function() returning

    3、解释参数部分。这里有两个参数,第一参数是 int sig。

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

    英语的表达为:

    signal is function(sig is int,) returning

    4、着眼另外一个参数。

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

    英语的表达为:

    signal is function(sig is int, func is) returning

    5、因为有括号, 所以这里解释*。

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

    英语的表达为:

    signal is function(sig is int, func is pointer to) returning

    6、解释表示函数的(), 参数为 int。

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

    英语的表达为:

    signal is function(sig is int, func is pointer to function(int) returning) returning

    7、解释数据类型修饰符 void。

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

    英语的表达为:

    signal is function(sig is int, func is pointer to function(int) returning void) returning

    8、参数部分已经解释结束。接着因为有括号,所以这里解释*。

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

    英语的表达为:

    signal is function(sig is int, func is pointer to function(int) returning void) returning pointer to

    9、解释表示函数的(),参数为 int。

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

    英语的表达为:

    signal is function(sig is int, func is pointer to function(int) returning void) returning pointer to function(int) returning

    10、最后,添上 void。

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

    英语的表达为:

    signal is function(sig is int, func is pointer to function(int) returning void) returning pointer to function(int) returning void

    11、翻译成中文……

    signal 是返回“指向返回 void,参数为 int 的函数的指针”的函数,它有两个参数, 一个是 int,另一个是“指向返回 void 参数为 int 的函数的指针”。

    如果能读懂这种难度的声明,我想应该不会再有什么让你畏惧的 C 声明了。

    下面的说明可能会让你对 C 语言感到更加不快。

    signal()是用于注册信号处理(当中断发生时被调用的函数)的函数。此函数的返回值是之前注册的处理当前信号中断的函数。

    也就是说,其中的一个参数和返回值,它们都是相同的类型——指向信号处理函数的指针。在一般的语言中,同样的表现模式出现两次并不会让你感到不适,但是解释 C 语言声明的过程是“一会儿向左一会儿向右”,因此,表示返回值的部分散落了在左右两侧。

    此时,运用 typedef 可以让声明变得格外得简洁。

    /*摘录于FreeBSD 的man page /
    typedef void(sig_t)(int);
    sig_t signal(int sig, sig_t func);

    sig_t 代表“指向信号处理函数的指针”这个类型。

    延伸阅读:

    《征服 C 指针》摘录1:什么是空指针?区分 NULL、0 和 ''

    《征服 C 指针》摘录2:C变量的 作用域 和 生命周期(存储期)

    《征服 C 指针》摘录3:数组 与 指针

    《征服 C 指针》摘录4:函数 与 指针

    《征服 C 指针》摘录5:函数形参 和 空的下标运算符[]

    《征服 C 指针》摘录6:解读 C 的声明

    《征服 C 指针》摘录7:练习——挑战那些复杂的声明

  • 相关阅读:
    打jar包的命令
    WebServiceWSDLWeb
    linux命令之检测端口是否启用
    mybatis generator 插件安装及使用
    Mybatis 中一对多,多对一的配置
    大数据时代日志分析平台ELK的搭建
    关于RestfulAPI与SpringMVC之间的传值
    linux快速清空文件内容
    Linux之第一个shell命令
    Linux之yum
  • 原文地址:https://www.cnblogs.com/52php/p/5683331.html
Copyright © 2011-2022 走看看