当前位置:天才代写 > tutorial > C语言/C++ 教程 > do {…} while (0) 在宏界说中的浸染

do {…} while (0) 在宏界说中的浸染

2017-11-01 08:00 星期三 所属: C语言/C++ 教程 浏览:56

假如你是一名C措施员,你必定很熟悉宏,它们很是强大,假如正确利用可以让你的事情事半功倍。然而,假如你在界说宏时很随意没有当真查抄,那么它们大概使你发疯,挥霍N多时间。在许多的C措施中,你大概会看到很多看起来不是那么直接的较非凡的宏界说。下面就是一个例子:

#define __set_task_state(tsk, state_value) \

   do{ (tsk)->state = (state_value); } while(0)

在Linux内核和其它一些著名的C库中有很多利用do{…}while(0)的宏界说。这种宏的用途是什么?有什么长处?

Google的Robert Love(先前从事Linux内核开拓)给我们解答如下:

do{…}while(0)在C中是独一的结构措施,让你界说的宏老是以沟通的方法事情,这样不管怎么利用宏(尤其在没有用大括号困绕挪用宏的语句),宏后头的分号也是沟通的结果。

这句话听起来大概有些拗口,其实用一句话归纳综合就是:利用do{…}while(0)结构后的宏界说不会受到大括号、分号等的影响,老是会按你期望的方法挪用运行。

譬喻:

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

然后你大概这样挪用:

foo(wolf);

这将被宏扩展为:

bar(wolf); baz(wolf);

这简直是我们期望的正确输出。下面看看假如我们这样挪用:

if (!feral)

   foo(wolf);

那么扩展后大概就不是你所期望的功效。上面语句将扩展为:

if (!feral)

   bar(wolf);

baz(wolf);

显而易见,这是错误的,也是各人常常易犯的错误之一。

险些在所有的环境下,期望写多语句宏来到达正确的功效是不行能的。你不能让宏像函数一样行为——在没有do/while(0)的环境下。

假如我们利用do{…}while(0)来从头界说宏,即:

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

此刻,该语句成果上等价于前者,do能确保大括号里的逻辑能被执行,而while(0)能确保该逻辑只被执行一次,即与没有轮回时一样。

对付上面的if语句,将会被扩展为:

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语句简直能被正确扩展,可是假如我们有下面的语句挪用呢:

if (!feral)

   foo(wolf);

else

   bin(wolf);

宏扩展后将酿成:

if (!feral) {

   bar(wolf);

   baz(wolf);

};

else

   bin(wolf);

各人可以看出,这就有语法错误了。

总结:Linux和其它代码库里的宏都用do/while(0)来困绕执行逻辑,因为它能确保宏的行为老是沟通的,而不管在挪用代码中利用了几多分号和大括号。

From:csdn博客 lanxuezaipiao

 

    关键字:


天才代写-代写联系方式