大括弧不換行的壞處有什麼?為什麼有人不換行?

【請勿修改問題謝謝!如有必要請再開帖發新的問題!】

如題,為什麼我看著有大神寫的代碼大括弧一不換行就渾身難受?還有新手入門到底該不該順手換行?

Python用戶看這裡:Python的Dictionary的花括弧,應該換行嗎? - 編程


我覺得,程序員們要統一口徑,畢竟大括弧換行和不換行的佔了99%以上

這樣的才tm是異端,要消滅!!!

int main()
{ int a, b, c;
//.............
return 0;
}

還有這樣的,統統打死

int main()
{
int a, b;
//...........
return 0;
}

統統打死

還有奇怪的GNU風格

int
main()
{
int a, b;
return 0;
}

縮進都能縮出三角形來了


1、IDE有規定的時候以IDE規定為主

2、IDE沒有規定的時候通常不換行

3、按代碼行數算工資的時候必須換行


我一般都這麼寫 &> _ &<

另外我最喜歡 lAtEx 了。

= = = = = =

其實,我是偏好不換行的。

#1 經常使用的語言(JavaScript)提倡不換行的風格。

原因參見:

[1]: JavaScript語言精粹 (豆瓣)

[2]: Javascript編程風格

#2 在保證一致性的情況下,代碼冗餘度更小。

例如: if else 語句的一致性

// Bad!
if (foo &> bar)
foobar();

// Good~
if (foo &> bar) {
foobar();
}

原因:與花括弧中包裹的語句不只一個的情況保持一致,也方便後期添加語句。

在保持以上的一致性的情況下,對比換行和不換行的寫法

// 換行
if (foobar)
{
foo();
}
else
{
bar();
}

// 不換行
if (foobar) {
foo();
} else {
bar();
}

很明顯不換行更加緊湊,冗餘的行數要少。

#3 原子性

和上面的例子一樣,單看 else 部分

換行的寫法:

...

}
else
{

...

不換行的寫法:

...

} else {

...

不換行的寫法中,else 的過渡語句佔了三行,在這三行間的空隙中插入任意一段語句,原來的代碼都不能正常工作。而不換行的版本,一行卻是一個原子性的整體。

#4 視覺流不會被沖斷

如果花括弧換行,視覺流在第一個 "{" 時 被沖斷一次,到了 else 時理應被沖斷一次,結果被沖斷了三次。

對比不換行的

代碼塊被清晰的切分成兩塊,一刀不多,一刀不少。

最後的話

選擇什麼代碼風格,第一個要考慮的是別人,而不是自己。如果使用這種語言的人,大多採用這種風格,那麼就優先使用這種風格。如果是項目規定需要遵守的規範,那就更應當遵守了。

至於換行不換行、孰優孰劣見仁見智。我雖然喜歡不換行,但如果讓我去寫 C# 這種規範要求換行的語言,我也會義無反顧的換行。

(另外,知乎編輯器真是渣到爆 &> _ &< )


程序員就喜歡在一些這種無聊的問題上浪費時間。

如果把這些時間都拿去敲代碼,可控核聚變說不定都已經實現了,火星上說不定已經測試高鐵了,航天局說不定都已經接待民用航天了。

話說回來,縮進是空四格還是空兩格?


別人無所謂了,反正代碼到俺這裡都會自動格式化一次。


C/C++換行

c#換行

java,js不換行

四空格縮進

相同語言環境下重寫一段相同功能邏輯的代碼,必和上次縮寫一絲不差


前段時間,整理了一下代碼規模,重新看了自己原來團隊的規範以及google的規範。

我把其中的一段Copy出來。如果你不希望看那麼長的廢話,就看這幾句就可以了。

其實代碼規範能體現一個團隊對閱讀代碼,書寫代碼的本質思路,大部分要求括弧統一換行的往往是希望依靠換行和垂直留白,達到分塊閱讀,語義轉進的效果。而且要求左括弧的左邊不換號的的設計思路往往是希望在一屏幕能閱讀更多的代碼,尤其是google的規範。

同時回答一下作者的兩個問題,

為什麼我看著有大神寫的代碼大括弧一換行就渾身難受?

如果你已經寫不少時間代碼,這個看你的編碼習慣或者閱讀習慣,或者你更願意信仰某個社區的代碼宗教而已?,其實換行在對齊上效果是更明顯一些的。如果你沒有寫太長時間,那麼只能說,你看的代碼不夠多。你看到的千奇百怪的規範還太少。

還有新手入門到底該不該順手換行?

當然應該,養成好習慣!甚至包括適應代碼規範的習慣。

自己的原文:

如果你有興趣閱讀Artistic Style 代碼風格章節的代碼說明,就會明白完整代碼排版風格也是老奶奶的裹腳布,又臭又長一件事情。

而其實各種排版流派中最大的爭論焦點就是{}放在什麼地方。主要區別在於{是否另起一行。或者}後else是否另起一行,以及另起一行後的縮進長度,(還有}是否另起一行)。Artistic Style 的支持的代碼排版風格有11種,不同派別程序員仍然在毫不讓步地爭吵著大括弧在代碼中應該擺放的位置,在某種程度上,他已經是一種宗教,而不是一種風格之爭,關於這種爭論的底層原因,一方面可能是人關於美學的理解的不同,更重要的還是人類不願意改變習慣天性使然的結果。

由於篇幅和主題,只討論幾種主要排版風格,關於可以看看《大括弧之戰》一文和Artistic Style的說明文檔《Artistic Style》。

Allman風格主要就是格式化代碼和縮進採用換行的{},{}和上一層的代碼保持對齊. 以Berkeley黑客Eric Allman之名命名,又被稱作BSD風格,也叫Ansi風格。優點是在所有的地方大括弧都是對稱的,大部分人認同這種風格的代碼更易讀,不認同的人認為其缺點是浪費空間。

//allman風格

而KR或者java等流派的不同的代碼域也保持縮進。但是{在上一個代碼塊的末尾。而同時又根據函數代碼塊,else代碼塊等情況做了變種。

Java風格大括弧{都是緊跟上一個代碼塊。

//Java風格的排版

KR風格排版:以傳說中的Kernighan Ritchie之名命名。大括弧{ 在namespaces,
classes, and function定義時換行,在函數縮進時{內部緊跟前面的語句。,因他們的樣例代碼而被廣為接受。又因Unitx內核使用這種風格,所以又被稱作Kernel Style。

//KR的風格

為什麼很多團隊選擇Allman的代碼排版規範呢?因為兩點,一是簡單統一,{}必須換行,和上一層代碼保持對齊這個說明簡單有力,我們不用費力的告訴你特例是什麼。二是。其他風格詬病Allman風格的不節約空間這個問題解決起來有太多種方法了。最簡單的方法是把你的屏幕豎起來工作,或者找一個良好的編輯工具。

時至今日,有必要把google的規範特別是格式拿出來對比一下,因為現在很多團隊都在使用Google的規範。google的代碼示例如下,注意,其實縮進應該是2個空格。

從{}的處理上看,Google和Java的格式頗有點相識,Google格式的特點如下:

l
縮進採用2個空格

l
if () 括弧內不推薦空格

l
條件語句和 { 同行,但)和{ 之間有空格,

l
條件語句後的單行語句是否前後加{}看各自規定

l
不推薦垂直留白(空行),

l
折行每行80個字元。

從這些方面看,Google的格式要求和我們差別不小,從Google的規範可以看出,他們的思路是加強代碼的一次閱讀的量,比如縮進,
{}的換行方式,不推薦空行垂直留白。基於這個出發點可能就能明白他各個點的初衷。而我個人認為閱讀代碼也是有段落的,空行(其實也包括{的換行)都作為一種語義轉義段落來理解,初衷不同導致了代碼格式規範差異。


不換行,代碼緊湊,給別人截圖的時候逼格高


話說今天 @Mili 給我說了 Word 源碼的縮進……簡直了

哦對了因為 Word 歷史過於悠久,所以你一度能見到最老的 KR 式的函數聲明,大概就是這種

/* X C O P Y F I E L D S */
/* Copy all live fields from pcaSrc to pcaDest. */
/* %%Function:XCopyFields %%Owner:peterj %%reviewed: 6/28/89 */
EXPORT XCopyFields(fPlan, pxbc, pcaSrc, pcaDest)
BOOL fPlan;
struct XBC *pxbc;
struct CA *pcaSrc, *pcaDest;
{
int ifld = IfldNextField (pcaSrc-&>doc, pcaSrc-&>cpFirst);
CP dcpAdj = pcaDest-&>cpFirst - pcaSrc-&>cpFirst;
struct FLCD flcd;
int cfld = 0;

GetIfldFlcd (pcaSrc-&>doc, ifld, flcd);

while (ifld != ifldNil flcd.cpFirst &< pcaSrc-&>cpLim)
{
/* else not a valid range to be copying */
Assert (flcd.cpFirst + flcd.dcpInst + flcd.dcpResult &<= pcaSrc-&>cpLim);

/* copy this field to docDest */
if (fPlan)
cfld += 2 + (flcd.dcpResult ? 1 : 0);
else
{
FInsertFltDcps (flcd.flt, pcaDest-&>doc, flcd.cpFirst+dcpAdj,
flcd.dcpInst, flcd.dcpResult, flcd);

if ((uns)(flcd.flt-fltSeqLevOut)&<=(fltSeqLevNum-fltSeqLevOut)) /* invalidate auto numbered fields */ vidf.fInvalSeqLev = PdodDoc(pcaDest-&>doc)-&>fInvalSeqLev = fTrue;
}

ifld = IfldAfterFlcd (pcaSrc-&>doc, ifld, flcd);
}
if (cfld &> 0)
{
Assert(fPlan);
if (!FAssureHplcfld(pcaDest-&>doc, 0))
PostTn(pxbc, tntAbort, NULL, 0);
else
PostTn(pxbc, tntHplc, PdodDoc(pcaDest-&>doc)-&>hplcfld, cfld);
}
}


空格黨被深刻滴教育了

----------------

那麼問題來了,你們用tab還是space


你看,我用python就不會有這種問題了~

前排售賣瓜子租賃板凳,瓜子五毛,板凳一塊~


我的換行方法是

左大括弧左邊有換行符

左大括弧右邊有換行符

右大括弧左邊有換行符

右大括弧右邊有換行符

有些人的不換行的方法是

左大括弧左邊沒有換行符

左大括弧右邊有換行符

右大括弧左邊有換行符

右大括弧右邊有換行符

一點都不對稱,這個人寫出來的程序肯定不能看。正確的不換行的方法,當然是要對稱的:

左大括弧左邊沒有換行符

左大括弧右邊有換行符

右大括弧左邊有換行符

右大括弧右邊沒有換行符


輪子哥說的正確且對稱的不換行方式:

左大括弧左邊沒有換行符

左大括弧右邊有換行符

右大括弧左邊有換行符

右大括弧右邊沒有換行符

總結成一句話,就是:括弧內側換行,外側不換,即:

所以,一款優秀的IDE應該帶有傾斜的滾動條。


C語言沒定標準,所以亂了。

C++也沒定標準,所以也亂了。

Java定了標準,所以整齊了,人家是不換行。

python沒這個問題,然而python有個冒號,這個冒號是不換行的,而它的含義與左大括弧相同。

爭得面紅耳赤的各位不妨思考一下為什麼在C和C++基礎上發明的Java語言以不換行為標準。


完全不知道你們在說什麼


//輪子文字版看起來太費勁。
//翻譯下
if (condition)
{
//輪子的換行
}
else

if (condition) {
//有些人的不換行
}
else

if (condition) {
//正確的不換行
} else


新手入門可以參照Oracle的編碼規範:http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-142311.html#449

每個大公司都有自己的編碼規範,我們公司就是以這個為標準。


Lisp 就笑笑看你們吵



大作業,老師說要300行

第一次大括弧不換行長度不夠,怒換之達到要求。從此擼代碼一律大括弧換行

===========================================================

那些吐槽規定行數的統一回復:

當時我們大一新生好嗎,才學了54課時的C語言,數據結構什麼都不會,根本寫不出什麼高效代碼,另外大作業沒有確定的題目,老師規定行數是為了保證我們最終的程序實現了某個有意義的功能。否則,絕壁有人if else出個100行的代碼說老師我寫了個列印一周七天星期幾的代碼。


推薦閱讀:

C語言內存中是否存在一個區域,存儲著變數的符號,變數的類型和變數的首地址?
c語言為什麼可以通過變數名來訪問變數的值?變數的值是存儲在計算機中,那麼變數名也同時存儲在計算機中嗎?
C 語言有什麼奇技淫巧?
如何快速便捷地打小括弧?
c語言里的char大小到底是4還是1?

TAG:編程 | Java | C編程語言 | C |