搜索
bottom↓
回复: 62

请问在要执行的语句上加do{}while(0),有什么深意?

  [复制链接]

出0入0汤圆

发表于 2010-12-3 09:49:20 | 显示全部楼层 |阅读模式
像这一句,#define SDA_DIR     do{P3DIR |= BIT1;P3SEL &= ~BIT1;}while(0)
按照C语言的语法理解,加上do{}while(0),跟没加是一样结果,那别人这样写有什么深意呢?

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2013-9-11 03:30:33 | 显示全部楼层
用心良苦,但实际上只需使用一个逗号‘,’即可:

#define SDA_DIR     P3DIR |= BIT1, P3SEL &= ~BIT1

出0入0汤圆

发表于 2013-9-11 09:25:37 | 显示全部楼层
本帖最后由 qlb1234 于 2013-9-11 09:31 编辑

好吧,無聊人來也。
  1. #include <cstdio>

  2. int main()
  3. {
  4. #define GOGOGO a=1,b=2
  5.     unsigned int a, b, c = 1;
  6.     if(c == 1)
  7.         GOGOGO;
  8.     else
  9.     {
  10.         a = 3;
  11.         b = 3;
  12.     }
  13.     printf("%u %u", a, b);
  14.     return 0;
  15. }
复制代码
GCC g++ 4.8.1,無任何錯誤提示,輸出
  1. 1 2
复制代码
其實,在每箇if、else、else if、while、for後,加上一箇大括號對,是一箇良好習慣,哪怕你的代碼衹有一行。

我的習慣是
  1. #include <cstdio>

  2. int main()
  3. {
  4. #define GOGOGO a=1;b=2
  5.     unsigned int a, b, c = 1;
  6.     if(c == 1)
  7.     {
  8.         GOGOGO;
  9.     }
  10.     else
  11.     {
  12.         a = 3;
  13.         b = 3;
  14.     }
  15.     printf("%u %u", a, b);
  16.     return 0;
  17. }
复制代码
同樣無錯誤,正常結果。
少年們,拋掉大學課堂上、各種“C語言由淺入深,深入淺出,深二淺八啪啪啪”書本裏的死板老舊風格吧。

出0入0汤圆

发表于 2010-12-3 12:02:41 | 显示全部楼层
比较下面这段代码,你就明白了。

#define SDA_DIR     P3DIR |= BIT1;P3SEL &= ~BIT1

if(condition)
      SDA_DIR;
else
      ......
相当于
if(condition)
      P3DIR |= BIT1;P3SEL &= ~BIT1;
else
      ......

宏展开的时候会报错,无论加什么括号也都是一样的。


而定义成
#define SDA_DIR     do{P3DIR |= BIT1;P3SEL &= ~BIT1;}while(0)
可以避免这个问题。

出0入0汤圆

 楼主| 发表于 2010-12-3 12:07:25 | 显示全部楼层
回复【2楼】tmpond
比较下面这段代码,你就明白了。
#define sda_dir     p3dir |= bit1;p3sel &amp;= ~bit1
if(condition)
      sda_dir;
else
      ......
相当于
if(condition)
      p3dir |= bit1;p3sel &amp;= ~bit1;
else
      ......
宏展开的时候会报错,无论加什么括号也都是一样的。
而定义成
#define sda_dir     do{p3dir |= bit1;p3sel &amp;= ~bit1;}while(0)
可以避免这个问题。

-----------------------------------------------------------------------

谢谢楼上的,如果不加括号,放在IF语句里肯定是错的,但整体加上大括号{}也会报错吗?我试下

出0入0汤圆

发表于 2010-12-3 12:28:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-3 12:43:36 | 显示全部楼层
如果只加大括号可能会出错的:

#define BLAH() { blahblah; }

if (cond)
    BLAH();  // <---- 后面有分号
else
{
    SomethingElse();
}

展开后变成:
if (cond)
{ blahblah; };  // <----- 注意后面的分号
else
{
    SomethingElse();
}

出0入0汤圆

 楼主| 发表于 2010-12-3 12:49:19 | 显示全部楼层
回复【5楼】theophilus
-----------------------------------------------------------------------

完全明白了,谢谢2楼和5楼!

出0入0汤圆

发表于 2010-12-3 12:55:19 | 显示全部楼层
编写规范,增强可读性

出0入0汤圆

发表于 2010-12-4 21:26:37 | 显示全部楼层
终于明白了,多谢~···

出0入0汤圆

发表于 2010-12-4 21:42:53 | 显示全部楼层
回复【7楼】ManofPhysics  
-----------------------------------------------------------------------
看我的头像。。。

出0入0汤圆

发表于 2010-12-4 22:28:14 | 显示全部楼层
回复【9楼】binaimei2007 兵仔
-----------------------------------------------------------------------
回复【7楼】ManofPhysics
-----------------------------------------------------------------------
可以玩找茬了

出0入0汤圆

发表于 2010-12-6 01:05:46 | 显示全部楼层
宏展开的时候会报错,无论加什么括号也都是一样的。
---------------
为什么啊,我加上括号的话,不是if为真的话,执行真个括号内的指令吗

出0入0汤圆

发表于 2011-6-9 15:30:56 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-9 15:46:07 | 显示全部楼层

(原文件名:1.jpg)

点击此处打开 ourdev_647238G1P0IY.jpg(文件大小:1.47M,只有400K以内的图片才能直接显示) (原文件名:2.jpg)
点击此处打开 ourdev_647239AMQPV4.jpg(文件大小:1.48M,只有400K以内的图片才能直接显示) (原文件名:3.jpg)

出0入0汤圆

发表于 2011-6-9 15:48:36 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-6-10 09:30:00 | 显示全部楼层
回复【13楼】TimCheng

(原文件名:1.jpg)
引用图片
点击此处打开  
点击此处打开  

-----------------------------------------------------------------------

这个是哪个教程里的?上面几位回答的跟这里几乎一摸一样,看来很多人读个这个教程呀?

出0入0汤圆

发表于 2011-6-10 10:17:14 | 显示全部楼层
学习了。。。

出0入0汤圆

发表于 2013-7-22 14:03:46 | 显示全部楼层
确实是个好办法,还可以消除go to

出0入0汤圆

发表于 2013-8-7 09:28:20 | 显示全部楼层
MACK,

出0入0汤圆

发表于 2013-8-7 10:43:59 | 显示全部楼层
cbing2000 发表于 2013-8-7 09:47
你宏定义 用{ } 就不会了。   #define SDA_DIR     {P3DIR |= BIT1;P3SEL &= ~BIT1;}

同意这位兄弟
完全正确
上面有些回复误导

{}后面有;分号肯定可以
ISO 9899写得很清楚:
A null statement (consisting of just a semicolon) performs no operations.

出0入0汤圆

发表于 2013-8-7 10:47:50 | 显示全部楼层
xiangxiadage 发表于 2013-8-7 10:43
同意这位兄弟
完全正确
上面有些回复误导

楼上的兄弟,以及楼上的兄弟,还是没有理解到。

如果if语句后面还要跟其他语句呢?加大括号行吗?

用do while是把多个语句封装成一个语句

出0入0汤圆

发表于 2013-8-7 10:56:20 | 显示全部楼层
xiangxiadage 发表于 2013-8-7 10:43
同意这位兄弟
完全正确
上面有些回复误导

如果只加大括号,在if()define SDA_DIR;else...这种情况下编译报错。//注意定义后面的分号,很多人都会这么写。

出0入0汤圆

发表于 2013-9-1 20:35:35 来自手机 | 显示全部楼层
收藏一下 我也试试

出0入0汤圆

发表于 2013-9-3 15:16:32 | 显示全部楼层
好,又学了一招,增强程序的移植性

出0入0汤圆

发表于 2013-9-5 22:50:37 来自手机 | 显示全部楼层
学习…………

出0入0汤圆

发表于 2013-9-6 16:52:45 | 显示全部楼层
边界效应!学习了...

出0入0汤圆

发表于 2013-9-6 17:09:46 | 显示全部楼层
crazy_horse 发表于 2013-8-7 10:56
如果只加大括号,在if()define SDA_DIR;else...这种情况下编译报错。//注意定义后面的分号,很多人都会这 ...

if(condition)
    xxx;
    ;  //把if和else分开了,报错!
else
    xxx;

出0入0汤圆

发表于 2013-9-7 23:11:22 来自手机 | 显示全部楼层
看大湿回复…………

出0入0汤圆

发表于 2013-9-8 08:57:12 | 显示全部楼层
是的 的确这样

出0入0汤圆

发表于 2013-9-8 09:10:25 | 显示全部楼层
学习了。。。。

出0入0汤圆

发表于 2013-9-8 10:29:18 | 显示全部楼层
学习了,要是没想到这点,出错了估计要找很久

出0入0汤圆

发表于 2013-9-9 17:53:21 | 显示全部楼层
TimCheng 发表于 2011-6-9 15:46
(原文件名:1.jpg)

点击此处打开 ourdev_647238G1P0IY.jpg(文件大小:1.47M,只有400K以内的图片才能直接 ...

请问这本书是?

出0入0汤圆

发表于 2013-9-9 18:10:25 来自手机 | 显示全部楼层
  学习了

出0入0汤圆

发表于 2013-9-9 18:10:40 | 显示全部楼层
TimCheng 发表于 2011-6-9 15:46
(原文件名:1.jpg)

点击此处打开 ourdev_647238G1P0IY.jpg(文件大小:1.47M,只有400K以内的图片才能直接 ...

请教下这个是什么文档,能发下学习吗

出0入0汤圆

发表于 2013-9-9 18:18:31 | 显示全部楼层
高人很多啊。

出0入0汤圆

发表于 2013-9-9 18:21:01 | 显示全部楼层
学习了      

出0入0汤圆

发表于 2013-9-10 08:17:21 | 显示全部楼层
forum 发表于 2013-9-9 18:10
请教下这个是什么文档,能发下学习吗

Linux内核情景分析

出0入0汤圆

发表于 2013-9-10 08:17:37 | 显示全部楼层
王二狗子 发表于 2013-9-9 17:53
请问这本书是?

Linux内核情景分析

出0入0汤圆

发表于 2013-9-10 08:18:21 | 显示全部楼层
wuha 发表于 2011-6-10 09:30
回复【13楼】TimCheng

(原文件名:1.jpg)

Linux内核情景分析

出0入0汤圆

发表于 2013-9-10 08:26:32 | 显示全部楼层
呵呵。。。。。mark

出0入0汤圆

发表于 2013-9-10 08:32:50 | 显示全部楼层
和高手交流,能提高自己!

出0入0汤圆

发表于 2013-9-10 22:42:54 | 显示全部楼层
貌似学到了什么

出0入0汤圆

发表于 2013-9-11 01:34:32 | 显示全部楼层
以前遇到这样的问题,用define怎么定义都出错,现在看了这个帖子终于明白了。感谢楼主!感谢2楼与5楼!
另外,11楼的头像也挺漂亮的,喜欢!

出0入0汤圆

发表于 2013-9-11 07:28:12 | 显示全部楼层
su_mj000 发表于 2013-9-11 03:30
用心良苦,但实际上只需使用一个逗号‘,’即可:

#define SDA_DIR     P3DIR |= BIT1, P3SEL &= ~BIT1 ...

我未試,但表同。

出0入0汤圆

发表于 2013-9-11 09:49:14 | 显示全部楼层
二楼和五楼果然强大。

出0入0汤圆

发表于 2013-9-11 12:53:55 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-9-17 09:29:23 | 显示全部楼层
太牛了,以前都没想到这种解决方法,赶紧回去修代码。。。

出0入0汤圆

发表于 2013-9-17 09:38:11 | 显示全部楼层
3L 正解         

出0入0汤圆

发表于 2013-9-18 10:03:17 | 显示全部楼层
好帖,Mark                          

出0入0汤圆

发表于 2013-9-19 08:57:31 | 显示全部楼层
学习了,原来还可以这样!!!

出0入0汤圆

发表于 2013-9-19 18:30:37 | 显示全部楼层
TimCheng 发表于 2011-6-9 15:46
(原文件名:1.jpg)

点击此处打开 ourdev_647238G1P0IY.jpg(文件大小:1.47M,只有400K以内的图片才能直接 ...

哇,学到东西了,哈哈

出0入0汤圆

发表于 2013-9-19 18:31:53 | 显示全部楼层
TimCheng 发表于 2011-6-9 15:46
(原文件名:1.jpg)

点击此处打开 ourdev_647238G1P0IY.jpg(文件大小:1.47M,只有400K以内的图片才能直接 ...

感谢!!

出0入0汤圆

发表于 2013-9-29 10:34:11 | 显示全部楼层
#define SDA_DIR     P3DIR |= BIT1;P3SEL &= ~BIT1

if(condition)
{    SDA_DIR ;
}
else
{    .......
}

这样写吧!
规范里不是要求:每个if  else 即使一条语句也要加括号的吗?

出0入0汤圆

发表于 2013-10-3 17:12:46 | 显示全部楼层
学过了,谢谢!

出0入0汤圆

发表于 2013-10-3 20:28:32 来自手机 | 显示全部楼层
在哪学的?绕来绕去的。我觉得没意义。
即使是分号,我也加。
if(a==1)
{;
}
else
{...
}

出0入0汤圆

发表于 2013-10-3 20:48:06 | 显示全部楼层
  1. #define SDA_DIR     P3DIR |= BIT1;P3SEL &= ~BIT1

  2. if(condition)
  3. {    SDA_DIR ;
  4. }
复制代码
What if some time in the future a dumbass comes around and changes the code to this, without seeing how SDA_DIR is defined:

  1. if(condition)
  2.     SDA_DIR ;
复制代码
Looks perfectly innocent.

Your code is not robust and it is a time bomb waiting for its next victim. Something like this is easy to debug in a small system but in a large system, it is difficult to identify.

出0入0汤圆

发表于 2013-10-4 11:53:35 | 显示全部楼层
学习了                                             

出0入0汤圆

发表于 2016-7-28 11:25:49 | 显示全部楼层
学习了、标记。

出0入0汤圆

发表于 2016-7-28 12:25:18 | 显示全部楼层
tmpond 发表于 2010-12-3 12:02
比较下面这段代码,你就明白了。

#define SDA_DIR     P3DIR |= BIT1;P3SEL &= ~BIT1

学习了,没有注意到的细节

出0入4汤圆

发表于 2016-7-28 19:46:56 | 显示全部楼层
tmpond 发表于 2010-12-3 12:02
比较下面这段代码,你就明白了。

#define SDA_DIR     P3DIR |= BIT1;P3SEL &= ~BIT1

Good !           
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 15:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表