目录
一、前言
就我的发现而言,csdn上面很少去有人去写提高编程质量,改良编程习惯的文章,包括现在的高等教育阶段所教授的c\c++,都大多只停留在如何写出这个程序,如何解决这个问题,
很少人去关注软件质量,以及代码风格等的问题。老师也很少去给学生去灌输代码质量的重要性的这个概念,甚至于有些非常努力的学生长时间在低质量,低水准,低效率的程序中摸爬滚打,浪费了自己的大学时间。
以至于在以后到企业工作的时候尝尽因为不良习惯和错误带来的苦头,而且会因为代码风格以及编程习惯在早期的学习中已经成型,很难去改正自己那些错误的,致命的习惯。在工作中去一点点否定自己以前的习惯,去重新建立新的习惯这样做是非常难去进步的,一不小心甚至会适得其反,就像邯郸学步一样。
所以说我认为初学者应该重视起来,在学习中去注意正确性、健壮性、可靠性、效率、易用性、可读性(可理解性)、可扩展性、 可复用性、兼容性、可移植性等代码质量问题。现在去改变这些不好的习惯还为时不晚,否则会因为这样不好的代码习惯而造成很多致命的错误,浪费大量时间去寻找这些本应能够避免的bug。
二、程序的版型
版型并不会影响代码的功能,但是不好的版型会影响到代码的可读性和美观程度,以及后期维护所需要的时间。有人把好的代码比作是“书法”,没错,版型好的代码,会使阅读的人赏心悦目,也会使你在找工作的时候,让面试官高看你一眼。
1、空行
空行虽然会使代码长度变长,但是代码中适当的加入空行会使代码更加的清晰,也能使各个部分的条理更加清楚。所以我们还是要在适当的位置加上空行。
1.1、在每个类声明之后、每个函数定义结束之后都要加空行
//空行 int ADD(int x, int y) //空行 int SUB(int x, int y) //空行 int main() //空行 | int ADD(int x, int y) int SUB(int x, int y) int main() |
1.2、在一个函数体内,逻辑上密切相关的语句间不加空行、其他地方应该加上空行,
//
空行
while (condition)
{
statement1;
//
空行
if (condition)
{
statement2;
}
else
{
statement3;
}
//
空行
statement4;
}
|
while (condition)
{
statement1;
if (condition)
{
statement2;
}
else
{
statement3;
}
statement4;
}
|
2、代码行
c语言中并没有过多的要求代码在什么时候需要换行,但是我们在书写中也要进行适当的换行来时代码更加整齐美观。
2.1、一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅读,并且方便于写注释
2.2、if、for、while、do 等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加{}。这样可以防止书写失误
2.3、尽量在定义变量的时候,去初始化这个变量。
相信各位在初学c语言使用sum变量去计算和的时候,有过没有初始化sum这个变量造成的bug。所以我认为在创建变量时初始化变量是个必要的好习惯。
int a = 0;//初始化a int b = 0; int c = 0; | int a=0,b=0,c=0; |
x = a + b; y = b + c; z = c + d; | x=a+b;y=b+c;z=c+d; |
if (0 == x) { printf("%d", a); } //空行 ... | if(x==0){ printf("%d",a); } //或是这样 if(x==0) printf("%d", a); |
3、代码行内的空格
3.1、关键字之后要留空格。象 const、virtual、inline、case 等关键字之后至少要留一个空格,否则无法辨析关键字。象 if、for、while 等关键字之后应留一个空格再跟左括号‘(’,以突出关键字。
3.2、函数名之后不要留空格,紧跟左括号‘(’,以与关键字区别。
3.3、(’向后紧跟,‘)’、‘,’、‘; ’向前紧跟,紧跟处不留空格。
3.4、‘,’之后要留空格,如 Function(x, y, z)。如果‘; ’不是一行的结束符号,其后要留空格,如 for (initialization; condition; update)。
3.5、赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“ = ”、“ += ” “ >= ”、“ <= ”、“ + ”、“ * ”、“ % ”、“ && ”、“ || ”、“ << ”, “ ^ ”等二元操作符的前后应当加空格。
3.6、一元操作符如“!”、“~”、“++”、“--”、“ & ”(地址运算符)等前后不加空格。
3.7、像是“[]”、“.”、“->”这类操作符前后不加空格。
3.8、对于表达式比较长的 for 语句和 if 语句,为了紧凑起见可以适当地去掉一些空格,如 for (i = 0; i < 10; i++)和 if ((a <= b) && (c <= d))
代码行空格这个东西我觉得是每一个程序员必备的技能之一。可能有些编译器例如VS会帮助程序员自动加上该有的空格。这个功能很好,但是我觉得我们可以把它作为一个参考,去自己有意识地加上该有的空格,毕竟不是所有的编译器都能拥有这个功能。否则在使用其他编译器时不知道应该在哪里加空格就要闹笑话了。
void Func1(int x, int y, int z); // 良好的风格
void Func1 (int x,int y,int z); // 不良的风格
|
if (year >= 2000) // 良好的风格
if(year>=2000) // 不良的风格
if ((a>=b) && (c<=d)) // 良好的风格
if(a>=b&&c<=d) // 不良的风格
|
for (i=0; i<10; i++) // 良好的风格
for(i=0;i<10;i++) // 不良的风格
for (i = 0; I < 10; i ++) // 过多的空格
|
x = a < b ? a : b; // 良好的风格
x=a<b?a:b; // 不好的风格
|
int *x = &y; // 良好的风格
int * x = & y; // 不良的风格
|
array[5] = 0; // 不要写成 array [ 5 ] = 0;
a.Function(); // 不要写成 a . Function();
b->Function(); // 不要写成 b -> Function();
|
4、对齐
4.1、‘{’要与相匹配的‘}’对齐
4.2、‘{’和‘}’自成一行
这样代码整体的观感会好很多。这个相信各位在书写中一般是有注意的,这个习惯并不难实现所以说大家在书写时还是要注意这一点。
void Function(int x)
{
… // program code
}
|
void Function(int x){
… // program code
}
|
5、长行拆分
5.1、当有比较长的代码行出现时,要保证本行的代码数不超过7~80个字符
5.2、拆分时从优先级较小的操作符处拆分,并且进行适当的缩进使上下对齐更加美观。
当我们在读代码时,看到一大行的代码是真的非常头痛,而且往往在读这种代码时可能一目十行会漏掉东西,非常危险。所以说把长行拆分成多个小行,能使代码的可读性有效地提高,还能降低读代码时造成错误的风险。
关于优先级这个东西,初学者可以不考虑,只要在换行时保证不出错就行。
6、修饰符的位置
6.1、’ * ‘ ‘ & ’这样的修饰符应该靠近变量名。
因为有些代码会产生歧义,例如下面的代码
int* a, b;
在这个例子中我们很容易把a,b变量想成是int* 类型的指针变量。但是其实被int*修饰的只有a一个。也就是说a是int*型指针变量,b是int型的整型变量。
那如果我们写成这样
int *a,b;
就会减少很多不必要的歧义。
7、 注释
7.1、注释一定要精炼,不能逐字逐句分析,而应该在应有的地方给予提示。
7.2、如果代码本来就是清楚的,则不必加注释。否则多此一举,令人厌烦。
例如
i++; // i 加 1,多余的注释
7.3、注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不可放在下方。
7.4、注释中避免出现缩写,以及会出现歧义的语句否则可能会适得其反。
7.5、当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,便于阅读。
注释出现的目的是方便人们阅读,提高代码的可读性,而如果注释本身就是有问题的那这样的注释反而会极大的影响我们阅读。所以说要尽可能地减少错误,并且在适当的位置给予注释。
/*
* 函数介绍:
* 输入参数:
* 输出参数:
* 返回值 :
*/
void Function(float x, float y, float z)
{
…
}
|
if (…)
{
…
while (…)
{
…
} // end of while
…
} // end of if
|
这篇之前有发过,但是排版有些小问题,在手机上看的话会看着很难受,所以说发一下重排的,也继续更新后续。