作者SeamusBerloz (軒摩斯)
看板C_and_CPP
標題Re: [問題] 類別跟迴圈加不加分號的問題
時間Mon Jan 14 20:08:49 2019
大括號 {},也就是指區塊。
區塊本身不需要分號結尾。
要不要加分號結尾?不需要猜,只要記得,
敘述、宣告才要加分號結尾。
以下 {} 故意寫成一行,用於說明區塊的效果。
多個敘述、宣告可以用 {} 包起來,視為一整體 (或單一行) 看待:
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: 裡的例子 01/16 08:26
→ 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