水滴石穿C语言之声明的语法
概述
在很多情况下,尤其是读别人所写代码的时候,对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语言之声明的语法相关推荐
- 理解C语言中指针的声明以及复杂声明的语法
昨天刚把<C程序设计语言>中"指针与数组"章节读完,终于把心中的疑惑彻底解开了.现在记录下我对指针声明的理解,顺便说下如何在C语言中创建复杂声明以及读懂复杂声明. 本文 ...
- 怎样在c语言中声明list这一变量,C语言变量赋值语句的语法解析算法实现
本篇文章是java开发编译器系列课程的文档,有兴趣的朋友可关注网易云课堂的视频内容: 自己动手用java开发编译器 经过一系列的算法摸索后,我们终于要进入 C 语言编译器开发的进程,这一节,我们的目的 ...
- 《C专家编程》第三章——分析C语言的声明
前面一章我们已经说过C语言存在的一些问题和它晦涩的地方,让我们对这门神奇的语言有了更深的了解.现在这一章则集中精力来讨论C语言的声明,分为三块,首先是说明C语言声明晦涩难懂的原因和声明是如何形成的,其 ...
- c语言函数声明定义参数命名,C语言函数声明与定义
C语言函数声明与定义教程 在 C语言函数声明与定义 语法 type funcName(paramType1 param1, paramType2 param2){ // 执行语句... return ...
- 编译原理课程作业-Cminus语言的词法及语法分析器实现
Cminus Compiler 编译原理课程作业-Cminus语言的词法及语法分析器实现 设计思想 词法分析 使用确定有限态自动机(DFA)实现与Lex自动分析两种方式实现. 语法分析 使用递归下降方 ...
- 从D语言看C++ Template语法
从D语言看C++ Template语法 许式伟 (版权声明) 2007-5-2 D语言是一门新兴的语言,它试图结合C/C++性能上的高效,同时又象Python.Ruby等"现代"语 ...
- 如何理解C语言的声明
在K&R中,作者承认"C语言声明的语法有时会带来严重的问题".C语言声明的语法对于编译器来说并不是什么大不了的事,但对于一般的程序员,它却会成为障碍. 在阅读较为复杂的代码 ...
- Scala语言学习一——基础语法
什么是 Scala Scala 是一种多范式的编程语言, 其设计的初衷是要集成面向对象编程和函数式编程的各种 特 性 . Scala 运 行 于 Java 平 台 (Java 虚 拟 机 ) , 并 ...
- c语言常用的格式声明,c语言函数声明格式是什么
c语言函数声明格式是什么 c语言函数声明格式是"函数类型 函数名称(参数列表);".在函数声明中的参数列表中,不需要给出具体的变量名称,但必须给出每个变量的类型. 函数声明,不是说 ...
最新文章
- ini配置文件的读取
- 膨胀和腐蚀之外的其他形态学变换
- [导入]使用RDLC报表(一)
- CTF-Misc-常用知识点
- 软考-信息系统项目管理师-战略管理
- 织梦 mail.class.php,详解织梦模板DEDECMS核心类TypeLink.class.php功能分析
- 输出节点位移_绝对值信号的编码器有哪些信号输出(一、二)
- 前端学习(3022):vue+element今日头条管理-首页layont布局
- 两个链表求交集_实现两个排序链表的并集和交集
- ubuntu不会自动休眠_关机、睡眠、休眠有啥区别?微软说非特殊情况不要关机
- dubbo的下载与运行
- 【Luogu1341】无序字母对(并查集联通,欧拉路模板)
- Emacs之hs-minor-mode折叠代码
- windous和Linux桌面版的比较
- win7连接共享打印机时安装驱动程序出现0x00000bcb错误
- Java Swing
- latex3的基本介绍
- 网络墨卡托投影的前世今生
- 免密登录 蹩脚的“脚本”
- 更改Ubuntu桌面环境