如何解析复杂的C语言声明
C语言中有时会出现复杂的声明,比如
char * const * (*next) (); //这是个什么东东?
在讲复杂声明的分析方法前,先来个补充点。
C语言变量的声明始终贯彻两点 :
1.声明和使用的语法尽量保持一致
例如:
#include
using namespace std;
double (*fun)(double); //声明一个函数指针
int main(){
fun=sin;
doube reslut=(*fun)(0.5);//使用这个函数指针
...
}
2.声明语句不是的阅读不是按照从左往右的阅读顺序,而是要根据各个符号的优先级进行阅读的
这点非常重要!先列出C语言声明的优先级规则,再举个例子就能掌握求解方法了。
C语言声明的优先级规则
A 声明从它的名字开始读取,然后按照优先级顺序依次读取;
B 优先级从高到低依次是:
B.1 声明中被括号括起来的那部分;
B.2 后缀操作符:
括号()表示这是一个函数,而
放括号[]表示这是一个数组;
B.3 前缀操作符:星号*表示这是一个“指向...的指针”;
C 如果const和(或)volatile关键字的后面紧跟类型说明符(如int,long等),那么它作用于类型说明符。在其他情况下,它作用于关键字左边紧邻的指针星号。
需要强调的一个重要注意点是,对于优先级: () > [] > * 。
举例,用优先级规则分析C语言声明一例:
char * const * (*next) ();
按照规则解读 char * const * (*next) ();
首先,(*next) 表示next是一个指针,它指向某个东东;
根据B.2和最右边的括号,next指向一个函数;
根据B.3,第二个星号表示,该函数返回一个指针;
char * const是函数返回的指针所指向的类型;
char* 是字符指针,const修饰左边的星号,即字符指针是常量的,该指针不可修改(该指针指向的字符内容是可修改的);
综合地表述为,next是一个指针,它指向一个函数,该函数返回一个指针,该指针指向一个类型为char的常量指针。
还是不明白?再往下看就明白了 www.yztrans.com
#---------------------------------------------------------------------------------#
总结一下,分析复杂的C语言声明,要采用"由内而外,层层剥离 ”的策略。
从哪里开始剥?从语句的最左边的标志符开始剥(上例为从next开始)。
往哪个方向剥?依照C语言的优先级规则一层层剥。
#---------------------------------------------------------------------------------#
再举一例作详细说明:
char *(* c[10]) (int **p);
第一步,char *(* c [10]) (int **p); 最左边的标志符是c,表示"c是一个什么东东";
第二步,char *(* [10] ) (int **p); 和[10]结合,表示"c是一个长度为10的数组";
第三步,char *(* ) (int **p); 和*结合,表示"这个数组存放着指针";
第四步,char * (int **p) ; 和(int **p)结合,表示"这个指针指向一个函数,函数的参数是二维指针";
第五步,char * ; 和 * 结合,表示"这个函数返回一个指针";
第六步,char ; 这个指针指向一个字符;
把上面六步串起来,读作: c是一个数组[0..9],它存放着指针,指针指向的函数参数是一个二维指针返回值是指向字符的指针。完工!
#---------------------------------------------------------------------------------#
注1: 这个方法若理解了,什么指针数组和数组指针、指针函数和函数指针等等之类的区别都是小菜一碟了。
注2: 合法的声明中存在限制条件。如函数的返回值不能是一个函数,也不能是一个数组,所以像function()()和function()[]是非法的,不能出现。
数组里面能存函数指针,但不能存函数,像int (* function[])()是合法的,function[]()则是非法的托福答案 www.lefeng123.com
如何解析复杂的C语言声明的更多相关文章
- [C语言]声明解析器cdecl修改版
一.写在前面 K&R曾经在书中承认,"C语言声明的语法有时会带来严重的问题.".由于历史原因(BCPL语言只有唯一一个类型——二进制字),C语言声明的语法在各种合理的组合下 ...
- C语言声明解析方法
1.C语言声明的单独语法成份 声明器是C语言声明的非常重要成份,他是所有声明的核心内容,简单的说:声明器就是标识符以及与它组合在一起的任何指针.函数括号.数组下表等,为了方便起见这里进行分类表 ...
- 如何读懂复杂的C语言声明
本文已迁移至: http://www.danfengcao.info/c/c++/2014/02/25/howto-understand-complicated-declaration-of-c.ht ...
- 14 Go's Declaration Syntax go语言声明语法
Go's Declaration Syntax go语言声明语法 7 July 2010 Introduction Newcomers to Go wonder why the declaration ...
- C语言声明语句
设计理念: C语言的一个设计理念就是声明变量和使用变量的形式应该是一致的 优点:声明变量和使用变量时的运算符优先级是相同的 缺点:运算符的优先级是C语言过度解析的部分之一 术语: 变量声明中使用到的符 ...
- 曹工说Redis源码(2)-- redis server 启动过程解析及简单c语言基础知识补充
文章导航 Redis源码系列的初衷,是帮助我们更好地理解Redis,更懂Redis,而怎么才能懂,光看是不够的,建议跟着下面的这一篇,把环境搭建起来,后续可以自己阅读源码,或者跟着我这边一起阅读.由于 ...
- visual studio 2010 C语言声明异常
如下这段程序,是C_Primer_plus_第五版内的一个复习题答案(感觉声明i的值有问题),在GCC上面可以运行,但是移植到VS2010就一堆错误, #include<stdio.h> ...
- 关于C语言声明数组时省略长度
C语言在声明数组时必须明确长度,如下两种方式: (一) 直接指定长度.如: int a[5]; (二) 声明时初始化元素.如:int a[]={1,3,5}. 如果,直接int a[]; 是不可以的 ...
- [置顶] cJSON库(构建json与解析json字符串)-c语言
一.c语言获取json中的数据. 1.先要有cJOSN库,两个文件分别是cJSON.c和cJSON.h. 2.感性认识 char * json = "{ \"json\" ...
随机推荐
- Bellman_ford最短路
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> ...
- 帕累托分析法(Pareto Analysis)(柏拉图分析)
帕累托分析法(Pareto Analysis)(柏拉图分析) ABC分类法是由意大利经济学家帕雷托首创的.1879年,帕累托研究个人收入的分布状态图是地,发现少数人收入占全部人口收入的大部分,而多数人 ...
- IOS实现小型计算器
作为一名初学者,编辑一款能够在IOS操作系统上运行的计算器是一件很值得自豪的事情,网络上虽然后很多相关的文章和代码,功能也很强大但是我感觉相关的计算器比加复杂,晦涩难懂,所以我想通过这个小小的计算器, ...
- AutoCompleteTextView ArrayAdapter
AutoCompleteTextView 继承于EditText,拥有EditText所有属性和方法 在输入框中输入我们想要输入的信息就会出现其他与其相关的提示信息 首先在activity_mai ...
- Eclipse自动插件依赖的一种配置解决方式
Eclipse的插件具有以下特点: (1)每一个插件有自己独立的classloader (2)插件资源的交互通过MENIFEST.MF中"Export-Package, Require-Bu ...
- 微信公众平台java开发具体解释(project代码+解析)
说明: 本次的教程主要是对微信公众平台开发人员模式的解说,网络上非常多类似文章,但非常多都让初学微信开发的人一头雾水,所以总结自己的微信开发经验,将微信开发的整个过程系统的列出,并对主要代码进行解说分 ...
- Fragment 创建 传递参数 跳转 典例
抽取的控制Fragment的父Activity /** * 抽象一个Activity托管我们的Single Fragment */ public abstract class SingleFrag ...
- knockout --- foreach -- 前端必备
很久很久没写博客了,丫的,节操掉一地了,颓废了,惭愧. 很久很久没有弄 knouckout.js 了,今天重新操作,蛋疼啊,忘记得差不多了,于是只好硬着头皮再去看官网,于是,feel慢慢回来了. 本来 ...
- maven第三章 maven使用入门
3.1编写pom groupId 一个项目名称 artifactId 子项目(模块)名称 version 开发中的版本,稳定的版本 name 项目名称,方便信息交流 http://news.cnblo ...
- mouseover,mouseout和mouseenter,mouseleave
mouseover和mouseout 鼠标指针进入或者离开被选元素或其子元素,都会触发相应事件. 非IE浏览器支持该事件. mouseenter和mouseleave 只有在鼠标指针进入或者离开被选元 ...