在C中编写if-else语句时,是否有理由优先使用运算符"等于"结果"不等于",两者都可以产生相同的结果?
以下代码提供了上下文。因此,如果参数计数等于2,则将从用户检索字符串。但是,如果获得任何其他参数值,则会显示错误消息。
int main(int argc, string argv[])
{
string msg;
if (argc == 2)
{
msg = GetString();
}
else
{
printf("ERROR: Please only enter a single key! \n");
return 1;
}
但是,通过将if-else循环的条件更改为"不等于",并翻转相关的操作,我可以获得与上述完全相同的结果。见下文:
int main(int argc, string argv[])
{
string msg;
if (argc != 2)
{
printf("ERROR: Please only enter a single key! \n");
return 1;
}
else
{
msg = GetString();
}
无论如何,由于两者产生相同的结果,是否应优先使用另一种?
答案 0 :(得分:12)
这只是一种编码风格问题。我讨厌嵌套主逻辑,我把它写成:
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("ERROR: Please only enter a single key! \n");
return 1;
}
string msg = GetString();
}
顺便说一句:main
的签名应为int main(int argc, char *argv[])
。
答案 1 :(得分:12)
C ++中有一个技术原因,那是因为如果你习惯使用==
而不是!=
,那么你就不需要重载那么多运算符。
当你处理函数对象(“functor”)时,这很重要。例如,当您使用标准容器类来存储自己的自定义对象并希望自动对它们进行排序时。为了使函数对象(例如std :: equal_to)起作用,您的类只需要重载==
运算符。您不必重载==
和!=
。
同样,其他函数对象要求您只重载<
而不是< > == != <= >=
的全部。
一般来说,否定对人类大脑来说并不容易理解。特别是如果你有双重否定。如果顺序在技术上无关紧要,那么在大多数编程语言中自定义首先编写相等性检查。大多数情况下,它使代码更容易阅读。
但与编程和编码风格一样,没有黑色或白色规则。如果检查的原因是找到错误,那么编写错误处理的最可读方式优先于“人类发现更难以阅读的否定”。
考虑一下这个编写得不太好的代码:
if(input == good)
{
if(format == expected)
{
do_stuff();
return ok;
}
else
{
return error_format;
}
}
else
{
return error_input;
}
想象一下,我们需要为此添加更多错误处理。相当常见的情况:假设我们正在编写一个解析器或一些具有大量错误处理的数据协议解码器。嵌套大括号的多个级别很快就会将代码变成一个完整的混乱。
如果我们从==更改为!=,我们可以摆脱嵌套if语句的需要。
if(input != good)
{
return error_input;
}
if(format != expected)
{
return error_format;
}
// if we got here then all is well
do_stuff();
return ok;
如果我们需要添加更多错误检查,这将更具可读性和扩展性。因此,通过更改为!=我们使代码更具可读性。
答案 2 :(得分:5)
我通常更喜欢&#34;等于&#34;,因为它使代码更多&#34;可读&#34;对于人类它使代码更简单。它将被命名为一个很好的编码指南&#34;而不是&#34;规则&#34;因为它根本不影响运行时(它是我以前公司的编码指南的一部分)。
检查一下:
if ( !isEmpty() )
与你写作相比,你的大脑需要几毫秒来理解测试的作用:
if ( isEmpty() )
即使它对运行时没有影响,我通常更喜欢&#34;等于&#34;与#34;不相等&#34;。
相同的参数适用于变量和函数名称。首选isSet
isNotSet
属性/方法。阅读像if ( !isNotSet() )
这样的代码比if ( isSet() )
更容易,即使它们最终是等效的。
如果您使用的代码无法控制,而且这个代码会提供回答否定问题的成员,那么:
if ( isNotSet() )
对于开发人员而言,更容易阅读:
if ( !isNotSet() )
答案 3 :(得分:1)
正如其他人所说,这是一个风格问题。没有真正的区别。
但要记住的一件事是尽量保持一致。如果您有一个块检查是否value1 == 2
,请尝试不要检查下一个块value2 != 4
。唯一不好的风格是不一致的风格。
答案 4 :(得分:0)
这是一个程序设计问题。作为程序员,您必须确定哪一个程序可以更好地执行,维护,可读性和性能。此外,这是两个完全不同的陈述。如果希望你的函数只在argc等于2时调用,而不是调用GetString();每当数字不是2时。
答案 5 :(得分:0)
现在两种情况之间没有语义差异,因为即使编译器应用的更简单的优化也可以中断“预期的执行流程”。
也许30到40年前,当C编译器的代码生成步骤与编写代码完全一致时,两种选择之间可能存在一些差异。
今天的实际差异在于语法和风格的清晰度。
所以,在写作时
while( *dst++=*src++ );
现在可以生成与
完全相同的机器代码for( i=0; src[i] != 0; i++ )
dst[i] = src[i];
dst[i] = '\0';
后者通常更容易阅读,如
中所示if( ! isOK() )
dontDoIt();
else
doIt();
并在
if( isOK() )
doIt()
else
dontDoIt();
但请放心,“清晰度”并非绝对值:它不仅取决于读者/评论者的“编程技巧和品味”,还取决于代码本身。
底线:选择你的产品并坚持下去以保持一致性!