我已经看了十多年了.我一直在努力思考它有什么好处.因为我主要在#defines中看到它,所以我认为它对内部范围变量声明和使用中断(而不是gotos)有好处.
对其他事情有好处吗?你用它吗?
Gre*_*ill 466
它是C中唯一可用于#define多if语句操作的结构,后面加一个分号,并且仍然在语句中使用.一个例子可能有帮助:
#define FOO(x) foo(x); bar(x)
if (condition)
FOO(x);
else // syntax error here
...;
Run Code Online (Sandbox Code Playgroud)
即使使用大括号也无济于事:
#define FOO(x) { foo(x); bar(x); }
Run Code Online (Sandbox Code Playgroud)
在if语句中使用它将要求您省略分号,这是违反直觉的:
if (condition)
FOO(x)
else
...
Run Code Online (Sandbox Code Playgroud)
如果你这样定义FOO:
#define FOO(x) do { foo(x); bar(x); } while (0)
Run Code Online (Sandbox Code Playgroud)
那么以下语法是正确的:
if (condition)
FOO(x);
else
....
Run Code Online (Sandbox Code Playgroud)
Jer*_*nes 105
这是一种简化错误检查并避免深层嵌套if的方法.例如:
do {
// do something
if (error) {
break;
}
// do something else
if (error) {
break;
}
// etc..
} while (0);
Run Code Online (Sandbox Code Playgroud)
Mar*_*wis 76
它有助于将多个语句分组到一个语句中,因此类似函数的宏实际上可以用作函数.假设你有
#define FOO(n) foo(n);bar(n)
Run Code Online (Sandbox Code Playgroud)
你也是
void foobar(int n) {
if (n)
FOO(n);
}
Run Code Online (Sandbox Code Playgroud)
然后这扩大到
void foobar(int n) {
if (n)
foo(n);bar(n);
}
Run Code Online (Sandbox Code Playgroud)
请注意,第二个调用(bar(n))不再是if语句的一部分.
将两者都包装到do {} while(0)中,也可以在if语句中使用宏.
小智 18
有趣的是,要注意以下情况:在做{}而(0)循环不会为你工作:
如果你想要一个返回值的类函数宏,那么你将需要一个语句表达式:({stmt; stmt;})而不是do {} while(0):
#include <stdio.h>
#define log_to_string1(str, fmt, arg...) \
do { \
sprintf(str, "%s: " fmt, "myprog", ##arg); \
} while (0)
#define log_to_string2(str, fmt, arg...) \
({ \
sprintf(str, "%s: " fmt, "myprog", ##arg); \
})
int main() {
char buf[1000];
int n = 0;
log_to_string1(buf, "%s\n", "No assignment, OK");
n += log_to_string1(buf + n, "%s\n", "NOT OK: gcc: error: expected expression before 'do'");
n += log_to_string2(buf + n, "%s\n", "This fixes it");
n += log_to_string2(buf + n, "%s\n", "Assignment worked!");
printf("%s", buf);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
137207 次 |
| 最近记录: |