Chinaunix

标题: do {} while(0); 到底有什么作用。 [打印本页]

作者: yjh777    时间: 2005-12-16 12:25
标题: do {} while(0); 到底有什么作用。
如题,把一个宏定义成do {} while(0);  到底有什么作用。

请教。
作者: wqmmmmm    时间: 2005-12-16 12:36
可以使用break代替goto语句
作者: 草草    时间: 2005-12-16 12:41
用在宏里面。
当宏里面有if时,可以起到封闭代码作用,防止与外面的 if 混淆。

比如定义宏,#define FREE1(p) if (p) free (p)

而在代码部分这样调用宏:
if (expression)
FREE1(p)
else
printf(“expression was false.\n”) ;

展开后,else会和宏中的if配对了,这就错了。但是宏写成如下的形式就永远不会错了
#define FREE4(P)  do { if (p) free(p)}; while (0)
作者: wqmmmmm    时间: 2005-12-16 12:45
原帖由 草草 于 2005-12-16 12:41 发表
用在宏里面。
当宏里面有if时,可以起到封闭代码作用,防止与外面的 if 混淆。

比如定义宏,#define FREE1(p) if (p) free (p)

而在代码部分这样调用宏:
if (expression)
FREE1(p)
else
printf(“exp ...



这根直接封个大括号有什么区别。还用得着do while?
作者: 草草    时间: 2005-12-16 12:55
当然有差别!
《Linux内核注释》这本书里有一段专门讲这个的,懒得抄写了,可以自己找来看看。在看之前我也是百思不得其解的,看后才感到,kernel写的果然处处是技巧。
作者: albcamus    时间: 2005-12-16 12:56
原帖由 wqmmmmm 于 2005-12-16 12:45 发表



这根直接封个大括号有什么区别。还用得着do while?


你仔细理解一下:
#define FREE1(p) {if (p) free (p) }


if (expression)
FREE1(p)
else
printf(“expression was false.\n”) ;

预处理之后,就变成了这样:
if (expression)
  {if (p) free (p) };
else
  printf(“expression was false.\n”) ;


仔细看看{}后面那个分号,明白了吧?
作者: 独孤九贱    时间: 2005-12-16 13:00
原帖由 albcamus 于 2005-12-16 12:56 发表


你仔细理解一下:
#define FREE1(p) {if (p) free (p) }


if (expression)
FREE1(p)
else
printf(“expression was false.\n”) ;

预处理之后,就变成了这样:
if (expression)
  {if (p) free ...


这也怪不得别人反问草草了,因为他举的例子中,把;号给忽略了,所以给别人造成了误解……
作者: yjh777    时间: 2005-12-16 13:14
谢谢草草,albcamus,独孤九贱,wqmmmmm。

wqmmmmm看题不仔细,答非所问,以后要细心点
作者: 思平    时间: 2005-12-16 13:19
没见过 do {} while(0); 这种宏,
只见过 do {} while(0) 这种宏
作者: zalem    时间: 2005-12-16 13:26
原帖由 思平 于 2005-12-16 13:19 发表
没见过 do {} while(0); 这种宏,
只见过 do {} while(0) 这种宏


真见过,在那个RO私服的Athena源码里...

[ 本帖最后由 zalem 于 2005-12-16 13:28 编辑 ]
作者: 思平    时间: 2005-12-16 13:30
原帖由 zalem 于 2005-12-16 13:26 发表


真见过,在那个RO私服的Athena源码里...多个空文而已

do {} while(0); 和  {} 是完全等价的,
所以没必要写这么复杂。

问题:
哪位同学能举出一个例子,让 do {} while(0); 和 {} 不等价?
作者: zalem    时间: 2005-12-16 13:44
原帖由 思平 于 2005-12-16 13:30 发表

do {} while(0); 和  {} 是完全等价的,
所以没必要写这么复杂。

问题:
哪位同学能举出一个例子,让 do {} while(0); 和 {} 不等价?


你回复前我就悔过了...

  1. #include <stdio.h>

  2. #define dd do{puts("a");}while(0);
  3. int main()
  4. {
  5.     if(1)
  6.         dd;
  7.     else
  8.         dd;

  9.     return 0;
  10. }
复制代码
localhost:~/c# LC_ALL=C gcc a.c
a.c: In function `main':
a.c:8: parse error before "else"

[ 本帖最后由 zalem 于 2005-12-16 13:46 编辑 ]
作者: 思一克    时间: 2005-12-16 13:46
to 思平,

这是区别。

你将main()中的F2换为F1就不行了。



  1. #define F1(C)                                   \
  2. {                                               \
  3.   return C;                                     \
  4. }

  5. #define F2(C)                                   \
  6. do                                              \
  7. {                                               \
  8.   return C;                                     \
  9. }                                               \
  10. while (0)


  11. int a, b, c;
  12. int main ()
  13. {
  14. if(a == b)
  15.      F2(c);
  16. else
  17.      return a;
  18. }
复制代码

作者: 思平    时间: 2005-12-16 14:06
原帖由 思一克 于 2005-12-16 13:46 发表
to 思平,

这是区别。

你将main()中的F2换为F1就不行了。


[CODE]
#define F1(C)                                   \
{                                               \
  return C;            ...

你没有仔细看,
我说的是:
原帖由 思平 于 2005-12-16 13:30 发表

do {} while(0); 和  {} 是完全等价的,
所以没必要写这么复杂。

问题:
哪位同学能举出一个例子,让 do {} while(0); 和 {} 不等价?


其实我早就说过了:
原帖由 思平 于 2005-12-16 13:19 发表
没见过 do {} while(0); 这种宏,
只见过 do {} while(0) 这种宏

作者: 思平    时间: 2005-12-16 14:08
原帖由 zalem 于 2005-12-16 13:44 发表


你回复前我就悔过了...

不用说“悔过”这么难听吧?
呵呵,大家讨论讨论而已嘛。
作者: wqmmmmm    时间: 2005-12-16 14:26
原帖由 思平 于 2005-12-16 13:30 发表

do {} while(0); 和  {} 是完全等价的,
所以没必要写这么复杂。

问题:
哪位同学能举出一个例子,让 do {} while(0); 和 {} 不等价?


{
    break;
}

do
{
   break;
}
while(0);
不等价,呵呵
作者: 思平    时间: 2005-12-16 14:28
原帖由 wqmmmmm 于 2005-12-16 14:26 发表


{
    break;
}

do
{
   break;
}
while(0);
不等价,呵呵

兄弟呀!
那是宏的内容,
不是使用时的差别啊。
没事干写什么 break 啊。
作者: wqmmmmm    时间: 2005-12-16 14:30
原帖由 思平 于 2005-12-16 14:28 发表

兄弟呀!
那是宏的内容,
不是使用时的差别啊。
没事干写什么 break 啊。


不是没事,有的时候需要这么用呀
宏里面一样可以这么用呀
难道宏里面不能使用break语句。。。。。  呵呵
作者: 思平    时间: 2005-12-16 14:33
原帖由 wqmmmmm 于 2005-12-16 14:30 发表


不是没事,有的时候需要这么用呀
宏里面一样可以这么用呀
难道宏里面不能使用break语句。。。。。  呵呵

呵呵,算你狠!
这算一种情况。
其它呢?
作者: yjh777    时间: 2005-12-16 15:41
原帖由 思平 于 2005-12-16 13:19 发表
没见过 do {} while(0); 这种宏,
只见过 do {} while(0) 这种宏


不好意思,我多加了一个;  不过不影响,多个空语句而已。

至于跟 {} 的区别,albcamus 已经说的很清楚了,没有必要再讨论了吧!

[ 本帖最后由 yjh777 于 2005-12-16 15:45 编辑 ]
作者: Dong888    时间: 2005-12-16 17:20
我也不太明白啊。
作者: 思平    时间: 2005-12-16 18:56
原帖由 yjh777 于 2005-12-16 15:41 发表


不好意思,我多加了一个; 不过不影响,多个空语句而已

至于跟 {} 的区别,albcamus 已经说的很清楚了,没有必要再讨论了吧!

根本不是那么回事。
如果你好学的话,就应该自己再仔细想想。
不然就算了。
作者: japonensis    时间: 2005-12-16 22:15
好难啊,本以为C很简单
作者: menp9999    时间: 2005-12-17 22:19
原帖由 yjh777 于 2005-12-16 12:25 发表
如题,把一个宏定义成do {} while(0);  到底有什么作用。

请教。

防止宏替换时候出现歧异性,没有什么其他的目的。
作者: sidac    时间: 2005-12-19 19:41
标题: 长见识
还是不太理解,慢慢跟各位虾壳学习吧。
作者: yjh777    时间: 2005-12-20 08:41
原帖由 思平 于 2005-12-16 18:56 发表

根本不是那么回事。
如果你好学的话,就应该自己再仔细想想。
不然就算了。


确实不应该加分号,谢谢!

do {} while(0);  与 {} 等价

do {} while(0)  与 {} 不等价
作者: mq110    时间: 2005-12-20 08:46
原帖由 yjh777 于 2005-12-20 08:41 发表


确实不应该加分号,谢谢!

do {} while(0);  与 {} 等价

do {} while(0)  与 {} 不等价


兄弟是大连哪的? 看来很闲的样子.不像是工作的.
作者: yjh777    时间: 2005-12-20 08:50
原帖由 mq110 于 2005-12-20 08:46 发表


兄弟是大连哪的? 看来很闲的样子.不像是工作的.


是,工作了,这两天不太忙,以前的问题没仔细想,发帖子跟大家讨论讨论。
你还在念书?
作者: mq110    时间: 2005-12-20 08:51
原帖由 yjh777 于 2005-12-20 08:50 发表


是,工作了,这两天不太忙,以前的问题没仔细想,发帖子跟大家讨论讨论。
你还在念书?


恩.~
作者: xtlsai    时间: 2005-12-20 10:52
这是一个功能扩展的函数,是防止以后加入第三方功能的函数的。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2