在之前一些關於代碼註釋的文章中,我發現,你不須要的註釋纔是最好的註釋。不要急着批判,請容許我闡述一下。首先代碼應該儘可能地簡潔,儘量地作到不須要依賴註釋就能夠理解。只有那些真的無法更易於理解的代碼,才須要咱們添加註釋。程序員
有一本很是經典的書叫《Structure and Interpretation of Computer Programs》(《電腦程序的結構和編譯》),最初發表於1985年,在序言中就代表其觀點:編程
引用工具
程序必須能便於咱們閱讀,讓機器執行只是附帶的。學習
Knuth也在他1984年發表的經典論文《Literate Programming》(《文學編程》)中秉持了相似的觀點:this
引用spa
咱們應該轉變傳統的思惟,程序再也不是告訴計算機作什麼的指令,而是向人類描述如何讓計算機作事情的文字,編程像寫文章同樣。rest
文學編程關注的主要是展示精緻的風格。程序員應該像做家同樣,認真地選擇變量名,並解釋每一個變量的意思,努力寫出易於人腦理解的程序。視頻
若是你寫出來的代碼,既能被其餘程序員理解又能成功編譯,那麼須要添加註釋的地方確定就不會不少。關於使用註釋做爲輔助工具,下面就是一個頗具表明意義的例子:blog
這段代碼取自一個已經使用多年、閉源了的系統。教程
引用
float _x = abs(x – deviceInfo->position.x) / scale;
int directionCode;
if (0 < _x & x != deviceInfo->position.x) {
if (0 > x – deviceInfo->position.x) {
directionCode = 0x04 /*left*/;
} else if (0 < x – deviceInfo->position.x) {
directionCode = 0x02 /*right*/;
}
}
上面的代碼等同於下面的代碼,可是下面的代碼可讀性更高。
引用
static const int DIRECTIONCODE_RIGHT = 0x02;static const int DIRECTIONCODE_LEFT = 0x04;static const int DIRECTIONCODE_NONE = 0x00;
int oldX = deviceInfo->position.x;
int directionCode = (x > oldX) ? DIRECTIONCODE_RIGHT : (x > oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;
須要注意的是,註釋的越多並不意味着代碼的理解性更強。固然在本案例中並無涉及到這一點。上面的註釋——若是你注意到的話——使得代碼更加顯得凌亂不堪。有時候,註釋得越精簡代碼的可讀性才越高。特別是在你必須更換使用其餘符號名的狀況下。
雖然咱們能無限次地重構和精簡代碼以免寫繁冗的註釋,可是表述本身的思考過程的方式倒是有侷限性的。
不管最後你呈現的代碼是有多麼的簡潔和清楚,代碼也不可能徹底自文檔化。可是代碼永遠也不可能取締註釋的存在。正如Jef Raskin所說:
[代碼]沒法解釋如此寫程序以及選擇該方法的緣由。從[代碼]上咱們也看不出選擇某些替代方法的理由。例如:
引用
/* A binary search turned out to be slower than the Boyer-Moore algorithm for the data sets of interest, thus we have used the more complex, but faster method even though this problem does not at first seem amenable to a string search technique. */
在A開發人員看來徹底顯而易見的東西,可能在B眼裏徹底就像霧裏看花同樣。因此咱們在寫註釋的時候,也要考慮到這一點:
下面這個可能你一清二楚
引用
$string = join(」,reverse(split(」,$string)));
反轉字符串,可是要如何才能插入到
引用
# Reverse the string
Perl文件中呢?
的確,這一點都不難。歸根究底,代碼只會告訴你程序是如何工做的,可是註釋則能說明工做的緣由。因此,下次你寫代碼的時候,不妨在這兩個方面給你的同事作個榜樣。
英文原文:Code Tells You How, Comments Tell You Why
另外若是你想更好的提高你的編程能力,學好C語言C++編程!彎道超車,快人一步!筆者這裏或許能夠幫到你~
歡迎轉行和學習編程的夥伴,利用更多的資料學習成長比本身琢磨更快哦!
免費學習資料: