看板 C_and_CPP 關於我們 聯絡資訊
大括號 {},也就是指區塊。 區塊本身不需要分號結尾。 要不要加分號結尾?不需要猜,只要記得, 敘述、宣告才要加分號結尾。 以下 {} 故意寫成一行,用於說明區塊的效果。 多個敘述、宣告可以用 {} 包起來,視為一整體 (或單一行) 看待: i = i + 1; k += i * 10; j = foo(k); 若改成: {i = i + 1; k += i * 10; j = foo(k);} 區塊沒有分號結尾。 while / do-while 敘述則是: do 單行敘述; while(條件); --> do {敘述; 敘述; ... 多行敘述;} while(條件); 真正加分號結尾的是 while,與 {} 無關。 區塊只是為了當條件成立,則要一次做一堆事情而設定的; 所以反過來也一樣: while(條件) 單行敘述; --> while(條件) {敘述; 敘述; ... 多行敘述;} 區塊將視為一整體邏輯,光是 {} 本身就已經等效於一行敘述, 所以寫成 {}; ,其中分號其實是多餘的,甚至會發生錯誤: if(條件) {}; <-- 錯的其實是這裡 (多了分號,讓後續 else 斷頭了) else <-- 但是編譯器會說這裡錯 (預期應該要有 if,但是找不到) {}; <-- 不會錯,但是多餘,只會把分號當作空敘述。 同樣的例子,還可以應用在 switch-case,請再自己試試看。 另外,我想多個宣告用區塊包起來 (變成結構),是容易誤會的地方: struct _MY_STRUCT {int i; int j; int k;} MyStruct; 其中 {} 一樣不加分號結尾;真正加分號的是 MyStruct。 再一個例子: class _MY_CLASS {int i; int j; int k;} MyClass; 道理和 struct 相同。 但是因為可以省略宣告對象,後面用到再用來實際宣告變數物件, 就變成了: struct _MY_STRUCT {int i; int j; int k;}; class _MY_CLASS {int i; int j; int k;}; 這大概是容易誤會的地方。 列舉也是一樣道理: enum _MY_ENUMERATE {A, B, C, D}; 區塊本身不需要分號結尾。 但若變成宣告的一部份,為了宣告的完整性,才給一個分號作結尾, 所以,真正需要分號的,其實是宣告,不是區塊本身。 同樣的道理,一樣適用於函數。 這是原型宣告: int foo(int i); 這是函數 (本體): int foo(int i) {return (i * i);} 一樣,區塊沒有分號結尾,需要分號結尾的是裡面的敘述。 (若有謬誤,煩請指正) -- 精密才是美,複雜不是罪! 這是將事物的描述給自己最鉅細靡遺的交代! -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.163.195.20 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1547467735.A.67F.html
cole945: 呃..被講完了..只好推囧 01/14 21:12
x246libra: 完美解說 01/14 22:54
me8z7gnk: 謝謝解說我多年的疑惑 01/15 00:59
me8z7gnk: 解說太完整了 完全解答 01/15 01:02
CoNsTaR: 在不加分號的地方加,對編譯器來講那個分號就是空敘述 01/15 13:06
CoNsTaR: 單純這樣而已吧,沒有那麼複雜啊 orz 01/15 13:06
CoNsTaR: 所以你要在 block 後面加 100 個分號編譯器也不會管你 01/15 13:06
CoNsTaR: 因為通通都是空敘述,都是業障 01/15 13:06
LPH66: 補充一個:lambda 先寫起來放的時候也是因宣告變數故要分號 01/15 13:23
LPH66: auto lambda=[](){return 42;}; //這裡指左邊第二個分號 01/15 13:25
LPH66: 對於這個我個人習慣是會先把 {}; 打好再寫裡面 01/15 13:29
LPH66: 在只有 {} 沒有內容時很容易知道這裡是不是該加分號的地方 01/15 13:30
me8z7gnk: 謝謝C大跟L大 我原本一直卡在類別為什麼結尾要加分號 01/15 21:36
me8z7gnk: 現在看完這篇 豁然開朗阿! 01/15 21:37
cole945: 本文有舉例結尾分號有差.if(){};;;else{}不行多加 01/16 08:24
cole945: 分號會影響parsing,並非全無意, do{}while();在macro 01/16 08:25
cole945: 很好用.可以看https://kernelnewbies.org/FAQ/DoWhile0 01/16 08:26
cole945: 裡的例子 01/16 08:26
SeamusBerloz: 拋磚引玉: http://c-faq.com/cpp/multistmt.html 01/16 09:40
me8z7gnk: 謝謝col大跟Se大提醒 01/16 20:29
me8z7gnk: 因為之前被教說能使用inline就使用 inline 01/16 20:29
me8z7gnk: 所以只把呼叫 macro 最後不能加分號背起來 01/16 20:29
me8z7gnk: 並沒有了解原意 現在才了解 01/16 20:29
me8z7gnk: do while(0) 之前看過以為只做一次沒什麼特別 01/16 20:29
me8z7gnk: 原來是用在 macro 上 這麼好用 01/16 20:30
TitanEric: 大推 01/18 00:31
hohamita: 推 感謝解說! 01/18 13:37