作者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://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1547467735.A.67F.html
1F:推 cole945: 呃..被讲完了..只好推囧 01/14 21:12
2F:推 x246libra: 完美解说 01/14 22:54
3F:推 me8z7gnk: 谢谢解说我多年的疑惑 01/15 00:59
4F:推 me8z7gnk: 解说太完整了 完全解答 01/15 01:02
5F:推 CoNsTaR: 在不加分号的地方加,对编译器来讲那个分号就是空叙述 01/15 13:06
6F:→ CoNsTaR: 单纯这样而已吧,没有那麽复杂啊 orz 01/15 13:06
7F:→ CoNsTaR: 所以你要在 block 後面加 100 个分号编译器也不会管你 01/15 13:06
8F:→ CoNsTaR: 因为通通都是空叙述,都是业障 01/15 13:06
9F:推 LPH66: 补充一个:lambda 先写起来放的时候也是因宣告变数故要分号 01/15 13:23
10F:→ LPH66: auto lambda=[](){return 42;}; //这里指左边第二个分号 01/15 13:25
11F:→ LPH66: 对於这个我个人习惯是会先把 {}; 打好再写里面 01/15 13:29
12F:→ LPH66: 在只有 {} 没有内容时很容易知道这里是不是该加分号的地方 01/15 13:30
13F:推 me8z7gnk: 谢谢C大跟L大 我原本一直卡在类别为什麽结尾要加分号 01/15 21:36
14F:→ me8z7gnk: 现在看完这篇 豁然开朗阿! 01/15 21:37
15F:推 cole945: 本文有举例结尾分号有差.if(){};;;else{}不行多加 01/16 08:24
16F:→ cole945: 分号会影响parsing,并非全无意, do{}while();在macro 01/16 08:25
18F:→ cole945: 里的例子 01/16 08:26
20F:→ me8z7gnk: 谢谢col大跟Se大提醒 01/16 20:29
21F:→ me8z7gnk: 因为之前被教说能使用inline就使用 inline 01/16 20:29
22F:→ me8z7gnk: 所以只把呼叫 macro 最後不能加分号背起来 01/16 20:29
23F:→ me8z7gnk: 并没有了解原意 现在才了解 01/16 20:29
24F:→ me8z7gnk: do while(0) 之前看过以为只做一次没什麽特别 01/16 20:29
25F:→ me8z7gnk: 原来是用在 macro 上 这麽好用 01/16 20:30
26F:推 TitanEric: 大推 01/18 00:31
27F:推 hohamita: 推 感谢解说! 01/18 13:37