作者beagle1 (满城飞絮风吹雪)
看板b92902xxx
标题Coding Style
时间Thu Dec 4 21:54:04 2003
最近两三个星期来, 收到的几份 source code , 多半都排得很乱,
向前看齐的也有, 前後乱跳的也有, 通常写程式会做缩排, 各位好像不知道... :p
还好我有 indent -kr 这秘招, 靠大师庇佑勉强看得懂... (其实他们还没死)
Coding Style 可以说是程式的外观或风格,
排版, 变数取名, 注解, 最好整份程式都能遵守一定的规律...
更深入的例如记忆体和其他资源的管理, 函式的结构, 也常常要定下规则来,
这样做主要的功用是 1. 易懂 2. 避免写出 bug ...
那麽你一定要问了, 程式自己懂就好, 写得太好懂不是方便别人抄吗?
这也不一定, 有时候自己写的 code 过两星期再看就看不懂了, 无从改起...
现在的作业, 一部份 code 有可能是明年修别的课可以再 reuse 的...
另外, 如果你星期一写的星期三就看不懂, 岂不是有苦说不出?
另外停止量产 bug 也是很重要的, 有结构地写程式, 辨明流程, 分清楚区块,
就可以减少大部份语法及流程上的 bug, 万一有问题也可以迅速找出位置...
不知道各位听过流程图吗? 那是麻瓜用的, 程式流程写清楚的话是不需要这个的...
* * *
Coding Style 是人订的, 你爱怎麽定都行, 只要符合一些要点, 就能达到目的...
C 语言的 coding style, 除了上次我提到的三个流派以外, 不同 leader 可能都会
订不同的 style... 不同语言也会有不同的 coding style ...
1. 缩排与大括号:
原理: 缩排是为了分清楚各区块 (code block) 的起始结束
code 分层结构中, 内层的句子往内缩, 同一个 compund statement 里面每一行都要
对齐, 这样才能分清哪一块是这个 if 的 then 哪一块是 else :
if (x == y) {
we do a;
we do b;
} else {
we do c;
return;
}
如果没有缩排, 当 if 里面还有 if 的时候, 一定会分不清哪个 else 配哪个 if ..
如果你用的是 Visual Studio, 他会这样排:
if (x == y)
{
we do a;
}
这样也可以, 分割 code block 的作用一样有达到...
大部份人都会把後面的大括号单独写一行, 以便清楚标示出 code block 结尾...
下面这种状况是不被鼓励的, 几乎没人这样做:
if (x == y) {
we do a; }
不过你如果很坚持, 那也随便你, 至少有缩排了...
缩排的宽度, 主流有 8 派和 4 派, 前者刚好一个 tab 宽, 後者可以放比较多层,
另外也有少数人用 2 格, 甚至还有用 3 格的, 这就看各位喜好了...
大部份编辑器都能设定 tab 缩排的宽度, 例如说 vi 可以这样:
:set ts=4
其他的多半也都能设定, 好像只有 Windows 记事本不行...
我一年级用 2 格, 这样可以开心的一直缩一直缩,
但是後来发现缩排超过 5 层的话, 容易写出 bug, 整个 code 会因为层数太多乱掉,
所以现在不管缩排是用几格, 只要层数到 6 层我都会尽量提出来另外写 function
写坏了怎麽办?
GNU 有一个小工具, 叫 indent (这个字是缩排的意思), 可以用来重排 code ,
有 -gnu(预设) -kr -orig 三种 style 可以选, 还有其他许多选项可以调整,
例如 indent -kr -i2 hw2.c 可以用 K&R style, 一次缩排 2 个空白,
原理: 程式做缩排不能治疗写出烂 code 的毛病
用 Visual Studio 或其他自动缩排编辑器的也要注意自己的 coding style,
写的时候要想清楚, 心中也必需段落分明, 如果发现想得和萤幕上排出来的不一样,
就要特别注意是不是写错了...
只要你晓得怎样利用, VC 和 Emacs 这种自动编排的功能帮助非常大...
2. 变数及 function 取名:
各位寄来的 code, 取名常常是一个字母, 至於 function 这东西好像没看过...
一个字母对用後即丢小变数来说不错, 节省空间也节省打字时间...
for 里面的 i , 改叫他 counter 并没有任何好处, 没有人会因为 i 短就看错...
但是对重要的资料, 最好用简单的单字表示, 例如 inbuf 和 outbuf ...
至少比 a 和 b 容易知道那一个是输入哪一个是输出...
如果是很多地方都用到, 散布四处的 global 变数, 最好描述清楚...
data_symbol_table 不要缩写成 DtSymTab, 那很难看懂, 你还得另外写注解去说...
微软有一种奇怪的习惯, 爱在变数和 function 开头写上 data type,
例如 dwStyle 表示 double word ... nCount 代表 int ...
这样做有点累赘, 因为 compiler 不管这个, 他本来就知道 data type 是什麽,
但 compiler 不会帮你检查 "头衔" 写错...
结果 type 写在名字前面只会扰乱写程式的人... (也难怪微软的程式 bug 一大堆)
不过如果你喜欢这样做, 那也随便你... :p
如果你的 function 中(包括main), local variable 超过 10 个,
那通常表示这个 function 可以再照不同功能切成小 function ...
3. 注解:
原理: 有注解非常好, 但注解太多也很危险, 和code有出入的话更不如不写
注解要做的是, 解释 code 要 "做什麽" "为啥要做这个", 而不是详细写出解法,
解法在 code 本身, 与其花时间写注解不如把 code 写得好懂一点...
而且, 花时间解释脏兮兮的烂 code 根本就是浪费时间...
注解最好写在整个 function 的开头, 以及变数定义的地方, 比较容易找,
插在 code 中的注解通常是用来做警告, 或是提示注意事项,
所以这种注解越少越容易引起注意...
只要写了注解就要负责, code 改了注解也要跟着改, code 搬动注解也要跟着搬...
* * *
好几个同学一起写 term project 的时候, 最好大家先讲好 coding style,
这样才容易互相 debug ... 但也不要为了 coding style 吵架, 每个人有每个人的
习惯, 定了其中一种方法大家 follow 就可以了, 通常大家的 coding style 不会
相差太多, 会吵架的通常都是 tab 宽度, 只要会用编辑器去调, 问题并不大...
--
我十七岁, 我不灌水...
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 218.161.3.4
1F:→ sskywind:推~~是毕业的学长吗? ^^ 推 218.160.214.54 12/04
2F:→ beagle1:嗯, 十七岁这 comment 是十年前写的 推 218.161.3.4 12/04
3F:→ beagle1:写得真好,我朗诵八遍了,到处转贴去 ^O^ 推 218.161.3.4 12/04