更新
我想我设法解决了。我利用了:
if(x) {
...
}
是相同的
for(; x ;) {
...
break:
}
我们需要从那里保存x
. 我们不能重用它,因为它x
可能是一个有副作用的表达式。所以:
int b;
for(; b = (x);) {
break;
}
现在,我们可以检查b
上面的 for 循环是否被执行。使用 for 循环完成的完整 if-elif-else 模式如下所示:
for(;b = (x);) { // if
...
break;
}
for(; !b ? b=(x==1) : 0;) { // elif
...
break;
}
for(; !b ;) { // else
...
break;
}
有了这个,我们可以像这样把它包起来,但要注意。但是,如果您if(x) break
在循环内执行此操作,则效果不佳。见下文。
int b; // Store truth value of last if or elif
#define if(x) for(;b = !!(x);)
#define do {
#define elif(x) break; } for(; !b ? b=!!(x) : 0;) {
#define else break; } for(;!b;) {
#define done break; }
演示:https ://onlinegdb.com/Zq6Y7vm5Q
break
没有语句的替代方法:
int b; // Store truth value of last if or elif
#define if(x) for(int c=1 ; c && (b = !!(x)); c=0)
#define do {
#define elif(x) } for(int c=1; c && (!b ? b=!!(x) : 0); c=0) {
#define else } for(int c=1; c && !b; c=0) {
#define done }
但是请注意,如果您break
在其中有这样的声明,这两种方法都可能会失败:
for(...) {
if(x)
do
break;
done
}
因为这将扩展为:
for(...) {
for(int c=1 ; c && (b = !!(x)); c=0)
{
break;
}
}
笔记:
这应该是显而易见的,但是如果您决定使用此代码(不要),那么使用比b
和c
避免冲突更好的名称。
旧的解决方法
不完全符合您的要求,但您承认您基本上只是在滥用预处理器。:)
但一个简单的解决方法是使用else
.
#define if(x) if (x)
#define do {
#define elif(x) } else if (x) {
#define otherwise } else {
#define done }
演示:https ://onlinegdb.com/Cp-gYpOvm
它适用于零个、一个或多个 elif 实例,无论有多少个 elif,它都可以在有或没有其他情况下工作。