C语言do...while语句的妙用(包裹宏替换多句代码)(代替go to语法)(隔绝外部变量)

Posted Dontla

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言do...while语句的妙用(包裹宏替换多句代码)(代替go to语法)(隔绝外部变量)相关的知识,希望对你有一定的参考价值。

文章目录

使用do…while(0)的好处

在C++中,do…while 通常是用来做循环用的,然而我们做循环操作可能用for和while要多一些。经常看到一些开源代码会出现do…while(0)这样的代码,这样的代码看上去肯定不是用来做循环的,那为什么要这样用呢?

实际上do…while(0)的作用远大于美化代码,现总结起来主要有以下几个作用:

> 辅助定义复杂的宏,避免引用的时候出错,提高代码健壮性

假设你需要定义一个这样的宏:

#define DOSOMETHING()\\

               func1();\\

               func2();

这个宏的本意是,当调用DOSOMETHING()时,函数func1()和func2()都会被调用。但是如果你在调用的时候这么写:

if(a>0)
    DOSOMETHING();

因为宏在预处理的时候会直接被展开,你实际上写的代码是这个样子的:

if(a>0)

    func1();

func2();

这就出现了问题,因为无论a是否大于0,func2()都会被执行,导致程序出错。

那么仅仅使用将func1()和func2()包起来行么?

我们在写代码的时候都习惯在语句右面加上分号,如果在宏中使用,代码里就相当于这样写了:“…;”,假如有以下代码:

#define DOSOMETHING()\\

               func1();\\

               func2();
...
if(a>0)
    DOSOMETHING();
else
   ...
...

展开后就是这个样子:

if(a>0)

    func1();

    func2();
;
else
    ...

这样是不会编译通过。所以,很多人才采用了do…while(0);

#define DOSOMETHING() \\

        do \\

          func1();\\

          func2();\\

        while(0)\\

...
if(a>0)
    DOSOMETHING();
else
    ...
...

> 消除分支语句或者goto语句,提高代码的易读性

如果在一个函数中开始要分配一些资源,然后在中途执行过程中如果遇到错误则退出函数,当然,退出前先释放资源,我们的代码可能是这样:

bool Execute()

   // 分配资源
   int *p = new int;
   bool bOk(true);

   // 执行并进行错误处理
   bOk = func1();
   if(!bOk) 
   
      delete p;   
      p = NULL;
      return false;
   

   bOk = func2();
   if(!bOk) 
   
      delete p;   
      p = NULL;
      return false;
   

   bOk = func3();
   if(!bOk) 
   
      delete p;   
      p = NULL;
      return false;
   

   // ..........

   // 执行成功,释放资源并返回
    delete p;   
    p = NULL;
    return true;
   

这里一个最大的问题就是代码的冗余,而且我每增加一个操作,就需要做相应的错误处理,非常不灵活。于是我们想到了goto:

bool Execute()

   // 分配资源
   int *p = new int;
   bool bOk(true);

   // 执行并进行错误处理
   bOk = func1();
   if(!bOk) goto errorhandle;

   bOk = func2();
   if(!bOk) goto errorhandle;

   bOk = func3();
   if(!bOk) goto errorhandle;

   // ..........

   // 执行成功,释放资源并返回
    delete p;   
    p = NULL;
    return true;

errorhandle:
    delete p;   
    p = NULL;
    return false;
   

代码冗余是消除了,但是我们引入了C++中身份比较微妙的goto语句,虽然正确的使用goto可以大大提高程序的灵活性与简洁性,但太灵活的东西往往是很危险的,它会让我们的程序捉摸不定,那么怎么才能避免使用goto语句,又能消除代码冗余呢,请看do…while(0)循环:

bool Execute()

   // 分配资源
   int *p = new int;

   bool bOk(true);
   do
   
      // 执行并进行错误处理
      bOk = func1();
      if(!bOk) break;

      bOk = func2();
      if(!bOk) break;

      bOk = func3();
      if(!bOk) break;

      // ..........

   while(0);

    // 释放资源
    delete p;   
    p = NULL;
    return bOk;
   

> 使用代码块,代码块内定义变量,不用考虑变量重复问题

当你的功能很复杂,变量很多你又不愿意增加一个函数的时候,使用dowhile(0);,将你的代码写在里面,里面可以定义变量而不用考虑变量名会同函数之前或者之后的重复。

参考文章:使用do…while(0)的好处

以上是关于C语言do...while语句的妙用(包裹宏替换多句代码)(代替go to语法)(隔绝外部变量)的主要内容,如果未能解决你的问题,请参考以下文章

C 语言宏定义中使用do...while

C语言在linux内核中do while妙用之法

do while的作用

do while的作用

do while的作用

do{}while(false)妙用