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

C/C++ Macro for breaking or continuing

我正在尝试编写一个简单的宏,该宏基于在调用它的循环中调用 breakcontinue 的条件。下面是代码:

#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;
}

我正在寻找的输出是: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 因为 main() 中的 else 条件被应用于 if BC_IF_EVEN 宏中的条件。

一个简单的解决方法是在 main() 中为 if 条件放置范围大括号,但我不想强制执行,因为应该允许用户以常规方式编码。

N.B. 我不能在宏中放置 do { .. } while(false) 循环(这是在条件语句中允许在宏调用后使用分号的标准技巧,因为通过 BC 发送的 breakcontinue 应用于此内部循环。

有没有不修改 main() 函数就能得到所需输出的简单方法?

#define BC_IF_EVEN(BC) if (i % 2 != 0); else BC

但真的为什么?

这就是创建函数的原因,只需创建一个函数来检查它是偶数还是奇数,return 如果偶数则为真,如果为奇数则为假。当你可以用另一种方式简单地做宏时,宏是丑陋的。为了爱,请所有遗留维护者编写可读代码。

例如:

// 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 << " ";
    }
}

即使在 if/else 语句中只有一行,也请使用花括号。在这种情况下,您将完全控制工作流程。
这种方法的另一个优点是,如果您需要注释掉 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();

你的情况是:

#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; } )

不要发明晦涩难懂的宏来试图证明你晦涩难懂的循环。在循环内频繁使用 continuebreak 是程序设计不佳的一定标志。

修复程序的方法如下:

  • 如果事先知道您迭代的项目数量,请使用 for 循环,因为它们通常更容易阅读并且更难搞砸。
  • 既然无论程序以何种方式分支都检查一个数字是否为偶数,不妨将该检查移到 if-else 之外。

    for(int i=0; i<30; i++)
    {
      if(i%2 == 0) // even
      {
        if(i < 15)
          continue;
        else
          break;
      }
    
      cout << i << " ";
    }
    
  • 现在看看条件和程序实际做了什么。这根本没有意义。它所做的只是以一种非常模糊的方式打印 0 到 14 之间的奇数。相反,您可能想要一个打印 0 到 15 之间的奇数的程序。

  • 应用常识:从0循环到15。检查每个数字是否为奇数。如果是这样,打印出来。否则无视。

    for(int i=0; i<=15; i++)
    {
      if(i%2 != 0)
        cout << i << " ";
    }
    
  • 或者,根本不用理会偶数:

    for(int i=1; i<=15; i+=2)
    {
      cout << i << " ";
    }
    

您只需要一对额外的大括号来限制内部 if 块的范围。以下应该有效:

#define BC_IF_EVEN(BC) {if(i % 2 == 0) BC;}

也不要使用';'使用宏时:

            if(i < 15)
                BC_IF_EVEN(continue) //No semicolon

或者如果你想使用分号来保证代码的一致性,那么必须多加一对大括号:

#define BC_IF_EVEN(BC) ({if(i % 2 == 0) BC;})