美文网首页
你用过do{...}while(0)吗?

你用过do{...}while(0)吗?

作者: TonyCode | 来源:发表于2020-04-03 11:45 被阅读0次

当第一次遇到do{...}while(0),我是懵的,这是什么操作,为了好看吗?后来发现Linux内核中随处可见啊,大神们这样的操作肯定是有道理的。查询了一些资料,做一下总结。在今后C语言开发中,你也可以放心使用这一技巧。

1. 配合定义复杂的宏,避免宏在预处理展开时出错

举个例子,假设你定义了一个宏:

#define DOSOMETHING() fuc1(); fuc2();

当调用DOSOMETHING()的时候,你希望调用fuc1()和fuc2()来做一些事情。但是当在if语句中调用时,可能会这么写:

if(num > 0)
    DOSOMETHING();

预处理展开宏,替换文本如下:

if(num > 0)
    fuc1();
fuc2();

这样就出现了问题,fuc2()就不受if语句的控制了,导致程序出错。

可能你会说,宏定义建议把整个表达式用大括号括起来的:

#define DOSOMETHING() {fuc1(); fuc2();}

还是if语句来调用:

if(num > 0)
    DOSOMETHING();
else
    printf("num<0\r\n");

这样程序编译会报错:

报错

我们查看预处理文件,宏展开是这样子的:

宏展开

if语句被后面的分号提前结束,else无法与其匹配。而使用do{...}while(0)后就不会出错了,Linux内核中的宏定义很多都是这么用的:

linux中使用

2. 避免定义空的宏时引起warning

一些大型的C工程中,为了兼容不同的架构,或者为了移植方便,都会用到空的宏定义。在编译的时候,编译器会给出警告,为了避免这些warning,我们可以使用do{...}while(0)来定义空的宏:

空宏

3. 避免goto语句

在一些函数中,我们可能需要在return语句之前做一些清理工作,很多人不提倡用goto语句。好吧,do{...}while(0)可以实现同样的功能:

int foo()
{
    somestruct *ptr = malloc(...);
    do
    {
        dosomething...;
        if(error)
            break;
        dosomething...;
        if(error)
            break;
        dosomething...;
    }
    while(0);

    free(ptr);
    return 0;
}

代码可读性和可维护性要比goto语句好多了。

4. 定义单一的函数块来完成复杂的操作

当你的功能复杂,变量很多又不愿增加一个函数的时候,可以将你的代码用do{...}while(0)包裹,在里面可以定义变量而不用考虑变量名会同函数前后重复。当然,为了后续维护方便,不建议这么做。

5. 就是感觉美观好看

对,就是觉得好看,不解释:

代码整洁

相关文章

  • 你用过do{...}while(0)吗?

    当第一次遇到do{...}while(0),我是懵的,这是什么操作,为了好看吗?后来发现Linux内核中随处可见啊...

  • do{}while(0)

    实际上,do{...}while(0)的作用远大于美化你的代码。查了些资料,总结起来这样写主要有以下几点好处: 1...

  • do while 和 break的妙用

    do{ }while(0); 我们知道do-while循环会先执行一次,判断while中条件为ture后,执行循环...

  • About do .... while(0)

    替代goto

  • 巧用do{...}while(0)

    在学习第一门编程语言时,就已经介绍了顺序分支、条件分支、循环分支。比如循环分支有for、while、do-whil...

  • 轻松说英语157

    Do you play mahjong?你打麻将吗?Once in a while.=Every now and ...

  • Day02--循环结构

    代表语句:while、do while、for while语句格式: do while语句格式: do while...

  • 04循环结构

    1、while(){} 先判断,后执行,所以执行次数>=0 2、do{}while(); 先执行,后判断,所以执行...

  • shell 按行读取并建立数组

    while read line;do array=({array[0]};pos=chr;done

  • 第四,五章 控制,初始化与清理

    执行流程 While{}do 和do{}while do{}while(flag) 至少会执行一次,而while(...

网友评论

      本文标题:你用过do{...}while(0)吗?

      本文链接:https://www.haomeiwen.com/subject/xpchuhtx.html