咨询热线:18839586270 联系人:江海霞 地址:新疆维吾尔自治省乌鲁木齐市乌鲁木齐市西虹西路554号
C++雾中风景番外篇:理解C++的复杂声明与声明解析
来源:金钻最新网址 发布时间:2019-11-19 点击量:235
在学习C系列语言的过程之中,理解C/C++的复杂声明一直是初学者很困扰的问题。笔者初学之时也深受困扰,对很多规则死记硬背。后续在阅读《C专家编程》之后,尝试在编译器的角度来理解C/C++的声明解析,并且编写代码将这部分逻辑串联起来,之后再看到许多看似复杂的声明,也能够很好的理解和消化了。
1.复杂的声明
在编写C/C++代码时偶尔能看到如下的复杂声明:float(*(*e[10])(int*))[5]
。我想你的第一反应一定是:MMP。虽然我们在实际工作之中是很少出现这种极其复杂的声明逻辑,同时也不提倡使用这样的声明。但是学会理解和解析这类复杂的声明逻辑,可以更好的理解C/C++之中诸个关键词是如何进行组织,来表达逻辑的,也能更好的理解各个关键词的使用方式。
比如之前笔者写的一篇文章之中整理了C/C++之中const关键词的用法 《C++雾中风景3:const用法的小结》的之中通过口诀的方式记忆const关键字在声明之中的先后顺序来厘清不同的逻辑。这种方式不仅效率低下,而且并没有理解到为什么不同的先后顺序会对声明逻辑产生影响。在本篇文章之中,笔者尝试带大家忘记这些口诀,从编译器的角度去理解编译器是如何处理这些声明的逻辑,知其然而知其所以然。
2.优先级规则
C/C++的声明模型是及其晦涩的,笔者简单统计了涉及声明模型的关键字如const,volatile等大概有十个左右。更为复杂的是在C/C++之中这些关键字的先后顺序与括号可以任意组合并且发生看起来很奇妙的"化学反应"。
万变而不离其中,总结出规律之后,再复杂的模型也可以简化成我们可以理解的单元来处理。所以我们先来看看C/C++声明的优先级规则。
声明是由标识符,也就是它的名字开始解析的。获取了声明之后,接下来安装如下优先级别来依次处理声明:1. 优先处理括号部分的声明逻辑。2. 优先处理后缀操作符,如[],()3. 处理前缀操作符,如*,const后续可以依次从右往左处理之前的声明了。掌握了上述的优先级规则之后,我们回到本文一开始举的一个小栗子
1.找到声明e,e将作为声明的名字。2.处理后缀操作符,也就是e代表的是一个容量为10的数组。3.回到前缀操作符,该数组存储的内容为指针。4.跳出括号,开始新的一轮的**优先级规则**,处理后缀操作符(),我们发现这个指针指向的是一个参数为int*的函数。5.接着再次回到前缀操作符,所以这个函数返回值依然是一个指针。6.跳出括号,继续前文的逻辑,我们发现该指针指向了一个内容为float,容量为5的数组。通过上述栗子我们不难发现,对于声明的处理本质上是一个有限自动机的状态变化过程,所以编译器同样也是按照上述的规律来理解并处理程序的复杂声明的。了解了优先级规则,我们也就不难去实现一个简单的小程序**cdecl**来处理声明逻辑了。####3.简单的代码实现通过上述流程的说明,我们很容易想到可以用**栈**来保存声明标识符左边的内容,而名字右边的内容则依照优先级规则依次处理。(优先处理数组与函数)。* **先分类将要处理声明的种类,并且声明token类型来进行处理**
enum type_tag {IDENTIFIER,QUALIFIER,TYPE,POINTER,LPAREN,LBRACKET,RPAREN,RBRACKET};
struct token {type_tag type;string content;};
* **不断读取token,并且压入栈中,直到读取到声明标识符**
void read_to_first_identifer() {gettoken();while (this_t.type != IDENTIFIER) {token_stack.push(this_t);gettoken();}
cout << this_t.content + " is ";gettoken();
}
* **按照优先级法则处理逻辑,先右后左,遇到括号弹出之后继续上述逻辑**
void deal_with_declarator(){switch (this_t.type) {case LBRACKET:deal_with_arrays();break;case LPAREN:deal_with_function_args();}
deal_with_pointers();while(!token_stack.empty()) { if(token_stack.top().type == LPAREN) { token_stack.pop(); gettoken(); deal_with_declarator(); } else { cout << token_stack.top().content + " "; token_stack.pop(); }}
}
* **处理数组类型的函数**
void deal_with_arrays() {while (this_t.type == LBRACKET) {cout << "array ";gettoken();if(isdigit(this_t.content[0])) {printf("0....%d of ",atoi(this_t.content.c_str()) - 1);gettoken();}
gettoken();}
}
* **处理函数类型的函数**
void deal_with_function_args() {while(this_t.type != RPAREN) {gettoken();}gettoken();
cout << "function returning ";
}```
所以通过上述的代码串联起来,我们就可以简单的完成一个解析C/C++声明的小程序。尝试这个小程序解析笔者在本文提出的示例:上述实现代码的完整版,笔者放在了自己的github之上,需要的可以自取。《C专家编程》之中也有对应C语言版本,需要的也可以用作参考。
4.小结
厌倦了复杂声明?希望有更友好的声明类型?番外篇当然是为了引出正篇,接下来笔者将会和大家一起来看看,C++为了简化声明的类型系统,做出了那些努力来更加高效的提升程序员的工作效率。A
相关产品
-
在Home Depot这样的店面,或者是其他大型硬件和家居装饰店中,“Nest”已经成为智能恒温控制器的代名词,就像舒洁(Kleenex)之于面巾纸,iPad之于平板电脑。因为市场占有率和精神占有率的关系,目前对于这个新兴市场,苹果和Alphabet都没有兴趣去考虑设备的交叉兼容个问题。而且某款具体的产品的价值是与整个细分市场有联系的,从消费者的心态角度来说,这样的联系也是无法切断的。
-
张柏芝回应称:向先生决定的所有事情我非常尊重,向太一直说把我当女儿看,所以希望他们都不要那么生气了。感谢他们一直以来对我的好,我也很感谢他们全家,他们对我的好我一定记得,一辈子都忘不了的。无论什么时候,在我心里,他们都是我的亲人。不能继续出演此片可能是双方理解上的误会,从训练到开拍我和剧组的工作人员相处都很愉快,很爱他们,舍不得他们,拜托大家不要有其他的猜测。大家加油!谢谢大家!(综 合)
-
而说到迷你电脑,Intel NUC可以说是标志性产品,拥有极其迷你的体积以及依靠着Intel在芯片领域强大实力而不断性能提升综合性能,让NUC这款搭载核芯显卡的整合平台成为能满足普通家庭娱乐应用的迷你电脑。但仅仅普通娱乐应用能满足现今主流用户以及游戏玩家的使用需求吗?这个答案是肯定的,并不能。
-
2012年11月9日上午,恒隆广场项目举行隆重开工典礼,时任县委书记徐超,县委常委、常务副县长田为友、县委常委顾为何,以及其他县四套班子主要领导悉数出席并剪彩。田为友是开工庆典的主持人,徐超启动触摸球祝贺恒隆广场项目正式开工。
-
据英国《金融时报》网站7月29日报道,自今年3月以来,热煤价格已上涨20%,中国交易商被迫抢购海运市场的货源或削减库存。据此前报道,国家发改委等部门就煤炭去产能研究举措,包括暂停审批新建煤矿项目、淘汰落后产能、引导“僵尸企业”退出等举措。未来三年,中国将关闭4300家煤矿(总产能约为每年7亿吨),分流人员100万人。中国政府将为此斥资45.7亿美元(约合300亿元人民币)。
-
他续说,朱立伦支持侯友宜参选新北市长已不是秘密,如果朱立伦能参选台北市长的话,正好可以和侯友宜打出“台北、新北:双北协同发展”的诉求,对于赢得选举会有很大帮助。2010年选举中,郝龙斌和朱立伦打出“黄金双兄弟,共同打造黄金双子城”,最终双双当选。
-
“每个人心中都有一个武侠梦”,话声尤在耳畔,但是毋庸置疑武侠剧正在丧失其市场地位。近年来,备受瞩目的大剧或是《三生三世十里桃花》等仙侠魔幻剧,或是《人民的名义》、《欢乐颂》等现实题材,古装武侠剧似乎缺席爆款已久。
-
2013款奥德赛沿用了老款的2.4L i-VTEC发动机,最大功率为133kw(180ps),峰值扭矩为218牛米。这款发动机的功率输出在同排量发动机中尽显优势,同时还拥有出色的燃油经济性,90km/h等速油耗仅为6.8l/100km。传动方面,奥德赛全系配备了5速自动变速箱,能为驾驶者带来非常顺畅的驾驶感受。
热点资讯
- 女主播起诉火山小视频索赔近14万:无法正常提现2019-11-16
- 暴马丁香栽培技术和肥水管理病虫害防治技术2019-11-19
- 1997年以前都是亏本?格力电器创始人朱江洪:胡说八道2019-11-10
- ?黑龙江省正式加入国家融资担保体系2019-10-31
- 凤凰单枞茶都有哪些功效2019-07-01
- 工作一年多的感慨与总结(一)2019-11-18
- 决定当代中国命运的关键一招2019-11-13
- 薄荷叶泡水喝的好处以及注意事项2019-11-17