zoukankan      html  css  js  c++  java
  • C语言拾遗(三):分析C语言声明

    C语言非常难理解的是指针,可是比指针还难理解的是什么呢?我想莫非是C语言的声明了。

    比如看下一个系统调用signal()的函数声明:

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

    是不是很晕乎?从哪个标识符开始读,singnal?sig?还是int?往左读还是往右读?

    其实理解了C语言声明的优先级规则就好办了。

    A 声明从它的名字开始读取,然后按照优先级的顺序依次读取。

    B 优先级从高到低:

      B.1标识符被小括号扩起来的那部分

      B.2后缀操作符:( )表示这是一个函数,[]表示这是一个数组。

      B.3前缀操作符:星号*表示“指向...的指针”

    C  如果const和(或)volatile关键字的后面紧跟类型说明符(int,long等)那么它作用于类型说明符,否则往前看,关键字作用于左边紧邻的类型符或指针星号。

    好了,理论用于实践,来看一个例子。

    char * const *(*next)();

    首先,读到next,往左前缀是*,表示next是一个指针,再后面(),说明next指向函数,函数的返回值是指针,指针指向char*const,表示指向字符类型的常量指针(const作用于指针)。

    再来看一个

    char *(* c[10])(int **p)

    分析:c是一个数组,数组的元素个数为10,元素是指针,这些指针指向函数,函数的参数是int **p(指向指针的指针),函数的返回类型是char *(字符指针)。

    好了,再回头看singal()的声明:

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

    分析:signal是一个函数,signal函数的参数,一个是int sig,还有一个是 void(*func)(int), 表示一个函数指针,指向一个参数为int,返回void的函数

    signal函数的返回也是一个函数指针,也是指向一个一个参数为int,返回void的函数。

    这样就比较清楚了。像庖丁解牛一样。这时你发现了没有signal还是挺绕,不够简洁,看分析中蓝色字体,是不是几乎一样?

    试试typedef吧。

    typedef void (*ptr_to_func)(int);

    为一个类型取了一个新名字,该类型是指向一个参数为int,返回void的函数指针。这样signal就可以这么声明了:

    ptr_to_func singal(int sig, ptr_to_func func);

    是不是很简洁,当然,如果不考虑可读性,还可以更简洁(不推荐啊)

    typedef void (*A)(int);
    A singal(int sig, A func);

    Note: typedef只是给某种类型取一个新名字,并不是声明一种新的类型。

    ---End---

  • 相关阅读:
    Java面试——VUE2&VUE3概览
    Golang 面试笔录
    数据科学完整流程概述
    周志华 机器学习 西瓜书 主要符号表
    数据分析师的发展方向?
    404 GET /nbextensions/jupyter-js-widgets/extension.js
    如何使用Conda源快速安装PyTorch?
    美化React组件之CSS Modules
    react如何全局配置sass
    nuxt api缓存,组件缓存,页面缓存
  • 原文地址:https://www.cnblogs.com/RandyXu/p/2979351.html
Copyright © 2011-2022 走看看