加入社区有几天了,在社区中我看到有不少正在学习编程的新手。新人们可能苦于各种问题,学习前端还是后端?什么是有效的学习路径?
作为一个半只脚踏入程序员门槛的人,我的视野不够广泛,在技术方面也乏善可陈,可能难以在这些方面提出很好的建议。
但是,看到许多人的代码组织得并不好,作为一个稍微有强迫症的人,我想在代码风格方面给新手们提出一些建议,希望能够帮助到你们。
以下为正文。
在我看来,代码风格可以粗略划分为命名、缩进、对齐、留白、注释等部分。
由于缩进和对齐是众所周知的规则,这里就不赘述了。
注释规则较为复杂,好的注释应该能够形成文档,并且有许多工具帮助规范,读者可以自行查阅相关工具的文档。
命名
命名属于老生常谈的内容,常见的命名法有驼峰命名法、帕斯卡命名法、下划线命名法。以下是一个例子:
驼峰命名法 | 帕斯卡命名法 | 下划线命名法 |
---|---|---|
myHashSet |
MyHashSet |
my_hash_set |
插一句建议,帖子的表格编辑十分不方便,没法用 Tab 在单元格之间跳转,并且编辑到最后一个单元格后不能使用
Ctrl
+Enter
换行,希望站主改进一下~编辑过程中又发现一个问题,在列表项中添加代码块,换行时会跳出代码模式,导致只能编辑出一行代码。
另外还有两种命名方法:
MY_HASH_SET
,常用于命名常量;- 匈牙利命名法,目前已不再推荐,但偶尔能见到这种命名法的影子,如全局变量的命名
g_
前缀的全局变量,g
为 global 的缩写,这种用法是建议的。
目前流行的语言一般混用驼峰命名法和帕斯卡命名法,驼峰命名法一般用来命名变量,帕斯卡命名法一般用来命名类。这些是有明确用途的。
留白
空格留白
这是大多数新手不甚注意的部分,空格留白的目的在于提高代码的可读性,以我搜索到的一个 C 语言实现冒泡排序的算法为例:
# include<stdio.h>
int main(void)
{
int i, j, t, n;
int a[100];
scanf("%d",&n); // A
getchar();
for(i=0;i<n;i++) // B
scanf("%d",&a[i]); // C
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1-i;j++)
{
if(a[j]>a[j+1])
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
for(i=0;i<n;i++)
printf("%d ",a[i]); // C
return 0;
}
这段代码或许能跑,但并不美观。如果上千行的代码都是这样组织,那么阅读者可能会晕掉+_+
-
A 处,一般来说代码中逗号后面应该加上一个空格,改为
scanf("%d", &n);
,这样读者可以很容易地辨识出逗号前后属于两个不同的参数 -
B 处,问题比较多
- 语法成分混合在一起,
for
的三个部分应该用空格分开,也就是;
后面加个空格,改为for(i=0; i<n; i++)
for
和后面的括号之间要加上一个空格,便于识别for
语句和循环头,改为for (i=0; i<n; i++)
- 在二元运算符前后要加上空格,便于识别运算符前后的部分,改为
for (i = 0; i < n; i++)
- 语法成分混合在一起,
-
C 和 D 处,缩进错误,作为
for
的循环体,应该再缩进一部分,改为for (i = 0; i < n; i++) printf("%d ", a[i]);
我们着重比较一下最大的循环体修改前后的效果:
// 修改前 // 修改后
for(i=0;i<n-1;i++) | for (i = 0; i < n - 1; i++)
{ | {
for(j=0;j<n-1-i;j++) | for (j = 0; j < n - 1 - i; j++)
{ | {
if(a[j]>a[j+1]) | if (a[j] > a[j + 1])
t=a[j]; | t = a[j];
a[j]=a[j+1]; | a[j] = a[j + 1];
a[j+1]=t; | a[j + 1] = t;
} | }
} | }
应该能感觉到修改后代码的可读性提高了很多。并且,很容易发现这里的 if
语句后面没有用花括号括起来,是个 bug(这也是代码风格带来的好处之一)。
好了,最后再来回顾一下重点:
-
for
循环头的三个部分要用空格分开推广开来,如果
for
的循环头的初始化部分有多个变量,也应分开for (int i = 0, j = 0; ;)
-
for
等关键词后应加上空格分开,如while (1) { }
-
二元运算符前后要加上空格,如
double v = (s + ds) / dt;
换行留白
没什么好说的,按照代码逻辑分块即可,不同块之间用空行隔开。
整体修改之后的代码
# include<stdio.h>
int main(void)
{
int i, j, t, n;
int a[100];
scanf("%d", &n);
getchar();
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
for (i = 0; i < n - 1; i++)
{
for (j = 0; j < n - 1 - i; j++)
{
if (a[j] > a[j + 1])
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
for (i = 0; i < n; i++)
printf("%d ", a[i]);
return 0;
}
除了添加空格外,还添加了空行,main
函数被空行组织为变量声明、输入 n
、输入数组、排序、输出、返回语句等多个部分。
有点像文章中的段落,或者句读,看代码时在空行处可以休息一下,不必那么紧张(想一想如果一篇文章通篇只有一段,得有多头疼)
到这里该结束了,目前网上的教程很少涉及到代码风格,但良好的代码风格是所有开发者都应该注意的。
在代码风格方面,也有一些争议的地方,如缩进使用 Tab 还是空格、左花括号是否要换行、变量应该如何命名。而 JavaScript 中也常见到 void main ()
这样函数名后带有空格的风格,都各有千秋。
本文不涉及这些争论,重要的是,一个项目的代码风格应该是统一的。如果代码风格良好,但整个团队不同文件之间的风格不一致,也会导致问题。
希望大家都能写出美观、漂亮的代码~