简体   繁体   English

C / C ++宏,用于中断或继续

[英]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发送的breakcontinue会应用于此内部循环。

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. 频繁使用continuebreak内部循环是程序设计不佳的一定标志。

Here's how to fix the program: 修复程序的方法如下:

  • When the amount of items you iterate through is known in advance, use a for loop, as they are usually easier to read and harder to mess up. 事先知道要遍历的项目数量时,请使用for循环,因为它们通常更易于阅读且更难弄乱。
  • 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM