4

这更像是一个入门级问题,但我想知道有一个空的 if 语句是否是一种好习惯。

考虑这段代码:

void RabbitList::purge()
{
    if(head == NULL)
    {
        //cout << "Can't purge an empty colony!" << endl;
    }
    else
    {
        //Kill half the colony
        for(int amountToKill = (getColonySize()) / 2; amountToKill != 0;)
        {
            RabbitNode * curr = head;
            RabbitNode * trail = NULL;

            bool fiftyFiftyChance = randomGeneration(2);

            //If the random check succeeded but we're still on the head node
            if(fiftyFiftyChance == 1 && curr == head)
            {
                head = curr->next;
                delete curr;
                --size;
                --amountToKill;
            }
            //If the random check succeeded and we're beyond the head, but not on last node
            else if(fiftyFiftyChance == 1 && curr->next != NULL)
            {
                trail->next = curr->next;
                delete curr;
                --size;
                --amountToKill;
            }
            //If the random check succeeded, but we're on the last node
            else if(fiftyFiftyChance == 1)
            {
                trail->next = NULL;
                delete curr;
                --size;
                --amountToKill;
            }
            //If the random check failed
            else
            {
                trail = curr;
                curr = curr->next;
            }
        }
        cout << "Food shortage! Colony has been purged by half." << endl;
    }
}

如您所见,第 5 行的 if 语句目前已被注释掉;这更像是一个调试文本,我不想再向控制台发送任何反馈。我很确定让 if 语句什么都不做会被认为是不好的做法。我知道我可以回来;

但由于我的返回类型是 void 它给了我一个错误。例如,如果我的返回类型不是 void 怎么办?

4

7 回答 7

6

即使你的返回类型是无效的,它在return那里也是合法的,而且当然因为if有大括号,至少这不是一个等待发生的错误。然而,它并不漂亮,需要更多的阅读/理解工作。

您可以将其改写

if(head == NULL) // or if(!head)
    return;

....

这应该消除对 else 的需要,并且其余代码现在在函数内部而不是嵌套范围内,这是一个快乐的特权。

于 2013-01-11T01:12:33.457 回答
5

对于单个分支,直接写即可:

if (head != 0) {
    // whatever
}

对于多个分支,有时有一个空的第一个分支可以简化以下条件:

if (head == 0) {
    // nothing to do
} else if (head->next == 0) {
    // whatever
} else {
    // whatever else
}

是的,你可以用一个额外的层写最后一个:

if (head != 0) {
    if (head->next == 0) {
        // whatever
    } else {
        // whatever else
    }
}

但是第一种形式更清晰,尤其是当第二种形式以三四个级别的 if 结尾时。

哦,还有

if (head == 0)
    return;

有时可能很困难,因为它为函数引入了额外的退出点。过去我是这种形式的粉丝,但在过去的几年里,我发现我最终会非常一致地删除它。

于 2013-01-11T13:08:24.310 回答
2

我会删除该if部分,直到第一个else,并将其替换为if (head),这是相反的条件,因此非常适合else在 if-else 情况下替换。但是,整个函数需要一个额外的缩进标签。在这一点上,它确实变得更加偏好,但我自己更喜欢早点把支票弄出来,而不是缩进。

如果您需要从任何地方返回,您可以使用return;.

于 2013-01-11T01:12:33.700 回答
2

我实际上并不认为这是主观的。为什么要写死代码?这是初学者的标志。相反,只需检查您所追求的条件并完成它:

if(!head)
   // stuff
于 2013-01-11T01:13:13.603 回答
2

我通过删除重复和冗余重写了你的函数。它归结为相当小。

void RabbitList::purge()
{
    if(head == NULL) return;

    //Kill half the colony
    for(int amountToKill = (getColonySize()) / 2; amountToKill != 0;)
    {
        RabbitNode * curr = head;
        RabbitNode * trail = NULL;

        bool fiftyFiftyChance = randomGeneration(2);

        if(fiftyFiftyChance == 1 )
        {
            if( curr == head)
                head = curr->next;
            else
                trail->next = curr->next;

            delete curr;
            --size;
            --amountToKill;
        }
        else
        {
            trail = curr;
            curr = curr->next;
        }
    }
    cout << "Food shortage! Colony has been purged by half." << endl;
}
于 2013-01-11T02:06:24.137 回答
1

正如@Oli 在评论中所说,这是一个主观风格问题。你有两个选择:

if (<something is true>) {
    // Do nothing
} else {
    // Some code goes here
}

或者

if (!<something is true>) {
    // Code goes here
}

我可以想象前者比后者更具可读性的情况,尤其是在条件比较复杂的情况下。

于 2013-01-11T01:37:46.593 回答
0

我会离开它。

但我会虚拟化日志记录(std::cout 并不总是有用)。

struct NullLogger : public Logger
{
    virtual void log(std::string const&) {}
};

// By default use the Null Logger
// But if you need to debug just pass a useful specialization of logging.
void RabbitList::purge(Logger const& logger = NullLogger())
{
    if(head == NULL)
    {
        logger.log("Can't purge an empty colony!");
    }
    else
    {
于 2013-01-11T03:38:28.357 回答