代码风格规范
代码风格的原则是:简明,易读,无二义性。
以下我通过一个城市温度排序的C语言程序来简单介绍一下代码风格规范问题。
1、行宽
行宽必须限制,但是以前有些文档规定的80字符行宽太小了(以前的计算机/打字机显示行宽为80字符),现在时代不同了,可为100字符。
2、括号
在复杂的条件表达式中,用括号清楚地表示逻辑优先级。
3、 断行与空白的{ }行
程序的结构是什么风格?下面有几种格式,我们一一讨论。
最精简的格式A:
有人喜欢这样,因为可以节省几行,但是不同的语句(Statement)放在一行中,会使程序调试(DeBug)非常不方便,如果要一步一步观察condition(condition有可能是包含函数调用的复杂表达式)中各个变量的变化情况,单步执行就很难了。
因此,我们还是要有断行,这样可以得到如下的结构——格式B:
这样的结构,由于没有明确的“{”和“}”来判断程序的结构,在有多层控制嵌套的时候,就不容易看清结构和对应关系。
于是我们最后做了这个选择,每个“{”和“}”都独占一行。就是格式C:
4、分行
不要把多行语句放在一行上。
更严格地说,不要把不同的变量定义在一行上。
5、 命名
当我们的程序比“Hello World”复杂10倍以上的时候,像给变量命名这样简单的事看起来也不那么简单了。我们就来谈谈如何起名字这个问题。程序中的实体、变量是程序员昼思夜想的对象,要起一个好的名字才行。用单个字母给有复杂语义的实体命名是不好的,目前最通用的,也是经过了实践检验的方法叫“匈牙利命名法”。例如:
fFileExist,表明是一个bool值,表示文件是否存在;
szPath,表明是一个以0结束的字符串,表示一个路径。
如此命名的目的是让程序员一眼就能看出变量的类型,避免在使用中出错。早期的计算机语言(如BCPL)不作类型检查,在C语言中,int、byte、char、bool大概都是一回事。下面这一句话:
if (i)
从语义来说,i可以是表示真/假的一个值,也可以表示长度是否为零,
还可以表示是否到了字符串的结束位置,或者可以表示两个字符串比较的结果不相等(strcmp()返回-1,0,1)。从程序的文字上,很难看出确切的语义。
同样是字符串类型,char *,BSTR的有些行为是很不一样的。
HRESULT的值也可以用来表示真假,但是HR_TRUE == 0,HR_FALSE ==1,这和通常的true/false刚好相反。
大部分的程序,错就错在这些地方!在变量面前加上有意义的前缀,就可以让程序员一眼看出变量的类型及相应的语义。这就是“匈牙利命名法”的用处。
6、 下划线问题
下划线用来分隔变量名字中的作用域标注和变量的语义,如:一个类型的成员变量通常用m_来表示。移山公司规定下划线一般不用在其他方面。
7、 大小写问题
由多个单词组成的变量名,如果全部都是小写,很不易读,一个简单的解决方案就是用大小写区分它们。
Pascal——所有单词的第一个字母都大写;
Camel——第一个单词全部小写,随后单词随Pascal格式,这种方式也叫lowerCamel。
一个通用的做法是:所有的类型/类/函数名都用Pascal形式,所有的变量都用Camel形式。
类/类型/变量:名词或组合名词,如Member、ProductInfo等。
函数则用动词或动宾组合词来表示,如get/set; RenderPage()。
8、 注释
谁不会写注释?但是,需要注释什么?
不要注释程序是怎么工作的(How),你的程序本身就应该能说明这一问题。
以上的注释是多余的。
注释是用来解释程序做什么(What),为什么这样做(Why),以及要特别注意的地方的,如下:
复杂的注释应该放在函数头,很多函数头的注释都是解释参数的类型等的,如果程序正文已经能够说明参数的类型in/out等,就不要重复!
注释也要随着程序的修改而不断更新,一个误导的注释往往比没有注释更糟糕。
在现代编程环境中,程序编辑器可以设置各种好看的字体,我们可以使用不同的显示风格来表示程序的不同部分。