假设我有这样的伪代码:

bool conditionA = executeStepA();
if (conditionA){
    bool conditionB = executeStepB();
    if (conditionB){
        bool conditionC = executeStepC();
        if (conditionC){
            ...
        }
    }
}

executeThisFunctionInAnyCase();

函数executeStepX当且仅当前一个成功时执行。 在任何情况下,executeThisFunctionInAnyCase函数都应该在最后被调用。 我在编程方面是一个新手,所以很抱歉提出一个非常基本的问题:有没有一种方法(例如在C/ c++中)以代码易读性为代价,避免长if链产生那种“金字塔式代码”?

我知道如果我们可以跳过executeThisFunctionInAnyCase函数调用,代码可以简化为:

bool conditionA = executeStepA();
if (!conditionA) return;
bool conditionB = executeStepB();
if (!conditionB) return;
bool conditionC = executeStepC();
if (!conditionC) return;

但是约束是executeThisFunctionInAnyCase函数调用。 break语句可以以某种方式使用吗?


当前回答

已经有很多不错的答案了,但大多数答案似乎都牺牲了一些(诚然,很少)灵活性。一种不需要这种权衡的常见方法是添加状态/持续变量。当然,价格是需要跟踪的额外价值:

bool ok = true;
bool conditionA = executeStepA();
// ... possibly edit conditionA, or just ok &= executeStepA();
ok &= conditionA;

if (ok) {
    bool conditionB = executeStepB();
    // ... possibly do more stuff
    ok &= conditionB;
}
if (ok) {
    bool conditionC = executeStepC();
    ok &= conditionC;
}
if (ok && additionalCondition) {
    // ...
}

executeThisFunctionInAnyCase();
// can now also:
return ok;

其他回答

把有条件的东西移到else中怎么样?

if (!(conditionA = executeStepA()){}
else if (!(conditionB = executeStepB()){}
else if (!(conditionC = executeStepC()){}
else if (!(conditionD = executeStepD()){}

这确实解决了缩进问题。

break语句可以以某种方式使用吗?

也许不是最好的解决办法,但你可以把你的陈述变成一种方式。While(0)循环并使用break语句而不是return。

在阅读了所有的答案之后,我想提供一种新的方法,它在适当的情况下可能非常清晰易读:状态模式。

如果你将所有的方法(executeStepX)打包到一个对象类中,它可以有一个属性getState()

class ExecutionChain
{
    public:
        enum State
        {
          Start,
          Step1Done,
          Step2Done,
          Step3Done,
          Step4Done,
          FinalDone,
        };
        State getState() const;

        void executeStep1();
        void executeStep2();
        void executeStep3();
        void executeStep4();
        void executeFinalStep();
    private:
        State _state;
};

这将允许你将你的执行代码平铺成这样:

void execute
{
    ExecutionChain chain;

    chain.executeStep1();

    if ( chain.getState() == Step1Done )
    {
        chain.executeStep2();
    }

    if ( chain.getState() == Step2Done )
    {
        chain.executeStep3();
    }

    if ( chain.getState() == Step3Done )
    {
        chain.executeStep4();
    }

    chain.executeFinalStep();
}

通过这种方式,它易于阅读,易于调试,你有一个清晰的流控制,还可以插入新的更复杂的行为(例如,只有在至少执行Step2时才执行Special Step)……

我的问题与其他方法,如ok = execute();如果(execute()),则代码应该清晰易读,就像正在发生的事情的流程图一样。在流程图中有两个步骤:1。2执行。基于结果的决定

因此,您不应该将重要的重载方法隐藏在if语句或类似语句中,它们应该独立存在!

Don't. Sometimes you need the complexity. The trick is how you do it. Having the "what you do when the condition exists" may take up some room, making the if statement tree appear larger than it really is. So instead of doing things if a condition is set, just set a variable to a specific value for that case( enumeration or number, like 10,014. After the if tree, then have a case statement, and for that specific value, do whatever you would have done in the if tree. It will lighten up the tree. if x1 if x2 if x3 Var1:=100016; endif endif end if case var=100016 do case 100016 things...

让执行函数在失败时抛出异常,而不是返回false。然后你的调用代码看起来像这样:

try {
    executeStepA();
    executeStepB();
    executeStepC();
}
catch (...)

当然,我假设在您最初的示例中,执行步骤只会在步骤内发生错误的情况下返回false ?