【问题标题】:C++: Empty if statementC++:空 if 语句
【发布时间】:2013-01-11 01:10:55
【问题描述】:

这更像是一个入门级问题,但我想知道使用空 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 怎么办?

【问题讨论】:

  • 这是一个风格问题,本质上是主观的。但是一个好的经验法则是永远不要在你的代码库中放置注释掉的代码。
  • @Oli 感谢您的回答。我是自学的,所以由于我没有直接的指导,我还是更喜欢问这类问题。
  • 附带说明:现在不推荐使用宏 NULL,更喜欢使用 nullptr,请参阅 stackoverflow.com/questions/1282295 和 stackoverflow.com/questions/13816385
  • 甚至可以将“head”条件放在 for 循环中
  • 我很想对这个问题发表一个空洞的答案。

标签: c++ if-statement


【解决方案1】:

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

您可以将其改写为

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

....

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

【讨论】:

  • 这是我的偏好。当你有一个简单的函数并且某些条件会导致它什么都不做时,我喜欢在开始时检测并返回。这样我就避免了过多的缩进,并且有一个策略,如果我到达函数的末尾,那么它就成功了。
【解决方案2】:

对于单个分支,直接写就行了:

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;

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

【讨论】:

    【解决方案3】:

    我会去掉 if 部分,直到第一个 else,并将其替换为 if (head),这是相反的条件,因此非常适合在 if-else 情况下替换 else .但是,整个函数需要一个额外的缩进标签。在这一点上,它确实变得更加偏好,但我自己更喜欢早点把 check out 和没有缩进。

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

    【讨论】:

    • 所以:if(head != NULL) AND if(head) 是一回事,对吗?就像 if(head == NULL) AND if(!head)?
    • @Marcan,是的,我更喜欢较短的形式。
    • 谢谢。在检查 2 个条件的更长的语句中呢?例如:if(mutantCount() > 0 && head)。或者为了清楚起见最好写: if(mutantCount() > 0 && head != NULL)?
    • @Marcan, head 应该同样清楚,尤其是指针。
    【解决方案4】:

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

    if(!head)
       // stuff
    

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

      • 哇,太好了。仅仅浏览你的代码就让我意识到我可以如何优化它,从而使它更具可读性。谢谢。
      【解决方案6】:

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

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

      或

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

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

      【讨论】:

        【解决方案7】:

        我会离开它。

        但我会虚拟化日志记录(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
            {
        

        【讨论】:

        • @Lieuwe:完成ballder-dash。
        猜你喜欢
        • 2016-06-16
        • 1970-01-01
        • 1970-01-01
        • 2021-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-17
        相关资源
        最近更新 更多