#define XXX do{ XXX } while(0) 为什么会有这种用法

#define XXX do{ XXX } while(0) 为什么会有这种用法


时常会遇到一个很"奇怪的宏定义", rt.(欧西巴...思考不够深刻啊, 皮鞭, 啪啪啪)


最近又遇到这家伙了,Quora上面Love神回答了这个问题, 我也就顶礼膜拜

http://www.quora.com/What-is-the-purpose-of-using-do-while-0-in-macros


这是C语言里面宏定义的时候,不会造成歧义或副作用的一种常用技巧.


考虑一下情况

#define foo(x)  bar(x); baz(x)


foo(wolf);


常规的,扩展成如下代码:

bar(wolf); baz(wolf);


这都还好,没啥问题.但是如果遇到if判断语句了,看看下面的例子.

f (!feral)
    foo(wolf);


这就扩展成了下面的形式,(⊙o⊙)看,是不是出现了你不想要粗线的情况捏?

这里if语句只能作用于第一个bar()函数,无法作用于第二个baz().但是这种方式很可能不是程序员的本意.

本意就是把foo单做一个整体嘛~


if (!feral)
    bar(wolf); baz(wolf);



等价于如下形式
if (!feral)
    bar(wolf);
baz(wolf);



离开了  do/while(0)你就别想把宏定义玩的跟函数一样一样的~

如果使用这种技巧定义宏定义, 

#define foo(x)  do { bar(x); baz(x); } while (0)


还是这个宏定义,这么用
f (!feral)
    foo(wolf);


就变成了如下形式.

if (!feral)
    do { bar(wolf); baz(wolf); } while (0);

等价于
if (!feral) {
    bar(wolf);
    baz(wolf);
}



你可能会想,用下面这种方式,加个{}不就解决问题了么?干嘛害的要do{} while(0)?
考虑如下情况
#define foo(x)  { bar(x); baz(x); }


if (!feral)
    foo(wolf);
else
    bin(wolf);


这就变成了
if (!feral) {
    bar(wolf);
    baz(wolf);
};
else
    bin(wolf);



注意!这里使得else变成了"臭名昭著的"dangling else.







  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,首先我们需要准备以下材料: 1. LPC2xxx 开发板 2. 8个发光二极管 3. 适当数量的导线 4. 面包板 5. 电源 接下来,我们可以按照以下步骤进行设计: 1. 打开 Proteus 设计软件,选择 LPC2xxx 微控制器,并将其拖放到工作区域中。 2. 连接开发板上的引脚与适当的元件,如发光二极管和面包板。 3. 使用 LPC2xxx 的 GPIO 引脚控制发光二极管显示学号后两位的 BCD 码。 4. 连接电源并测试设计。 接下来我将提供一些 C 语言代码,您可以将其复制到 Keil 或其他编译器中进行编译。代码如下: ``` #include <LPC214x.h> #define LED0 (1<<17) // P1.17 #define LED1 (1<<18) // P1.18 #define LED2 (1<<19) // P1.19 #define LED3 (1<<20) // P1.20 #define LED4 (1<<21) // P1.21 #define LED5 (1<<22) // P1.22 #define LED6 (1<<23) // P1.23 #define LED7 (1<<24) // P1.24 void delay(int count) { int i; for(i=0;i<count;i++); } int main() { IO1DIR = LED0|LED1|LED2|LED3|LED4|LED5|LED6|LED7; // 设置引脚方向为输出 while(1) { IO1SET = LED0|LED1|LED2|LED3|LED4|LED5|LED6|LED7; // 关闭所有 LED IO1CLR = LED4|LED5|LED6|LED7; // 打开 LED0-LED3 delay(1000000); IO1SET = LED0|LED1|LED2|LED3|LED4|LED5|LED6|LED7; IO1CLR = LED0|LED1|LED6|LED7; // 打开 LED2-LED5 delay(1000000); IO1SET = LED0|LED1|LED2|LED3|LED4|LED5|LED6|LED7; IO1CLR = LED1|LED2|LED5|LED6; // 打开 LED0-LED3、LED6、LED7 delay(1000000); IO1SET = LED0|LED1|LED2|LED3|LED4|LED5|LED6|LED7; IO1CLR = LED0|LED3|LED4|LED7; // 打开 LED1-LED6 delay(1000000); } } ``` 在这个示例中,我们使用了LPC214x的引脚来控制发光二极管的显示。您可以根据需要更改代码以适应您的具体硬件设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值