这更像是一个入门级问题,但我想知道如果有一个空的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,因此给出了错误。如果我的返回类型不是空的怎么办?
答案 0 :(得分:6)
即使你的返回类型是无效的,return
也是合法的,当然if
有括号,至少这不是一个等待发生的错误。然而,它并不漂亮,需要更多的工作来阅读/理解。
你可以改写到
if(head == NULL) // or if(!head)
return;
....
这应该不需要else,其余的代码现在在函数内部,而不是嵌套的范围,一个快乐的振作。
答案 1 :(得分:4)
对于单个分支,只需直接编写:
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;
有时会很困难,因为它会为函数引入额外的退出点。在过去,我是这种形式的粉丝,但在过去的几年里,我发现我最终一直将它删除。
答案 2 :(得分:2)
我会删除if
部分,直至第一个else
,并将其替换为if (head)
,这是相反的条件,因此非常适合替换{{1}在if-else情况下。但是,有一个额外的缩进标签的问题,整个功能。在这一点上,它确实变得更加偏好,但我自己更愿意提前检查并没有缩进。
如果您需要从任何地方返回,可以使用else
。
答案 3 :(得分:2)
我实际上并不认为这是主观的。为什么写死代码?这是一个初学者的标志。相反,只需检查您所处的状况并完成它:
if(!head)
// stuff
答案 4 :(得分: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;
}
答案 5 :(得分:0)
正如@Oli在评论中所说,这是一个主观风格问题。你有两个选择:
if (<something is true>) {
// Do nothing
} else {
// Some code goes here
}
或
if (!<something is true>) {
// Code goes here
}
我可以想象前者比第二种更具可读性的情况,特别是如果条件适度复杂的话。
答案 6 :(得分: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
{