C++常见编程思想及语法错误2014-10-15 13:38:54
C++常见编程思想及语法错误:
第1章 基础问
常见错误1:过分积极的注释
常见错误2:幻数
常见错误3:全局变量
常见错误4:未能区分函数重载和形式参数默认值
常见错误5:对引用的认识误区
常见错误6:对常量(性)的认识误区
常见错误7:无视基础语言的精妙之处
常见错误8:未能区分可访问性和可见性
常见错误9:使用糟糕的语言
常见错误10:无视(久经考验的)习惯用法
常见错误11:聪明反被聪明误
常见错误12:嘴上无毛,办事不牢
第2章 语法问题
常见错误13:数组定义和值初始化的语法形式混淆
常见错误14:捉摸不定的评估求值次序
常见错误15:(运算符)优先级问题
常见错误16:for 语句引发的理解障碍
常见错误17:取大优先解析原则带来的问题
常见错误18:声明饰词次序的小聪明
常见错误19:“函数还是对象”的多义性
常见错误20:效果漂移的类型量化饰词
常见错误21:自反初始化
常见错误22:静态连接类型和外部连接类型
常见错误23:运算符函数名字查找的反常行为
常见错误24:晦涩难懂的operato->
第3章 预处理器问题
常见错误25:使用≠}denne定义的字面量
常见错误26:使用#define定义的伪函数(函数宏)
常见错误27:≠if的滥用
常见错误28:断言(assert宏)的副作用
第1章 基础问题
说一个问题是基础的,并不就是说它不是严重的或不是普遍存在的。事实上,本章所讨论的基础问题的共同特点比起在以后章节讨论的技术复杂度而言,可能更侧重于使人警醒。这里讨论的问题由于它们的基础性,在某种程度上可以说它们存在于几乎所有的C++代码中。
常见错误1:过分积极的注释
很多注释都是画蛇添足。它们只会让源代码更难读、更难维护,并经常把维护工程师引入歧途。考虑下面的简单语句:
1.a = b; // 将b赋值给a
这个注释难道比代码本身更能说明语句的意义吗?其实它是完全无用的。事实上,它比完全无用还要坏。它是害人精。首先,这条注释转移了代码阅读者的注意力,增加了阅读量,从而使代码更费解。其次,要维护的东西更多了,因为注释也是要随着它描述的代码的更改而更改的。第三,对注释的更改常常被忽视了 。
1.c = b; // 将b赋值给a
仔细的维护工程师不会武断地说注释是错的 ,所以他就被迫要去检视整个程序以确定注释到底是错了的呢,还是好意的呢(c可能是a的引用),还是微妙的呢(赋值给c可能引发一些传播效应以使a的值也发生相应变化)等等,总之这一行就根本不应该带注释。
1.a = b;
该代码本来的样子就最清楚地表明了其意义,也不用维护额外的注释。这在精神上也符合老生常谈,亦即"最有效率的代码就是根本不存在的代码"。这条经验对于注释也适用:最好的注释就是根本用不着写的注释,因为要注释的代码已经"自注释"了。
另一些常见的非必要的注释的例子经常可以在类型的定义里见到,它们要么是病态的编码标准的怪胎,要么就是出自C++新手:
1.class C {
2. // 公开接口
3. public:
4. C(); // 默认构造函数
5. ~C(); // 析构函数
6. // ...
7.};
你会觉得别人在挑战你的智商。要是某个维护工程师连"public:"是什么意思都需要教,你还敢让他碰你的代码吗?对于任何有经验的C++软件工程师而言,这些注释除了给代码添乱、增加需要维护的文本数量以外没有任何用处。
1.class C {
2. // 公开接口
3. protected:
4. C( int ); // 默认构造函数
5. public:
6. virtual ~C(); // 析构函数
7. // ...
8.};
软件工程师还有一种强烈的心理趋势就是尽量不要"平白无故"地在源文件文本中多写哪怕一行。这里公布一个有趣的行业秘密:如果某种结构(函数、类型的公开接口等)能被塞在一"页"里,也就在三四十行左右 的话,它就很容易理解。假如有些内容跑到第二页去了,它理解起来就难了一倍。如果三页才塞得下,据估计理解难度就成原来的四倍了 。
一种特别声名狼藉的编码实践就是把更改日志作为注释插入到源文件的头部或尾部:
1./* 6/17/02 SCD 把一个该死的 bug 干掉了 */
这到底是有用的信息,抑或仅仅是维护工程师的自吹自擂?在这行注释被写下以后的一两个星期,它怎么看也不再像是有用的了,但它却也许要在代码里粘上很多年,欺骗着一批又一批的维护工程师。顶好是用你的版本控制软件来做这种无用注释真正想做的事,C++的源代码文件里可没有闲地方来放这些东西。
想不用注释却又要使代码意义明确、容易维护的最好办法就是遵循简单易行的、定义良好的命名习惯来为你使用的实体(函数、类型、变量等)取个清晰的、能反映其抽象含义的名字。(函数)声明中形式参数的名字尤其重要。考虑一个带有三个同一类型参数的函数:
1./*
从源到目的执行一个动作
第一个参数是动作编码(action code),第二个参数是源(source),第三个参数是目的
1.??? (destination)
2.*/
3.void perform( int, int, int );
这也不算太坏吧,不过如果参数是七八个而不是三个,你又该写多少东西呢?我们明明可以做得更好:
......
原文下载:
C++常见编程思想及语法错误.doc [登录雪炭网后可见]