如何读懂 C 语言复杂的声明

作者能力有限, 如果您在阅读过程中发现任何错误, 还请您务必联系本人,指出错误, 避免后来读者再学习错误的知识.谢谢!

参考<<C专家编程>>

废话

虽说 C 语言相比于其他更高级的语言来讲,有着非常精简的语法结构,对于初学者非常的友好。 然而,使用 C 语言依然可以可以写出非常难懂的代码, 也许这也就是精简的语法所必须面对的缺点吧。 笔者就经常一些复杂的声明,看得一头雾水,这里就分享一个帮你读懂这些声明的技巧吧。

自测

先自己测试一下, 如下的声明你能读懂吗?

void (*signal(int sig, void(*func)(int))) (int); // 当然,比这个复杂的声明还有很多...

技巧

要读懂一个声明,必须要懂得其中的优先级规则

优先级规则如下:

A: 声明从它的名字开始读起, 然后按照优先级顺序依次读取
B: 优先级从高到低依次是:
    B.1: 声明中括号括起来的部分
    B.2: 后缀操作符:
        括号 () 表示这是一个函数
        方括号 [] 表示这是一个数组
    B.3: 前缀操作符: 星号 * 表示 “指向…的指针”
C: 如果 const 和 ( 或 ) volatile 关键字的后边紧跟类型说明符(如 long 等), 那么它作用于类型说明符。
    在其他情况下,const 和 ( 或 ) volatile 关键字作用于它左边紧邻的指针星号

示例

例1:

char * const *(*next)();
  1. 首先,变量名为 next
  2. 这里优先级最高的就是括号了。 括号中 \*next 为一个整体,具有最高优先级。 由 B.3 可以得知 "next 是一个指向 ... 的指针"
  3. 除括号外,最高优先级为后缀操作符,这里有括号紧跟着 (\*next)。 由 B.2 可知 "next 是一个函数指针,被指向的函数没有输入参数, 返回值还需要进一步分析"
  4. 接下来最高优先级的结构应该是 (\*next) 的前缀操作符------星号\*。 这里需要进一步分析更前面的结构
  5. 最后,我们应该将 "char \* const \*" 解释为一个结构。 由 C 可知它的意义为 "指向字符的常量指针"

总结,这个声明的含义为: next 是一个函数指针, 该函数指针指向的函数无输入参数且返回一个指向字符的常量指针

例2:

void (*signal(int sig, void(*func)(int))) (int); // 当然,比这个复杂的声明还有很多...

这就是我们前面提到的声明,我们来试着分析一下。

  1. 首先,变量名是 signal
  2. 其次就是括号了。 括号中 (\*signal(int sig, void(\*func)(int))) 为一个整体。 signal 前有星号,它的意义是 "signal 是一个指向 ... 的指针"
    1. 接着 signal 后有括号,标志着 signal 是一个函数指针,它有一些复杂的参数和不易分析的返回值。
    2. signal 函数指针指向的函数具有两个参数, 一个是 int sig, 一个是 void(\*func)(int)。
    3. void(\*func)(int) 表示一个函数指针,被指向的函数接收一个 int 参数返回值为 void。
  3. 接着就是最后的那个 (int), 它和最前面的 void 一起表示 signal 指向的函数返回一个函数指针。 后者所指向的函数接受一个 int 参数并返回 void.

总结, 这个声明的含义为: signal 是一个函数指针,它返回一个接收一个 int 参数并返回 void 的函数指针。而 signal 函数接收一个 int 和一个函数指针作为参数。 第二个参数所指向的函数接收一个 int 参数并返回 void

哈哈,其实我想说,即使我们分析清楚了这个声明的意义,它依旧像魔鬼一样难以理解。

欢迎交流任何想法.

End…

如何读懂 C 语言复杂的声明相关推荐

  1. [一篇读懂]C语言五讲:指针

    [一篇读懂]C语言五讲:指针 1. 指针的本质(间接访问原理) 1 指针的定义 2 取地址操作符与取值操作符,指针本质 2. 指针的==传递==使用场景 1 指针的传递 [例1.1]指针的传递使用场景 ...

  2. 语言编程思维陈萌_这本书告诉你,计算机为何能读懂人类语言,编程思维让你更聪明...

    在这个互联网时代,我们出门购物.拍照.打电话.浏览信息,只需要带上一部智能手机就可以了.如果在20年前,要实现这些功能,需要带一大堆东西.如今,我们口袋里的这台计算机,和50年前送宇航员上月球的那台计 ...

  3. centos 删除文件夹_手机文件夹是英文,占空间还不敢乱删?花一分钟读懂手机语言...

    不少人肯定发现,自己的手机里面有一些莫名其妙的文件夹,占据内存空间.且占据很大,想删除,但全部是由英文标注,不知道从何删起. 今天小兰就来帮助大家决绝这么问题,一分钟教你读懂这些手机语言,快速清理手机 ...

  4. html语言代码大全,菜鸟快速读懂HTML语言_html

    html语言是网页制作的基础,是初学者必学的内容.虽然现在有许多所见即所得的网页制作工具,但是说到底,还是有必要了解一些HTML的语法.这样,您可以更精确的控制页面的排版,可以实现更多的功能.HTML ...

  5. 5分钟读懂c语言编译步骤

    编写的C/C++代码,通过ide生成一个可执行文件,我们只需要点一下编译就可以实现,但实际上,我们点下编译之后,编译器经历了很多步骤,才最终生成了我们需要的软件. 在早期没有ide或者在Linux上我 ...

  6. 一文读懂Java语言方法的重写(覆盖、Override)

    很多初学Java语言的小伙伴,在学到"面向对象"这块内容的时候,都会学到的一个概念,那就是"方法的重写".重写又叫覆盖,英文名为"Override&q ...

  7. c语言位向量机伞_一文读懂C语言精华-指针变量和指向指针的指针

    1978年贝尔实验室正式发表C语言,受到众多IT从业者的热捧,即使41年过去了,C语言仍然牢牢占据最受欢迎编程语言前二的位置,许多人的程序开发之路也是从C语言开始的. 编程语言受欢迎排名 C语言简洁紧 ...

  8. 读懂python语言_一文读懂python反射机制

    反射 反射机制就是在运行时,动态的确定对象的类型,并可以通过字符串调用对象属性.方法.导入模块,是一种基于字符串的事件驱动.解释型语言:程序不需要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译 ...

  9. 计算机是怎么读懂C语言的?

    文章目录 前言 程序环境 翻译环境 翻译环境分类 编译 预处理 预处理符号 预定义符号 #define #undef 命令行定义 条件编译 文件包含 头文件包含查找规则 嵌套文件包含 其他预处理指令 ...

最新文章

  1. 语音识别(ASR)评估指标-WER(字错误率)和SER(句错误率)
  2. java字符串类型常量拼接与变量拼接的区别
  3. 打印机打印网页不清晰_打印机墨水:你不知道的秘密
  4. 干货:如何在前端统计用户访问来源?
  5. .NET 动态脚本语言Script.NET系列文章汇总 非常精彩的应用举例
  6. cisco packet tracer路由器配置_【干货】思科交换机路由器怎么配置密码?
  7. mysql 1z0_MySQL 8 OCP(1Z0-908)认证考试题库原题(第12题)
  8. Droopy v0.2 靶机渗透(drupal 7.3版本漏洞)
  9. ScreenToGif
  10. OSPF邻居关系建立故障排除
  11. M システム - 笔记(4) -- 客户合作胜过合同谈判
  12. 教师公开课卡通动态通用PPT模板
  13. docker中各ID之间的关系和计算(二)-layerID-diffID-chainID-cacheID的计算
  14. metasploit基础命令介绍
  15. [Linux] USB-Storage驱动 源码阅读笔记(一)
  16. oss2罗列所有文件
  17. HEVC中级别(Level)计算
  18. Java 第三方sdk服务_文档中心 | QuickSDK——专业的手游第三方SDK接入服务平台,渠道SDK聚合,广告跟踪,客服,登录充值SDK...
  19. elementui确认消息区分取消和关闭按钮
  20. 正版Xshell+Xftp免费使用,你还在找破解版吗

热门文章

  1. php 文件加载方式
  2. js 简单弹框toast
  3. C语言 - strcpy和strncpy的编程实现及总结
  4. 安装、卸载、查看软件时常用的命令
  5. OpenCV图像或视频显示在VC对话框中的方法
  6. centos php日志分析,记录一下CentOS7安装GoAccess日志分析工具
  7. 某中学要对学校运动会进行计算机管理,2020年新编高职入学考试适应性试卷信息技术试卷定稿名师精品资料....
  8. python 去除不可见字符\x00
  9. python创建长度为n的数组_在Python中建立N维数组并赋初值
  10. python访问网页变量_Python 如何访问外围作用域中的变量