[英]C/C++ Macro for breaking or continuing
I am trying to code a simple macro which based on a condition either calls break
or continue
in the loop in which it is called. 我正在尝试编写一个简单的宏,该宏基于调用break
或在调用它的循环中continue
的条件。 Below is the code: 下面是代码:
#include <iostream>
#define BC_IF_EVEN(BC) if(i % 2 == 0) BC
using namespace std;
int main() {
int i = 0;
while(i++ < 30) {
if(i < 15)
BC_IF_EVEN(continue);
else
BC_IF_EVEN(break);
cout << i << " ";
}
cout << endl;
}
The output that I am looking for is: 1 3 5 7 9 11 13 15
, but the above code outputs: 1 3 5 7 9 11 13 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
because the else
condition in main()
gets applied to the if
condition in the BC_IF_EVEN
macro. 我正在寻找的输出是: 1 3 5 7 9 11 13 15
,但上面的代码输出: 1 3 5 7 9 11 13 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
因为else
main()
条件将应用于BC_IF_EVEN
宏中的if
条件。
A simple fix is to put scope braces for the if
condition in main()
, but I do not want to enforce that because the user should be allowed to code in regular way. 一个简单的解决方法是在main()
为if
条件放置范围括号,但是我不想强制执行该操作,因为应该允许用户以常规方式进行编码。
NB I cannot put a do { .. } while(false)
loop in the macro (which is a standard trick to allow semicolons after macro calls in conditionals because the break
and continue
sent via BC
get applied to this inner loop. 注意:我不能在宏中放入do { .. } while(false)
循环(这是在条件调用宏之后允许分号的标准技巧,因为通过BC
发送的break
和continue
会应用于此内部循环。
Is there an easy way to get the required output without modifying the main()
function? 有没有一种简单的方法就可以在不修改main()
函数的情况下获得所需的输出?
#define BC_IF_EVEN(BC) if (i % 2 != 0); else BC
但是为什么呢?
Don't invent obscure macros in an attempt to justify your obscure loops. 不要发明晦涩的宏来试图证明晦涩的循环。 Frequent use of continue
and break
inside loops is a certain sign of poor program design. 频繁使用continue
和break
内部循环是程序设计不佳的一定标志。
Here's how to fix the program: 修复程序的方法如下:
Since you check if a number is even no matter in which way the program branches, might as well move that check outside the if-else. 由于您检查数字是否与程序分支的方式无关,因此最好将该检查移至if-else之外。
for(int i=0; i<30; i++) { if(i%2 == 0) // even { if(i < 15) continue; else break; } cout << i << " "; }
Now look at the conditions and what the program actually does. 现在查看条件以及程序实际执行的操作。 This doesn't make sense at all. 这根本没有道理。 All it does is to print the odd numbers between 0 and 14 in a very obscure way. 它所做的只是以非常模糊的方式打印0到14之间的奇数。 Instead, you probably wanted a program which prints the odd numbers between 0 and 15. 相反,您可能想要一个打印0到15之间的奇数的程序。
Apply common sense: Loop from 0 to 15. Check each number to see if it is odd. 应用常识:从0到15循环。检查每个数字是否为奇数。 If so, print it. 如果是这样,请打印它。 Otherwise ignore it. 否则忽略它。
for(int i=0; i<=15; i++) { if(i%2 != 0) cout << i << " "; }
Alternatively, don't bother with even numbers at all: 或者,根本不用理会偶数:
for(int i=1; i<=15; i+=2) { cout << i << " "; }
This is why functions were created, just create a function to check if it is even or odd and return a true if even and false if odd. 这就是创建函数的原因,只需创建一个函数来检查它是偶数还是奇数,然后返回true(如果偶数)和false(如果奇数)。 Macros are ugly when you can do it simply another way. 当您可以简单地以另一种方式执行宏时,宏就会很丑陋。 Please for the love all legacy maintainers make readable code. 请为所有旧版维护者的爱做可读的代码。
eg: 例如:
// Example program
#include <iostream>
using namespace std;
bool checkeven(int i)
{
if( i % 2 != 0)
return false;
else
return true;
}
int main()
{
for(int i = 0; i < 30; i++) //while(i++ < 30) is readable, but I think this is even easier
{
if(i < 15)
{
if(checkeven(i))
continue;
}
else
{
if(checkeven(i))
break;
}
cout << i << " ";
}
}
Use curly brackets even if you have the only line in if/else statement. 即使在if / else语句中只有一行,也请使用大括号。 In this case you'll fully control the workflow. 在这种情况下,您将完全控制工作流程。
The other advantage of this approach is that if you need to comment out the line in if/else statement you'll just put //
in the start of the line. 这种方法的另一个优点是,如果您需要在if / else语句中注释掉该行,只需将//
放在该行的开头。
// wrong workflow
if ( expr )
// commented out for debug issues
//do_when_expr();
do_whatever();
// right workflow
if ( expr )
{
// commented out for debug issues
//do_when_expr();
}
do_whatever();
In your case it would be: 您的情况是:
#define BC_IF_EVEN( BC ) if (i % 2 == 0) { BC; }
...
if(i < 15)
{
BC_IF_EVEN(continue)
}
else
{
BC_IF_EVEN(break);
}
尝试这个
#define BC_IF_EVEN(BC) ( { if(i % 2 == 0) BC; } )
You just need an extra pair of curly braces to restrict the scope for your inner if block. 您只需要另外一对花括号即可限制内部if块的范围。 Following should work: 以下应该工作:
#define BC_IF_EVEN(BC) {if(i % 2 == 0) BC;} #define BC_IF_EVEN(BC){if(i%2 == 0)BC;}
Also do not use ';' 也不要使用';' while using macro: 在使用宏时:
if(i < 15)
BC_IF_EVEN(continue) //No semicolon
Or if you want use semicolon for code consistency then an extra pair of braces has to be put: 或者,如果您想使用分号来保证代码的一致性,那么就必须另外花括号:
#define BC_IF_EVEN(BC) ({if(i % 2 == 0) BC;}) #define BC_IF_EVEN(BC)({if(i%2 == 0)BC;})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.