概述

  在很多情况下,尤其是读别人所写代码的时候,对C语言声明的理解能力变得非常重要,而C语言本身的凝练简约也使得C语言的声明常常会令人感到非常困惑,因此,在这里我用一篇的内容来集中阐述一下这个问题。

  问题:声明与函数

  有一段程序存储在起始地址为0的一段内存上,如果我们想要调用这段程序,请问该如何去做?

  答案

  答案是(*(void (*)( ) )0)( )。看起来确实令人头大,那好,让我们知难而上,从两个不同的途径来详细分析这个问题。

  答案分析:从尾到头

  首先,最基本的函数声明:void function (paramList);

  最基本的函数调用:function(paramList);

  鉴于问题中的函数没有参数,函数调用可简化为 function();

  其次,根据问题描述,可以知道0是这个函数的入口地址,也就是说,0是一个函数的指针。使用函数指针的函数声明形式是:void (*pFunction)(),相应的调用形式是: (*pFunction)(),则问题中的函数调用可以写作:(*0)( )。

  第三,大家知道,函数指针变量不能是一个常数,因此上式中的0必须要被转化为函数指针。

  我们先来研究一下,对于使用函数指针的函数:比如void (*pFunction)( ),函数指针变量的原型是什么? 这个问题很简单,pFunction函数指针原型是( void (*)( ) ),即去掉变量名,清晰起见,整个加上()号。

  所以将0强制转换为一个返回值为void,参数为空的函数指针如下:( void (*)( ) )。

  OK,结合2)和3)的分析,结果出来了,那就是:(*(void (*)( ) )0)( ) 。

  答案分析:从头到尾理解答案

  (void (*)( )) ,是一个返回值为void,参数为空的函数指针原型。
  (void (*)( ))0,把0转变成一个返回值为void,参数为空的函数指针,指针指向的地址为0.
  *(void (*)( ))0,前面加上*表示整个是一个返回值为void的函数的名字
  (*(void (*)( ))0)( ),这当然就是一个函数了。

  我们可以使用typedef清晰声明如下

  typedef void (*pFun)( );

  这样函数变为 (*(pFun)0 )( );

  问题:三个声明的分析

  对声明进行分析,最根本的方法还是类比替换法,从那些最基本的声明上进行类比,简化,从而进行理解,下面通过分析三个例子,来具体阐述如何使用这种方法。

#1:int* (*a[5])(int, char*);

  首先看到标识符名a,“[]”优先级大于“*”,a与“[5]”先结合。所以a是一个数组,这个数组有5个元素,每一个元素都是一个指针,指针指向“(int, char*)”,很明显,指向的是一个函数,这个函数参数是“int, char*”,返回值是“int*”。OK,结束了一个。:)

#2:void (*b[10]) (void (*)());

   b是一个数组,这个数组有10个元素,每一个元素都是一个指针,指针指向一个函数,函数参数是“void (*)()”【注10】,返回值是“void”。完毕!

  注意:这个参数又是一个指针,指向一个函数,函数参数为空,返回值是“void”。

#3. doube(*)() (*pa)[9];

   pa是一个指针,指针指向一个数组,这个数组有9个元素,每一个元素都是“doube(*)()”(也即一个函数指针,指向一个函数,这个函数的参数为空,返回值是“double”)。

水滴石穿C语言之声明的语法相关推荐

  1. 理解C语言中指针的声明以及复杂声明的语法

    昨天刚把<C程序设计语言>中"指针与数组"章节读完,终于把心中的疑惑彻底解开了.现在记录下我对指针声明的理解,顺便说下如何在C语言中创建复杂声明以及读懂复杂声明. 本文 ...

  2. 怎样在c语言中声明list这一变量,C语言变量赋值语句的语法解析算法实现

    本篇文章是java开发编译器系列课程的文档,有兴趣的朋友可关注网易云课堂的视频内容: 自己动手用java开发编译器 经过一系列的算法摸索后,我们终于要进入 C 语言编译器开发的进程,这一节,我们的目的 ...

  3. 《C专家编程》第三章——分析C语言的声明

    前面一章我们已经说过C语言存在的一些问题和它晦涩的地方,让我们对这门神奇的语言有了更深的了解.现在这一章则集中精力来讨论C语言的声明,分为三块,首先是说明C语言声明晦涩难懂的原因和声明是如何形成的,其 ...

  4. c语言函数声明定义参数命名,C语言函数声明与定义

    C语言函数声明与定义教程 在 C语言函数声明与定义 语法 type funcName(paramType1 param1, paramType2 param2){ // 执行语句... return ...

  5. 编译原理课程作业-Cminus语言的词法及语法分析器实现

    Cminus Compiler 编译原理课程作业-Cminus语言的词法及语法分析器实现 设计思想 词法分析 使用确定有限态自动机(DFA)实现与Lex自动分析两种方式实现. 语法分析 使用递归下降方 ...

  6. 从D语言看C++ Template语法

    从D语言看C++ Template语法 许式伟 (版权声明) 2007-5-2 D语言是一门新兴的语言,它试图结合C/C++性能上的高效,同时又象Python.Ruby等"现代"语 ...

  7. 如何理解C语言的声明

    在K&R中,作者承认"C语言声明的语法有时会带来严重的问题".C语言声明的语法对于编译器来说并不是什么大不了的事,但对于一般的程序员,它却会成为障碍. 在阅读较为复杂的代码 ...

  8. Scala语言学习一——基础语法

    什么是 Scala Scala 是一种多范式的编程语言, 其设计的初衷是要集成面向对象编程和函数式编程的各种 特 性 . Scala 运 行 于 Java 平 台 (Java 虚 拟 机 ) , 并 ...

  9. c语言常用的格式声明,c语言函数声明格式是什么

    c语言函数声明格式是什么 c语言函数声明格式是"函数类型 函数名称(参数列表);".在函数声明中的参数列表中,不需要给出具体的变量名称,但必须给出每个变量的类型. 函数声明,不是说 ...

最新文章

  1. ini配置文件的读取
  2. 膨胀和腐蚀之外的其他形态学变换
  3. [导入]使用RDLC报表(一)
  4. CTF-Misc-常用知识点
  5. 软考-信息系统项目管理师-战略管理
  6. 织梦 mail.class.php,详解织梦模板DEDECMS核心类TypeLink.class.php功能分析
  7. 输出节点位移_绝对值信号的编码器有哪些信号输出(一、二)
  8. 前端学习(3022):vue+element今日头条管理-首页layont布局
  9. 两个链表求交集_实现两个排序链表的并集和交集
  10. ubuntu不会自动休眠_关机、睡眠、休眠有啥区别?微软说非特殊情况不要关机
  11. dubbo的下载与运行
  12. 【Luogu1341】无序字母对(并查集联通,欧拉路模板)
  13. Emacs之hs-minor-mode折叠代码
  14. windous和Linux桌面版的比较
  15. win7连接共享打印机时安装驱动程序出现0x00000bcb错误
  16. Java Swing
  17. latex3的基本介绍
  18. 网络墨卡托投影的前世今生
  19. 免密登录 蹩脚的“脚本”
  20. 更改Ubuntu桌面环境

热门文章

  1. 快手有佳人|2020快手女性人群价值报告
  2. 2020年Airbnb爱彼迎中国房东社区报告
  3. 运用数组,输出从小到大的10个数
  4. wxpython界面切换_wxpython中的图形用户界面
  5. 基于金融知识图谱的会计欺诈风险识别方法
  6. 【算法分析与设计】图的着色问题
  7. 使用Spring框架实现数据库事务处理
  8. iptables filter表案例/iptables nat表应用
  9. CentOS 6.9编译安装新版本内核
  10. Outlook式样界面菜单和页面控制