在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Google編程風(fēng)格指南(六)

C語(yǔ)言專家集中營(yíng) ? 來(lái)源:未知 ? 作者:李倩 ? 2018-09-27 18:18 ? 次閱讀

9. 格式

每個(gè)人都可能有自己的代碼風(fēng)格和格式, 但如果一個(gè)項(xiàng)目中的所有人都遵循同一風(fēng)格的話, 這個(gè)項(xiàng)目就能更順利地進(jìn)行. 每個(gè)人未必能同意下述的每一處格式規(guī)則, 而且其中的不少規(guī)則需要一定時(shí)間的適應(yīng), 但整個(gè)項(xiàng)目服從統(tǒng)一的編程風(fēng)格是很重要的, 只有這樣才能讓所有人輕松地閱讀和理解代碼.

為了幫助你正確的格式化代碼, 我們寫了一個(gè)emacs 配置文件.

9.1. 行長(zhǎng)度

總述

每一行代碼字符數(shù)不超過(guò) 80.

我們也認(rèn)識(shí)到這條規(guī)則是有爭(zhēng)議的, 但很多已有代碼都遵照這一規(guī)則, 因此我們感覺(jué)一致性更重要.

優(yōu)點(diǎn)

提倡該原則的人認(rèn)為強(qiáng)迫他們調(diào)整編輯器窗口大小是很野蠻的行為. 很多人同時(shí)并排開(kāi)幾個(gè)代碼窗口, 根本沒(méi)有多余的空間拉伸窗口. 大家都把窗口最大尺寸加以限定, 并且 80 列寬是傳統(tǒng)標(biāo)準(zhǔn). 那么為什么要改變呢?

缺點(diǎn)

反對(duì)該原則的人則認(rèn)為更寬的代碼行更易閱讀. 80 列的限制是上個(gè)世紀(jì) 60 年代的大型機(jī)的古板缺陷; 現(xiàn)代設(shè)備具有更寬的顯示屏, 可以很輕松地顯示更多代碼.

結(jié)論

80 個(gè)字符是最大值.

如果無(wú)法在不傷害易讀性的條件下進(jìn)行斷行, 那么注釋行可以超過(guò) 80 個(gè)字符, 這樣可以方便復(fù)制粘貼. 例如, 帶有命令示例或 URL 的行可以超過(guò) 80 個(gè)字符.

包含長(zhǎng)路徑的#include語(yǔ)句可以超出80列.

頭文件保護(hù)可以無(wú)視該原則.

9.2. 非 ASCII 字符

總述

盡量不使用非 ASCII 字符, 使用時(shí)必須使用 UTF-8 編碼.

說(shuō)明

即使是英文, 也不應(yīng)將用戶界面的文本硬編碼到源代碼中, 因此非 ASCII 字符應(yīng)當(dāng)很少被用到. 特殊情況下可以適當(dāng)包含此類字符. 例如, 代碼分析外部數(shù)據(jù)文件時(shí), 可以適當(dāng)硬編碼數(shù)據(jù)文件中作為分隔符的非 ASCII 字符串; 更常見(jiàn)的是 (不需要本地化的) 單元測(cè)試代碼可能包含非 ASCII 字符串. 此類情況下, 應(yīng)使用 UTF-8 編碼, 因?yàn)楹芏喙ぞ叨伎梢岳斫夂吞幚?UTF-8 編碼.

十六進(jìn)制編碼也可以, 能增強(qiáng)可讀性的情況下尤其鼓勵(lì) —— 比如"\xEF\xBB\xBF", 或者更簡(jiǎn)潔地寫作u8"\uFEFF", 在 Unicode 中是零寬度 無(wú)間斷的間隔符號(hào), 如果不用十六進(jìn)制直接放在 UTF-8 格式的源文件中, 是看不到的.

(Yang.Y 注:"\xEF\xBB\xBF"通常用作 UTF-8 with BOM 編碼標(biāo)記)

使用u8前綴把帶uXXXX轉(zhuǎn)義序列的字符串字面值編碼成 UTF-8. 不要用在本身就帶 UTF-8 字符的字符串字面值上, 因?yàn)槿绻幾g器不把源代碼識(shí)別成 UTF-8, 輸出就會(huì)出錯(cuò).

別用 C++11 的char16_t和char32_t, 它們和 UTF-8 文本沒(méi)有關(guān)系,wchar_t同理, 除非你寫的代碼要調(diào)用 Windows API, 后者廣泛使用了wchar_t.

9.3. 空格還是制表位

總述

只使用空格, 每次縮進(jìn) 2 個(gè)空格.

說(shuō)明

我們使用空格縮進(jìn). 不要在代碼中使用制表符. 你應(yīng)該設(shè)置編輯器將制表符轉(zhuǎn)為空格.

9.4. 函數(shù)聲明與定義

總述

返回類型和函數(shù)名在同一行, 參數(shù)也盡量放在同一行, 如果放不下就對(duì)形參分行, 分行方式與函數(shù)調(diào)用一致.

說(shuō)明

函數(shù)看上去像這樣:

ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) { DoSomething(); ...}

如果同一行文本太多, 放不下所有參數(shù):

ReturnType ClassName::ReallyLongFunctionName(Type par_name1, Type par_name2, Type par_name3) { DoSomething(); ...}

甚至連第一個(gè)參數(shù)都放不下:

ReturnType LongClassName::ReallyReallyReallyLongFunctionName( Type par_name1, // 4 space indent Type par_name2, Type par_name3) { DoSomething(); // 2 space indent ...}

注意以下幾點(diǎn):

使用好的參數(shù)名.

只有在參數(shù)未被使用或者其用途非常明顯時(shí), 才能省略參數(shù)名.

如果返回類型和函數(shù)名在一行放不下, 分行.

如果返回類型與函數(shù)聲明或定義分行了, 不要縮進(jìn).

左圓括號(hào)總是和函數(shù)名在同一行.

函數(shù)名和左圓括號(hào)間永遠(yuǎn)沒(méi)有空格.

圓括號(hào)與參數(shù)間沒(méi)有空格.

左大括號(hào)總在最后一個(gè)參數(shù)同一行的末尾處, 不另起新行.

右大括號(hào)總是單獨(dú)位于函數(shù)最后一行, 或者與左大括號(hào)同一行.

右圓括號(hào)和左大括號(hào)間總是有一個(gè)空格.

所有形參應(yīng)盡可能對(duì)齊.

缺省縮進(jìn)為 2 個(gè)空格.

換行后的參數(shù)保持 4 個(gè)空格的縮進(jìn).

未被使用的參數(shù), 或者根據(jù)上下文很容易看出其用途的參數(shù), 可以省略參數(shù)名:

class Foo { public: Foo(Foo&&); Foo(const Foo&); Foo& operator=(Foo&&); Foo& operator=(const Foo&);};

未被使用的參數(shù)如果其用途不明顯的話, 在函數(shù)定義處將參數(shù)名注釋起來(lái):

class Shape { public: virtual void Rotate(double radians) = 0;};class Circle : public Shape { public: void Rotate(double radians) override;};void Circle::Rotate(double /*radians*/) {}// 差 - 如果將來(lái)有人要實(shí)現(xiàn), 很難猜出變量的作用.void Circle::Rotate(double) {}

屬性, 和展開(kāi)為屬性的宏, 寫在函數(shù)聲明或定義的最前面, 即返回類型之前:

MUST_USE_RESULT bool IsOK();

9.5. Lambda 表達(dá)式

總述

Lambda 表達(dá)式對(duì)形參和函數(shù)體的格式化和其他函數(shù)一致; 捕獲列表同理, 表項(xiàng)用逗號(hào)隔開(kāi).

說(shuō)明

若用引用捕獲, 在變量名和&之間不留空格.

int x = 0;auto add_to_x = [&x](int n) { x += n; };

短 lambda 就寫得和內(nèi)聯(lián)函數(shù)一樣.

std::set blacklist = {7, 8, 9};std::vector digits = {3, 9, 1, 8, 4, 7, 1};digits.erase(std::remove_if(digits.begin(), digits.end(), [&blacklist](int i) { return blacklist.find(i) != blacklist.end(); }), digits.end());

9.6. 函數(shù)調(diào)用

總述

要么一行寫完函數(shù)調(diào)用, 要么在圓括號(hào)里對(duì)參數(shù)分行, 要么參數(shù)另起一行且縮進(jìn)四格. 如果沒(méi)有其它顧慮的話, 盡可能精簡(jiǎn)行數(shù), 比如把多個(gè)參數(shù)適當(dāng)?shù)胤旁谕恍欣?

說(shuō)明

函數(shù)調(diào)用遵循如下形式:

bool retval = DoSomething(argument1, argument2, argument3);

如果同一行放不下, 可斷為多行, 后面每一行都和第一個(gè)實(shí)參對(duì)齊, 左圓括號(hào)后和右圓括號(hào)前不要留空格:

bool retval = DoSomething(averyveryveryverylongargument1, argument2, argument3);

參數(shù)也可以放在次行, 縮進(jìn)四格:

if (...) { ... ... if (...) { DoSomething( argument1, argument2, // 4 空格縮進(jìn) argument3, argument4); }

把多個(gè)參數(shù)放在同一行以減少函數(shù)調(diào)用所需的行數(shù), 除非影響到可讀性. 有人認(rèn)為把每個(gè)參數(shù)都獨(dú)立成行, 不僅更好讀, 而且方便編輯參數(shù). 不過(guò), 比起所謂的參數(shù)編輯, 我們更看重可讀性, 且后者比較好辦:

如果一些參數(shù)本身就是略復(fù)雜的表達(dá)式, 且降低了可讀性, 那么可以直接創(chuàng)建臨時(shí)變量描述該表達(dá)式, 并傳遞給函數(shù):

int my_heuristic = scores[x] * y + bases[x];bool retval = DoSomething(my_heuristic, x, y, z);

或者放著不管, 補(bǔ)充上注釋:

bool retval = DoSomething(scores[x] * y + bases[x], // Score heuristic. x, y, z);

如果某參數(shù)獨(dú)立成行, 對(duì)可讀性更有幫助的話, 那也可以如此做. 參數(shù)的格式處理應(yīng)當(dāng)以可讀性而非其他作為最重要的原則.

此外, 如果一系列參數(shù)本身就有一定的結(jié)構(gòu), 可以酌情地按其結(jié)構(gòu)來(lái)決定參數(shù)格式:

// 通過(guò) 3x3 矩陣轉(zhuǎn)換 widget.my_widget.Transform(x1, x2, x3, y1, y2, y3, z1, z2, z3);

9.7. 列表初始化格式

總述

您平時(shí)怎么格式化函數(shù)調(diào)用, 就怎么格式化列表初始化.

說(shuō)明

如果列表初始化伴隨著名字, 比如類型或變量名, 格式化時(shí)將將名字視作函數(shù)調(diào)用名,{}視作函數(shù)調(diào)用的括號(hào). 如果沒(méi)有名字, 就視作名字長(zhǎng)度為零.

// 一行列表初始化示范.return {foo, bar};functioncall({foo, bar});pair p{foo, bar};// 當(dāng)不得不斷行時(shí).SomeFunction( {"assume a zero-length name before {"}, // 假設(shè)在 { 前有長(zhǎng)度為零的名字. some_other_function_parameter);SomeType variable{ some, other, values, {"assume a zero-length name before {"}, // 假設(shè)在 { 前有長(zhǎng)度為零的名字. SomeOtherType{ "Very long string requiring the surrounding breaks.", // 非常長(zhǎng)的字符串, 前后都需要斷行. some, other values}, SomeOtherType{"Slightly shorter string", // 稍短的字符串. some, other, values}};SomeType variable{ "This is too long to fit all in one line"}; // 字符串過(guò)長(zhǎng), 因此無(wú)法放在同一行.MyType m = { // 注意了, 您可以在 { 前斷行. superlongvariablename1, superlongvariablename2, {short, interior, list}, {interiorwrappinglist, interiorwrappinglist2}};

9.9. 條件語(yǔ)句

總述

傾向于不在圓括號(hào)內(nèi)使用空格. 關(guān)鍵字if和else另起一行.

說(shuō)明

對(duì)基本條件語(yǔ)句有兩種可以接受的格式. 一種在圓括號(hào)和條件之間有空格, 另一種沒(méi)有.

最常見(jiàn)的是沒(méi)有空格的格式. 哪一種都可以, 最重要的是保持一致. 如果你是在修改一個(gè)文件, 參考當(dāng)前已有格式. 如果是寫新的代碼, 參考目錄下或項(xiàng)目中其它文件. 還在猶豫的話, 就不要加空格了.

if (condition) { // 圓括號(hào)里沒(méi)有空格. ... // 2 空格縮進(jìn).} else if (...) { // else 與 if 的右括號(hào)同一行. ...} else { ...}

如果你更喜歡在圓括號(hào)內(nèi)部加空格:

if ( condition ) { // 圓括號(hào)與空格緊鄰 - 不常見(jiàn) ... // 2 空格縮進(jìn).} else { // else 與 if 的右括號(hào)同一行. ...}

注意所有情況下if和左圓括號(hào)間都有個(gè)空格. 右圓括號(hào)和左大括號(hào)之間也要有個(gè)空格:

if(condition) // 差 - IF 后面沒(méi)空格.if (condition){ // 差 - { 前面沒(méi)空格.if(condition){ // 變本加厲地差.if (condition) { // 好 - IF 和 { 都與空格緊鄰.

如果能增強(qiáng)可讀性, 簡(jiǎn)短的條件語(yǔ)句允許寫在同一行. 只有當(dāng)語(yǔ)句簡(jiǎn)單并且沒(méi)有使用else子句時(shí)使用:

if (x == kFoo) return new Foo();if (x == kBar) return new Bar();

如果語(yǔ)句有else分支則不允許:

// 不允許 - 當(dāng)有 ELSE 分支時(shí) IF 塊卻寫在同一行if (x) DoThis();else DoThat();

通常, 單行語(yǔ)句不需要使用大括號(hào), 如果你喜歡用也沒(méi)問(wèn)題; 復(fù)雜的條件或循環(huán)語(yǔ)句用大括號(hào)可讀性會(huì)更好. 也有一些項(xiàng)目要求if必須總是使用大括號(hào):

if (condition) DoSomething(); // 2 空格縮進(jìn).if (condition) { DoSomething(); // 2 空格縮進(jìn).}

但如果語(yǔ)句中某個(gè)if-else分支使用了大括號(hào)的話, 其它分支也必須使用:

// 不可以這樣子 - IF 有大括號(hào) ELSE 卻沒(méi)有.if (condition) { foo;} else bar;// 不可以這樣子 - ELSE 有大括號(hào) IF 卻沒(méi)有.if (condition) foo;else { bar;}// 只要其中一個(gè)分支用了大括號(hào), 兩個(gè)分支都要用上大括號(hào).if (condition) { foo;} else { bar;}

9.9. 循環(huán)和開(kāi)關(guān)選擇語(yǔ)句

總述

switch語(yǔ)句可以使用大括號(hào)分段, 以表明 cases 之間不是連在一起的. 在單語(yǔ)句循環(huán)里, 括號(hào)可用可不用. 空循環(huán)體應(yīng)使用{}或continue.

說(shuō)明

switch語(yǔ)句中的case塊可以使用大括號(hào)也可以不用, 取決于你的個(gè)人喜好. 如果用的話, 要按照下文所述的方法.

如果有不滿足case條件的枚舉值,switch應(yīng)該總是包含一個(gè)default匹配 (如果有輸入值沒(méi)有 case 去處理, 編譯器將給出 warning). 如果default應(yīng)該永遠(yuǎn)執(zhí)行不到, 簡(jiǎn)單的加條assert:

switch (var) { case 0: { // 2 空格縮進(jìn) ... // 4 空格縮進(jìn) break; } case 1: { ... break; } default: { assert(false); }}

在單語(yǔ)句循環(huán)里, 括號(hào)可用可不用:

for (int i = 0; i < kSomeNumber; ++i) printf("I love you\n");for (int i = 0; i < kSomeNumber; ++i) { printf("I take it back\n");}

空循環(huán)體應(yīng)使用{}或continue, 而不是一個(gè)簡(jiǎn)單的分號(hào).

while (condition) { // 反復(fù)循環(huán)直到條件失效.}for (int i = 0; i < kSomeNumber; ++i) {} // 可 - 空循環(huán)體.while (condition) continue; // 可 - contunue 表明沒(méi)有邏輯.while (condition); // 差 - 看起來(lái)僅僅只是 while/loop 的部分之一.

9.10. 指針和引用表達(dá)式

總述

句點(diǎn)或箭頭前后不要有空格. 指針/地址操作符 (*,&) 之后不能有空格.

說(shuō)明

下面是指針和引用表達(dá)式的正確使用范例:

x = *p;p = &x;x = r.y;x = r->y;

注意:

在訪問(wèn)成員時(shí), 句點(diǎn)或箭頭前后沒(méi)有空格.

指針操作符*或&后沒(méi)有空格.

在聲明指針變量或參數(shù)時(shí), 星號(hào)與類型或變量名緊挨都可以:

// 好, 空格前置.char *c;const string &str;// 好, 空格后置.char* c;const string& str;int x, *y; // 不允許 - 在多重聲明中不能使用 & 或 *char * c; // 差 - * 兩邊都有空格const string & str; // 差 - & 兩邊都有空格.

在單個(gè)文件內(nèi)要保持風(fēng)格一致, 所以, 如果是修改現(xiàn)有文件, 要遵照該文件的風(fēng)格.

9.11. 布爾表達(dá)式

總述

如果一個(gè)布爾表達(dá)式超過(guò)標(biāo)準(zhǔn)行寬, 斷行方式要統(tǒng)一一下.

說(shuō)明

下例中, 邏輯與 (&&) 操作符總位于行尾:

if (this_one_thing > this_other_thing && a_third_thing == a_fourth_thing && yet_another && last_one) { ...}

注意, 上例的邏輯與 (&&) 操作符均位于行尾. 這個(gè)格式在 Google 里很常見(jiàn), 雖然把所有操作符放在開(kāi)頭也可以. 可以考慮額外插入圓括號(hào), 合理使用的話對(duì)增強(qiáng)可讀性是很有幫助的. 此外, 直接用符號(hào)形式的操作符, 比如&&和~, 不要用詞語(yǔ)形式的and和compl.

9.12. 函數(shù)返回值

總述

不要在return表達(dá)式里加上非必須的圓括號(hào).

說(shuō)明

只有在寫x=expr要加上括號(hào)的時(shí)候才在returnexpr;里使用括號(hào).

return result; // 返回值很簡(jiǎn)單, 沒(méi)有圓括號(hào).// 可以用圓括號(hào)把復(fù)雜表達(dá)式圈起來(lái), 改善可讀性.return (some_long_condition && another_condition);return (value); // 畢竟您從來(lái)不會(huì)寫 var = (value);return(result); // return 可不是函數(shù)!

9.13. 變量及數(shù)組初始化

總述

用=,()和{}均可.

說(shuō)明

您可以用=,()和{}, 以下的例子都是正確的:

int x = 3;int x(3);int x{3};string name("Some Name");string name = "Some Name";string name{"Some Name"};

請(qǐng)務(wù)必小心列表初始化{...}用std::initializer_list構(gòu)造函數(shù)初始化出的類型. 非空列表初始化就會(huì)優(yōu)先調(diào)用std::initializer_list, 不過(guò)空列表初始化除外, 后者原則上會(huì)調(diào)用默認(rèn)構(gòu)造函數(shù). 為了強(qiáng)制禁用std::initializer_list構(gòu)造函數(shù), 請(qǐng)改用括號(hào).

vector v(100, 1); // 內(nèi)容為 100 個(gè) 1 的向量.vector v{100, 1}; // 內(nèi)容為 100 和 1 的向量.

此外, 列表初始化不允許整型類型的四舍五入, 這可以用來(lái)避免一些類型上的編程失誤.

int pi(3.14); // 好 - pi == 3.int pi{3.14}; // 編譯錯(cuò)誤: 縮窄轉(zhuǎn)換.

9.14. 預(yù)處理指令

總述

預(yù)處理指令不要縮進(jìn), 從行首開(kāi)始.

說(shuō)明

即使預(yù)處理指令位于縮進(jìn)代碼塊中, 指令也應(yīng)從行首開(kāi)始.

// 好 - 指令從行首開(kāi)始 if (lopsided_score) {#if DISASTER_PENDING // 正確 - 從行首開(kāi)始 DropEverything();# if NOTIFY // 非必要 - # 后跟空格 NotifyClient();# endif#endif BackToNormal(); }// 差 - 指令縮進(jìn) if (lopsided_score) { #if DISASTER_PENDING // 差 - "#if" 應(yīng)該放在行開(kāi)頭 DropEverything(); #endif // 差 - "#endif" 不要縮進(jìn) BackToNormal(); }

9.15. 類格式

總述

訪問(wèn)控制塊的聲明依次序是public:,protected:,private:, 每個(gè)都縮進(jìn) 1 個(gè)空格.

說(shuō)明

類聲明 (下面的代碼中缺少注釋, 參考類注釋) 的基本格式如下:

class MyClass : public OtherClass { public: // 注意有一個(gè)空格的縮進(jìn) MyClass(); // 標(biāo)準(zhǔn)的兩空格縮進(jìn) explicit MyClass(int var); ~MyClass() {} void SomeFunction(); void SomeFunctionThatDoesNothing() { } void set_some_var(int var) { some_var_ = var; } int some_var() const { return some_var_; } private: bool SomeInternalFunction(); int some_var_; int some_other_var_;};

注意事項(xiàng):

所有基類名應(yīng)在 80 列限制下盡量與子類名放在同一行.

關(guān)鍵詞public:,protected:,private:要縮進(jìn) 1 個(gè)空格.

除第一個(gè)關(guān)鍵詞 (一般是public) 外, 其他關(guān)鍵詞前要空一行. 如果類比較小的話也可以不空.

這些關(guān)鍵詞后不要保留空行.

public放在最前面, 然后是protected, 最后是private.

關(guān)于聲明順序的規(guī)則請(qǐng)參考聲明順序一節(jié).

9.16. 構(gòu)造函數(shù)初始值列表

總述

構(gòu)造函數(shù)初始化列表放在同一行或按四格縮進(jìn)并排多行.

說(shuō)明

下面兩種初始值列表方式都可以接受:

// 如果所有變量能放在同一行:MyClass::MyClass(int var) : some_var_(var) { DoSomething();}// 如果不能放在同一行,// 必須置于冒號(hào)后, 并縮進(jìn) 4 個(gè)空格MyClass::MyClass(int var) : some_var_(var), some_other_var_(var + 1) { DoSomething();}// 如果初始化列表需要置于多行, 將每一個(gè)成員放在單獨(dú)的一行// 并逐行對(duì)齊MyClass::MyClass(int var) : some_var_(var), // 4 space indent some_other_var_(var + 1) { // lined up DoSomething();}// 右大括號(hào) } 可以和左大括號(hào) { 放在同一行// 如果這樣做合適的話MyClass::MyClass(int var) : some_var_(var) {}

9.17. 命名空間格式化

總述

命名空間內(nèi)容不縮進(jìn).

說(shuō)明

命名空間不要增加額外的縮進(jìn)層次, 例如:

namespace {void foo() { // 正確. 命名空間內(nèi)沒(méi)有額外的縮進(jìn). ...}} // namespace

不要在命名空間內(nèi)縮進(jìn):

namespace { // 錯(cuò), 縮進(jìn)多余了. void foo() { ... }} // namespace

聲明嵌套命名空間時(shí), 每個(gè)命名空間都獨(dú)立成行.

namespace foo {namespace bar {

9.19. 水平留白

總述

水平留白的使用根據(jù)在代碼中的位置決定. 永遠(yuǎn)不要在行尾添加沒(méi)意義的留白.

說(shuō)明

通用

void f(bool b) { // 左大括號(hào)前總是有空格. ...int i = 0; // 分號(hào)前不加空格.// 列表初始化中大括號(hào)內(nèi)的空格是可選的.// 如果加了空格, 那么兩邊都要加上.int x[] = { 0 };int x[] = {0};// 繼承與初始化列表中的冒號(hào)前后恒有空格.class Foo : public Bar { public: // 對(duì)于單行函數(shù)的實(shí)現(xiàn), 在大括號(hào)內(nèi)加上空格 // 然后是函數(shù)實(shí)現(xiàn) Foo(int b) : Bar(), baz_(b) {} // 大括號(hào)里面是空的話, 不加空格. void Reset() { baz_ = 0; } // 用括號(hào)把大括號(hào)與實(shí)現(xiàn)分開(kāi). ...

添加冗余的留白會(huì)給其他人編輯時(shí)造成額外負(fù)擔(dān). 因此, 行尾不要留空格. 如果確定一行代碼已經(jīng)修改完畢, 將多余的空格去掉; 或者在專門清理空格時(shí)去掉(尤其是在沒(méi)有其他人在處理這件事的時(shí)候). (Yang.Y 注: 現(xiàn)在大部分代碼編輯器稍加設(shè)置后, 都支持自動(dòng)刪除行首/行尾空格, 如果不支持, 考慮換一款編輯器或 IDE)

循環(huán)和條件語(yǔ)句

if (b) { // if 條件語(yǔ)句和循環(huán)語(yǔ)句關(guān)鍵字后均有空格.} else { // else 前后有空格.}while (test) {} // 圓括號(hào)內(nèi)部不緊鄰空格.switch (i) {for (int i = 0; i < 5; ++i) {switch ( i ) { // 循環(huán)和條件語(yǔ)句的圓括號(hào)里可以與空格緊鄰.if ( test ) { // 圓括號(hào), 但這很少見(jiàn). 總之要一致.for ( int i = 0; i < 5; ++i ) {for ( ; i < 5 ; ++i) { // 循環(huán)里內(nèi) ; 后恒有空格, ; ?前可以加個(gè)空格.switch (i) { case 1: // switch case 的冒號(hào)前無(wú)空格. ... case 2: break; // 如果冒號(hào)有代碼, 加個(gè)空格.

操作符

// 賦值運(yùn)算符前后總是有空格.x = 0;// 其它二元操作符也前后恒有空格, 不過(guò)對(duì)于表達(dá)式的子式可以不加空格.// 圓括號(hào)內(nèi)部沒(méi)有緊鄰空格.v = w * x + y / z;v = w*x + y/z;v = w * (x + z);// 在參數(shù)和一元操作符之間不加空格.x = -5;++x;if (x && !y) ...

模板和轉(zhuǎn)換

// 尖括號(hào)(< and >) 不與空格緊鄰, < 前沒(méi)有空格, > 和 ( 之間也沒(méi)有.vector x;y = static_cast(x);// 在類型與指針操作符之間留空格也可以, 但要保持一致.vector x;

9.19. 垂直留白

總述

垂直留白越少越好.

說(shuō)明

這不僅僅是規(guī)則而是原則問(wèn)題了: 不在萬(wàn)不得已, 不要使用空行. 尤其是: 兩個(gè)函數(shù)定義之間的空行不要超過(guò) 2 行, 函數(shù)體首尾不要留空行, 函數(shù)體中也不要隨意添加空行.

基本原則是: 同一屏可以顯示的代碼越多, 越容易理解程序的控制流. 當(dāng)然, 過(guò)于密集的代碼塊和過(guò)于疏松的代碼塊同樣難看, 這取決于你的判斷. 但通常是垂直留白越少越好.

下面的規(guī)則可以讓加入的空行更有效:

函數(shù)體內(nèi)開(kāi)頭或結(jié)尾的空行可讀性微乎其微.

在多重 if-else 塊里加空行或許有點(diǎn)可讀性.

譯者 (YuleFox) 筆記

對(duì)于代碼格式, 因人, 系統(tǒng)而異各有優(yōu)缺點(diǎn), 但同一個(gè)項(xiàng)目中遵循同一標(biāo)準(zhǔn)還是有必要的;

行寬原則上不超過(guò) 80 列, 把 22 寸的顯示屏都占完, 怎么也說(shuō)不過(guò)去;

盡量不使用非 ASCII 字符, 如果使用的話, 參考 UTF-8 格式 (尤其是 UNIX/Linux 下, Windows 下可以考慮寬字符), 盡量不將字符串常量耦合到代碼中, 比如獨(dú)立出資源文件, 這不僅僅是風(fēng)格問(wèn)題了;

UNIX/Linux 下無(wú)條件使用空格, MSVC 的話使用 Tab 也無(wú)可厚非;

函數(shù)參數(shù), 邏輯條件, 初始化列表: 要么所有參數(shù)和函數(shù)名放在同一行, 要么所有參數(shù)并排分行;

除函數(shù)定義的左大括號(hào)可以置于行首外, 包括函數(shù)/類/結(jié)構(gòu)體/枚舉聲明, 各種語(yǔ)句的左大括號(hào)置于行尾, 所有右大括號(hào)獨(dú)立成行;

./->操作符前后不留空格,*/&不要前后都留, 一個(gè)就可, 靠左靠右依各人喜好;

預(yù)處理指令/命名空間不使用額外縮進(jìn), 類/結(jié)構(gòu)體/枚舉/函數(shù)/語(yǔ)句使用縮進(jìn);

初始化用=還是()依個(gè)人喜好, 統(tǒng)一就好;

return不要加();

水平/垂直留白不要濫用, 怎么易讀怎么來(lái).

關(guān)于 UNIX/Linux 風(fēng)格為什么要把左大括號(hào)置于行尾 (.cc文件的函數(shù)實(shí)現(xiàn)處, 左大括號(hào)位于行首), 我的理解是代碼看上去比較簡(jiǎn)約, 想想行首除了函數(shù)體被一對(duì)大括號(hào)封在一起之外, 只有右大括號(hào)的代碼看上去確實(shí)也舒服; Windows 風(fēng)格將左大括號(hào)置于行首的優(yōu)點(diǎn)是匹配情況一目了然.

譯者(acgtyrant)筆記

80 行限制事實(shí)上有助于避免代碼可讀性失控, 比如超多重嵌套塊, 超多重函數(shù)調(diào)用等等.

Linux 上設(shè)置好了 Locale 就幾乎一勞永逸設(shè)置好所有開(kāi)發(fā)環(huán)境的編碼, 不像奇葩的 Windows.

Google 強(qiáng)調(diào)有一對(duì) if-else 時(shí), 不論有沒(méi)有嵌套, 都要有大括號(hào). Apple 正好有栽過(guò)跟頭.

其實(shí)我主張指針/地址操作符與變量名緊鄰,int*a,bvsint*a,b, 新手會(huì)誤以為前者的b是int*變量, 但后者就不一樣了, 高下立判.

在這風(fēng)格指南里我才剛知道 C++ 原來(lái)還有所謂的Alternative operator representations, 大概沒(méi)人用吧.

注意構(gòu)造函數(shù)初始值列表(Constructer Initializer List)與列表初始化(Initializer List)是兩碼事, 我就差點(diǎn)混淆了它們的翻譯.

事實(shí)上, 如果您熟悉英語(yǔ)本身的書寫規(guī)則, 就會(huì)發(fā)現(xiàn)該風(fēng)格指南在格式上的規(guī)定與英語(yǔ)語(yǔ)法相當(dāng)一脈相承. 比如普通標(biāo)點(diǎn)符號(hào)和單詞后面還有文本的話, 總會(huì)留一個(gè)空格; 特殊符號(hào)與單詞之間就不用留了, 比如if(true)中的圓括號(hào)與true.

本風(fēng)格指南沒(méi)有明確規(guī)定 void 函數(shù)里要不要用 return 語(yǔ)句, 不過(guò)就 Google 開(kāi)源項(xiàng)目 leveldb 并沒(méi)有寫; 此外從Is a blank return statement at the end of a function whos return type is void necessary?來(lái)看,return;比return;更約定俗成(事實(shí)上 cpplint 會(huì)對(duì)后者報(bào)錯(cuò), 指出分號(hào)前有多余的空格), 且可用來(lái)提前跳出函數(shù)棧.

10. 規(guī)則特例

前面說(shuō)明的編程習(xí)慣基本都是強(qiáng)制性的. 但所有優(yōu)秀的規(guī)則都允許例外, 這里就是探討這些特例.

10.1. 現(xiàn)有不合規(guī)范的代碼

總述

對(duì)于現(xiàn)有不符合既定編程風(fēng)格的代碼可以網(wǎng)開(kāi)一面.

說(shuō)明

當(dāng)你修改使用其他風(fēng)格的代碼時(shí), 為了與代碼原有風(fēng)格保持一致可以不使用本指南約定. 如果不放心, 可以與代碼原作者或現(xiàn)在的負(fù)責(zé)人員商討. 記住,一致性也包括原有的一致性.

10.2. Windows 代碼

總述

Windows 程序員有自己的編程習(xí)慣, 主要源于 Windows 頭文件和其它 Microsoft 代碼. 我們希望任何人都可以順利讀懂你的代碼, 所以針對(duì)所有平臺(tái)的 C++ 編程只給出一個(gè)單獨(dú)的指南.

說(shuō)明

如果你習(xí)慣使用 Windows 編碼風(fēng)格, 這兒有必要重申一下某些你可能會(huì)忘記的指南:

不要使用匈牙利命名法 (比如把整型變量命名成iNum). 使用 Google 命名約定, 包括對(duì)源文件使用.cc擴(kuò)展名.

Windows 定義了很多原生類型的同義詞 (YuleFox 注: 這一點(diǎn), 我也很反感), 如DWORD,HANDLE等等. 在調(diào)用 Windows API 時(shí)這是完全可以接受甚至鼓勵(lì)的. 即使如此, 還是盡量使用原有的 C++ 類型, 例如使用constTCHAR*而不是LPCTSTR.

使用 Microsoft Visual C++ 進(jìn)行編譯時(shí), 將警告級(jí)別設(shè)置為 3 或更高, 并將所有警告(warnings)當(dāng)作錯(cuò)誤(errors)處理.

不要使用#pragmaonce; 而應(yīng)該使用 Google 的頭文件保護(hù)規(guī)則. 頭文件保護(hù)的路徑應(yīng)該相對(duì)于項(xiàng)目根目錄 (Yang.Y 注: 如#ifndefSRC_DIR_BAR_H_, 參考#define 保護(hù)一節(jié)).

除非萬(wàn)不得已, 不要使用任何非標(biāo)準(zhǔn)的擴(kuò)展, 如#pragma和__declspec. 使用__declspec(dllimport)和__declspec(dllexport)是允許的, 但必須通過(guò)宏來(lái)使用, 比如DLLIMPORT和DLLEXPORT, 這樣其他人在分享使用這些代碼時(shí)可以很容易地禁用這些擴(kuò)展.

然而, 在 Windows 上仍然有一些我們偶爾需要違反的規(guī)則:

通常我們禁止使用多重繼承, 但在使用 COM 和 ATL/WTL 類時(shí)可以使用多重繼承. 為了實(shí)現(xiàn) COM 或 ATL/WTL 類/接口, 你可能不得不使用多重實(shí)現(xiàn)繼承.

雖然代碼中不應(yīng)該使用異常, 但是在 ATL 和部分 STL(包括 Visual C++ 的 STL) 中異常被廣泛使用. 使用 ATL 時(shí), 應(yīng)定義_ATL_NO_EXCEPTIONS以禁用異常. 你需要研究一下是否能夠禁用 STL 的異常, 如果無(wú)法禁用, 可以啟用編譯器異常. (注意這只是為了編譯 STL, 自己的代碼里仍然不應(yīng)當(dāng)包含異常處理).

通常為了利用頭文件預(yù)編譯, 每個(gè)每個(gè)源文件的開(kāi)頭都會(huì)包含一個(gè)名為StdAfx.h或precompile.h的文件. 為了使代碼方便與其他項(xiàng)目共享, 請(qǐng)避免顯式包含此文件 (除了在precompile.cc中), 使用/FI編譯器選項(xiàng)以自動(dòng)包含該文件.

資源頭文件通常命名為resource.h且只包含宏, 這一文件不需要遵守本風(fēng)格指南.

11. 結(jié)束語(yǔ)

運(yùn)用常識(shí)和判斷力, 并且保持一致.

編輯代碼時(shí), 花點(diǎn)時(shí)間看看項(xiàng)目中的其它代碼, 并熟悉其風(fēng)格. 如果其它代碼中if語(yǔ)句使用空格, 那么你也要使用. 如果其中的注釋用星號(hào) (*) 圍成一個(gè)盒子狀, 那么你同樣要這么做.

風(fēng)格指南的重點(diǎn)在于提供一個(gè)通用的編程規(guī)范, 這樣大家可以把精力集中在實(shí)現(xiàn)內(nèi)容而不是表現(xiàn)形式上. 我們展示的是一個(gè)總體的的風(fēng)格規(guī)范, 但局部風(fēng)格也很重要, 如果你在一個(gè)文件中新加的代碼和原有代碼風(fēng)格相去甚遠(yuǎn), 這就破壞了文件本身的整體美觀, 也讓打亂讀者在閱讀代碼時(shí)的節(jié)奏, 所以要盡量避免.

好了, 關(guān)于編碼風(fēng)格寫的夠多了; 代碼本身才更有趣. 盡情享受吧!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Google
    +關(guān)注

    關(guān)注

    5

    文章

    1788

    瀏覽量

    58700
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3685

    瀏覽量

    94915
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2117

    瀏覽量

    74823

原文標(biāo)題:Google C++ 編程規(guī)范 - 6

文章出處:【微信號(hào):C_Expert,微信公眾號(hào):C語(yǔ)言專家集中營(yíng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    MATLAB 編程風(fēng)格指南

    thebeginning.”(良好的寫作規(guī)范的程序比糟糕的寫作規(guī)范的要好,因?yàn)樗麄兙哂休^少的錯(cuò)誤、易于調(diào)試與修改,因此,從一開(kāi)始就考慮風(fēng)格是很重要的)。本指南列舉的MATLAB 代碼編寫的建議在
    發(fā)表于 09-22 16:19

    Google C++編程指南

    Google C++編程指南目標(biāo):增強(qiáng)代碼一致性,創(chuàng)建通用的、必需的習(xí)慣用語(yǔ)和模式可以使代碼更加容易理解C++是一門包含大量高級(jí)特性的巨型語(yǔ)言,某些情況下,我們會(huì)限制甚至禁止使用某些特性使代碼簡(jiǎn)化
    發(fā)表于 11-29 09:15

    MATLAB編程風(fēng)格指南

    有關(guān) MATLAB代碼的建議通常強(qiáng)調(diào)的是效率,譬如說(shuō)有關(guān)“不要用循環(huán)”等的建議,本指南與之不同。本指南主要考慮的是代碼(格式)的正確性、清晰性與通用性。本指南的目的在
    發(fā)表于 07-18 10:54 ?0次下載

    linux內(nèi)核C語(yǔ)言的編程風(fēng)格

    linux 內(nèi)核C語(yǔ)言的編程風(fēng)格
    發(fā)表于 09-26 14:22 ?0次下載

    Google編程風(fēng)格指南(一)

    使代碼易于管理的方法之一是加強(qiáng)代碼一致性. 讓任何程序員都可以快速讀懂你的代碼這點(diǎn)非常重要. 保持統(tǒng)一編程風(fēng)格并遵守約定意味著可以很容易根據(jù) “模式匹配” 規(guī)則來(lái)推斷各種標(biāo)識(shí)符的含義. 創(chuàng)建通用
    的頭像 發(fā)表于 09-27 17:57 ?3299次閱讀

    Google編程風(fēng)格指南(二)

    鼓勵(lì)在 .cc 文件內(nèi)使用匿名命名空間或 static 聲明. 使用具名的命名空間時(shí), 其名稱可基于項(xiàng)目名或相對(duì)路徑. 禁止使用 using 指示(using-directive)。禁止使用內(nèi)聯(lián)命名空間(inline namespace)。
    的頭像 發(fā)表于 09-27 18:01 ?2756次閱讀

    Google編程風(fēng)格指南(三)

    C/C++ 中的函數(shù)參數(shù)或者是函數(shù)的輸入, 或者是函數(shù)的輸出, 或兼而有之. 輸入?yún)?shù)通常是值參或 const 引用, 輸出參數(shù)或輸入/輸出參數(shù)則一般為非 const 指針. 在排列參數(shù)順序時(shí), 將所有的輸入?yún)?shù)置于輸出參數(shù)之前. 特別要注意, 在加入新參數(shù)時(shí)不要因?yàn)樗鼈兪切聟?shù)就置于參數(shù)列表最后, 而是仍然要按照前述的規(guī)則, 即將新的輸入?yún)?shù)也置于輸出參數(shù)之前.
    的頭像 發(fā)表于 09-27 18:06 ?2744次閱讀

    Google編程風(fēng)格指南(四)

    用于定義移動(dòng)構(gòu)造函數(shù) (使用類的右值引用進(jìn)行構(gòu)造的函數(shù)) 使得移動(dòng)一個(gè)值而非拷貝之成為可能. 例如, 如果 v1 是一個(gè) vector, 則 auto v2(std::move(v1)) 將很可能不再進(jìn)行大量的數(shù)據(jù)復(fù)制而只是簡(jiǎn)單地進(jìn)行指針操作, 在某些情況下這將帶來(lái)大幅度的性能提升.
    的頭像 發(fā)表于 09-27 18:08 ?3076次閱讀

    Google編程風(fēng)格指南(五)

    所有具有靜態(tài)存儲(chǔ)類型的變量 (例如靜態(tài)變量或全局變量, 參見(jiàn) 存儲(chǔ)類型) 都應(yīng)當(dāng)以此方式命名. 對(duì)于其他存儲(chǔ)類型的變量, 如自動(dòng)變量等, 這條規(guī)則是可選的. 如果不采用這條規(guī)則, 就按照一般的變量命名規(guī)則.
    的頭像 發(fā)表于 09-27 18:15 ?2688次閱讀

    Google C++編程風(fēng)格指南PDF版免費(fèi)下載

    Google的項(xiàng)目大多使用C++開(kāi)發(fā)。每一個(gè)C++程序員也都知道, C++具有很多強(qiáng)大的語(yǔ)言特性,但這種強(qiáng)大不可避免的導(dǎo)致它的復(fù)雜,而復(fù)雜性會(huì)使得代碼更容易出現(xiàn)bug.難于閱讀和維護(hù)。
    發(fā)表于 03-06 08:00 ?0次下載
    <b class='flag-5'>Google</b> C++<b class='flag-5'>編程</b><b class='flag-5'>風(fēng)格</b><b class='flag-5'>指南</b>PDF版免費(fèi)下載

    Google C++編程風(fēng)格指南PDF電子書免費(fèi)下載

    Google 的開(kāi)源項(xiàng)目大多使用 C++開(kāi)發(fā)。每一個(gè) C++程序員也都知道,C++具有很多強(qiáng)大的語(yǔ)言特性,但這種強(qiáng)大不可避免的導(dǎo)致它的復(fù)雜,這種復(fù)雜會(huì)使得代碼更易于出現(xiàn) bug、難于閱讀和維護(hù)。本
    發(fā)表于 12-12 08:00 ?1次下載
    <b class='flag-5'>Google</b> C++<b class='flag-5'>編程</b><b class='flag-5'>風(fēng)格</b><b class='flag-5'>指南</b>PDF電子書免費(fèi)下載

    Verilog HIDL的RTL設(shè)計(jì)風(fēng)格指南資源下載

    Verilog HIDL的RTL設(shè)計(jì)風(fēng)格指南資源下載
    發(fā)表于 04-13 10:09 ?9次下載

    西門子S7-1200和S7-1500編程風(fēng)格指南

    西門子S7-1200和S7-1500編程風(fēng)格指南分享
    發(fā)表于 08-17 17:30 ?22次下載

    Google 應(yīng)用出海計(jì)劃 | 指南針 第期強(qiáng)勢(shì)回歸啟動(dòng)報(bào)名!

    原文標(biāo)題:Google 應(yīng)用出海計(jì)劃 | 指南針 第期強(qiáng)勢(shì)回歸啟動(dòng)報(bào)名! 文章出處:【微信公眾號(hào):谷歌開(kāi)發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
    的頭像 發(fā)表于 04-21 19:15 ?1912次閱讀
    <b class='flag-5'>Google</b> 應(yīng)用出海計(jì)劃 | <b class='flag-5'>指南</b>針 第<b class='flag-5'>六</b>期強(qiáng)勢(shì)回歸啟動(dòng)報(bào)名!

    Google Python代碼風(fēng)格指南

    1 背景 Python是谷歌主要使用的動(dòng)態(tài)語(yǔ)言,本風(fēng)格指導(dǎo)列舉了使用Python編程時(shí)應(yīng)該做和不該做的事項(xiàng)(dos nothing on first line # 縮進(jìn)4個(gè)空格,首行括號(hào)后無(wú)內(nèi)容
    的頭像 發(fā)表于 11-03 10:20 ?3334次閱讀
    主站蜘蛛池模板: 黄色国产 | 国产主播在线观看 | 欧美精品专区55页 | japanese日本护士xx亚洲 | 米奇777色狠狠8888影视 | 国产成人综合网在线播放 | 波多野结衣50连精喷在线 | 国产三a级日本三级日产三级 | 美女一级毛片免费观看 | 五月婷综合网 | 99pao强力打造免费高清色 | 日本不卡高清视频 | 嗯好舒服好爽好快好大 | 国产亚洲视频在线播放大全 | 国产18到20岁美女毛片 | 成人免费观看一区二区 | 天天做天天爽 | 日本不卡专区 | 国产在线观看www鲁啊鲁免费 | 日本wwwwww| 久久天天躁夜夜躁狠狠躁2015 | 丝袜美腿一区 | 男人的视频网站 | 中文字幕第十页 | 69xxx视频| 鸥美三级 | 57pao成人永久免费视频 | 女人张腿让男子桶免费动态图 | 天天激情站 | 二级黄色大片 | 人人揉揉香蕉大免费不卡 | 伊人久久大香线蕉影院95 | 井野雏田小樱天天被调教 | 天堂网 | 久久精品国产2020观看福利色 | 在线天堂中文字幕 | 色天天干 | 色视频网站大全免费 | 国产在线美女 | 国产综合图片 | 操操久久|