作者LPH66 (-858993460)
看板C_and_CPP
标题Re: [问题] do{...}while(..)
时间Thu May 5 02:15:16 2011
※ 引述《wawaer398 (哇哈哈~)》之铭言:
: 开发平台(Platform): (Ex: VC++, GCC, Linux, ...)
: 突然想一个问题,我觉得很疑惑的
: 曾经不知在哪边看过一段do..while的用法 如下
: do{
: ....
: .....
: }while(0)
: 这个不就是只做一次吗??
: 为啥还要用do while包起来?
: 还是其中有什麽特别的含意吗??
: @@?
: 推 falllian:有的Macro会用这个包起来 05/05 01:54
我看过的用法都是在 macro 里面用的...
事情是这样的
假设某个 macro 是这样写的
#define swapint(x,y) \
{ \
int temp; \
temp = x; \
x = y; \
y = temp; \
}
然後有段使用它的程式是这麽写的:
if(condition)
swapint(a,b);
else
swapint(a,c);
一切看起来似乎都没问题
但是 macro 展开之後变成这样了:
if(condition)
{
int temp;
temp = a;
a = b;
b = temp;
};
else
{
int temp;
temp = a;
a = c;
c = temp;
};
因为 macro 展开会代换掉的地方只到 () 结束 ; 留下来了 所以变成这样
但这个留下来的 ; 却会造成 compile error
(compiler 会告诉你他不知道这个 else 是做什麽的
因为 compiler 把那个 ; 理解为一个空叙述
因此它会认为前面的 if 结束了 就向你抱怨说这个 else 不知道来做什麽)
要解决这个问题有两种方法
一个是使用时别写分号
但这样一来这程式会变成
if(condition)
swapint(a,b)
else
swapint(a,c)
怎麽看怎麽别扭
(只要是写了一段时间的 C 的人
看到後面没有 ; 的叙述大概总会有种冲动把 ; 加上去 XD)
另一种就是这种写法:
#define swapint(x,y) \
do \
{ \
int temp; \
temp = x; \
x = y; \
y = temp; \
} while(0)
这样在展开之後会变成
if(condition)
do
{
int temp;
temp = a;
a = b;
b = temp;
} while(0);
else
do
{
int temp;
temp = a;
a = c;
c = temp;
} while(0);
compiler 看起来就是 if(...) do{}while(0); else do{}while(0);
变成合法的叙述了
注意的是为了不让同样的事情再度发生
macro 定义里的 while(0) 後面是没有分号的
展开後的分号是上面提到过留下来的那个分号
--
也就是这是为了别让 compiler 抱怨而出现的写法
所以自从有了 inline 之後这种东西就渐渐消失了....
--
い
ああオレたちには见えてるモノがあるbデ きっと谁にも夺われないモノがあるはずさ
け
开口一番一虚一実跳梁跋扈形影相吊yュL羊头狗肉东奔西走国士无双南柯之梦 歪も
ぶ
意味がないと思えるコトがある ラPきっとでも意図はそこに必ずある んの
く
依依恋恋空前絶後疾风怒涛有无相生 ラH急転直下物情骚然愚者一得相思相爱 だが
ろ
无意味じゃない ラ6あの意図が 恋た
で
有为転変死生有命苍天已死黄天当立 !!6五里雾中解散宣言千错万综则天去私 のり
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.230.62
1F:推 BSpowerx:长知识推m(_ _)m 05/05 02:17
2F:推 wawaer398:长知识+1 感谢 05/05 02:20
3F:推 peefly:其实 #1C9hMqYD 有问过相同的问题XD 05/05 02:29
4F:推 saxontai:推超详细的佛心解说! 05/05 02:30
6F:→ loveme00835:方法是邪魔歪道, 根本不想了解它... 05/05 02:46
7F:→ loveme00835:应该是说使用情境为 function 而不是 subroutine 的情 05/05 02:54
8F:→ loveme00835:况, 想怎麽恶搞都只能治标而已, 我程式码用错..orz 05/05 02:54
9F:推 lf21201:长知识!!! 05/05 03:05
10F:→ LPH66:是啊 所以现在能用 inline 就用吧 05/05 04:50
11F:推 VictorTom:小弟常见到的另一个用法就是原文推文讲的, 05/05 09:31
12F:→ VictorTom:拿来(在某种程度内)取代goto; 用break强制跳到{}尾端@@" 05/05 09:31
13F:推 softwind:GOOD! Linux kernel 几乎都是这样写 安心用吧... 05/05 22:43
14F:→ softwind:版主 你的sample 要用()再包一层欧~ 因为他没有 return 05/05 22:43
15F:→ softwind:value ... gcc extension 有这种写法... 05/05 22:44
16F:→ softwind:同样的 在Linux kerenl和Android framework也是大量使用 05/05 22:44
17F:→ softwind: gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html 05/05 22:46
18F:→ loveme00835:0.0 05/06 04:42
19F:推 xatier:长知识推 05/07 14:34
20F:推 eyhuang:长知识!!! 08/14 22:39