C语言 if-else语句中的“等于”与“不等于”运算符[已关闭]

v2g6jxz6  于 2023-01-16  发布在  其他
关注(0)|答案(6)|浏览(167)
    • 已关闭**。此问题为opinion-based。当前不接受答案。
    • 想要改进此问题吗?**请更新此问题,以便editing this post可以用事实和引文来回答。

六年前关闭了。
Improve this question
在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循环的条件更改为"not equals to",并翻转相关的操作来实现与上面完全相同的结果。

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

无论如何,由于两者产生相同的结果,是否应该优先使用其中一个而不是另一个?

nhaq1z21

nhaq1z211#

在C++中有一个技术原因,那就是如果您习惯使用==而不是!=,那么就不需要重载那么多运算符。
当你处理函数对象(“functors”)时,这一点很重要。例如,当你使用一个标准容器类来存储你自己的自定义对象,并希望它们自动排序时。为了使函数对象(例如std::equal_to)工作,你的类只需要重载==操作符。你不必同时重载==!=
类似地,其他函数对象要求您只重载<,而不是< > == != <= >=的全部。
一般来说,人类大脑不容易理解否定。特别是当你有双重否定的时候。如果顺序在技术上不重要,那么在大多数编程语言中习惯于先编写相等性检查。通常这会使代码更容易阅读。
但就像编程和编码风格一样,没有非黑即白色的规则。如果检查的原因是为了发现错误,那么编写错误处理的最具可读性的方法优先于“人类发现否定更难读”。
这段代码写得不太好:

if(input == good)
{
  if(format == expected)
  {
    do_stuff();
    return ok;
  }
  else
  {
    return error_format;
  }
}
else
{
  return error_input;
}

假设我们需要添加更多的错误处理,这是一个很常见的例子:假设我们正在写一个解析器或者一些数据协议解码器,有很多错误处理。2多层嵌套的大括号很快就会把代码变成一团乱麻。
如果我们把==改成!=,就可以不需要嵌套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;

如果我们需要添加更多的错误检查,这将更加易读并且可伸缩。因此,通过更改为!=,我们使代码更加易读。

8cdiaqws

8cdiaqws2#

这只是一个编码风格的问题。我讨厌嵌套主逻辑,我将它写为:

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[])

avkwfej4

avkwfej43#

我通常更喜欢"等于",因为它使代码对人来说更"可读"。它使代码更简单。它更应该被称为"好的编码指南"而不是"规则",因为它根本不影响运行时(它是我以前公司的编码指南的一部分)。
检查以下内容:

if ( !isEmpty() )

你的大脑要比你写的多花几毫秒才能理解测试的作用:

if ( isEmpty() )

即使它对运行时没有影响,我通常更喜欢"等于"而不是"不等于"。
变量和函数名的参数也是一样的,isSet属性/方法比isNotSet更好,读一段像if ( !isNotSet() )这样的代码并不比if ( isSet() )容易,即使它们最终是等价的。
如果您使用您无法控制的代码,并且此代码提供了一个回答否定问题的成员,则:

if ( isNotSet() )

对于开发人员来说,绝对比以下内容更容易阅读:

if ( !isNotSet() )
vhipe2zx

vhipe2zx4#

就像其他人说的,这是风格问题。没有什么真实的的区别。
不过,有一点要记住,那就是要保持一致性。如果你有一个块检查value1 == 2,那么尽量不要让下一个块检查value2 != 4。唯一不好的是风格不一致。

qco9c6ql

qco9c6ql5#

这是一个程序设计问题。作为程序员,你必须决定哪一个在执行、维护、可读性和性能方面更好。而且,这是两个完全不同的语句。如果你想让你的函数只在argc等于2时调用,而不是调用GetString();只要该数目不是2。

8dtrkrch

8dtrkrch6#

如今,这两种情况在语义上没有区别,因为即使编译器应用的更简单的优化也可能"中断""预期的执行流"。
也许在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();

但请放心,"清晰度"不是绝对值:它不仅取决于读者/评审者的"编程技巧和品味",而且取决于代码本身。
底线:做出你的选择,并坚持它的统一性!

相关问题