C 检查非零的惯用方法

C 检查非零的惯用方法,c,if-statement,idioms,C,If Statement,Idioms,当我想检查一个值在C中是否为0时,按照惯用的方法是怎样做的 if(!num) if(num==0) 我总是喜欢第二种方式: if (num == 0) Asnum==0或ptr==NULL计算结果为布尔值,这就是目的。Java编译器强制执行此表单,但C/C++编译器没有 最糟糕的例子是: if (!strcmp(str, "something")) 这实际上掩盖了它的意图,因为strcmp函数族不返回布尔值,它们返回正、零或负(正如@JoachimPileborg所指出的) 但是,如果使用

当我想检查一个值在C中是否为
0
时,按照惯用的方法是怎样做的

  • if(!num)
  • if(num==0)

    • 我总是喜欢第二种方式:

      if (num == 0)
      
      As
      num==0
      ptr==NULL
      计算结果为布尔值,这就是目的。Java编译器强制执行此表单,但C/C++编译器没有

      最糟糕的例子是:

      if (!strcmp(str, "something"))
      
      这实际上掩盖了它的意图,因为strcmp函数族不返回布尔值,它们返回正、零或负(正如@JoachimPileborg所指出的)

      但是,如果使用
      int
      表示布尔类型,而C没有内置类型,则此表单可以:

      if (!b)
      
      但这可以通过创建自定义类型来实现自文档化:

      typedef int bool;
      #define true 1
      #define false 0
      
      bool b = true;
      if (!b)
      {
         ... etc
      }
      

      虽然这是一个品味的问题,但我发现这在很大程度上取决于意图。如果要将该值用作布尔值,
      可以。如果该值正在计数,则等式更有意义

      if (!isVisible) {...}
      if (isVisible == 0) {...} // Intention not as clear as line above.
      
      if (numberOfItems == 0) {...}
      if (!numberOfItems) {...} // Intention not as clear as line above.
      

      我认为这取决于上下文。如果变量引用的是布尔值,则最好是首选。否则,第二个更好。

      就你的风格而言,你想怎么做就怎么做。我不认为这有什么关系,只要你坚持并且清楚你想做什么,或者如果你在英语句子中表达得更好,并且可能强调你在做什么


      为了清楚起见,我通常会使用
      if(num==0)
      ,因为当我检查代码时,理解我在做什么需要更少的思考。

      不管其他人告诉你什么,只有一个例外

      不要使用
      float
      double
      来执行此操作。IEEE 754
      float
      s/
      double
      s/
      long double
      s(最常用的)通常不包含精确的值,因此直接将它们与
      0
      进行比较是愚蠢的(或者如果(!floatValue)

      例如:

      使用未优化编译可以返回(在ideone上)


      (如果启用优化,编译器可以以更高的精度预先计算一些值,并将它们四舍五入到
      0

      !!如果要检查值是否为非零,则value
      也将起作用

      !值
      在值为0时计算为1,在值为0时计算为0≠0.

      第二个
      翻转它,使其成为
      !!值
      当值为≠当value=0时为0和0。

      我们可能会争论哪种方法更好,但是惯用的方法,尽管我可以从其他古老的答案中看出,将是
      ,如果(!num)

      对于编译器来说,这当然不重要。对人类读者来说,它的确如此。因为这两种形式都被其他人使用,所以你应该习惯并识别它们。就我个人而言,我更喜欢最短的形式,它需要更少的时间(更少的标记,尤其是括号)来阅读和理解。特别是:

      if (!ptr) {}
      if (!strcmp(a,b)) {}
      
      你比我容易阅读

      if (ptr != NULL) {}
      if (strcmp(a,b) == 0) {}
      of (0 == strcmp()) {}
      

      最后一张表格让我身体不舒服。

      我正要写完全一样的东西。我想我们都写过同样的东西;)<代码>strcmp
      就是一个很好的例子。我喜欢Objective-C中的这一点,苹果提供了一个带有
      sensorderedescending
      sensorderedsame
      sensorderedescending
      的枚举,这使得意图比-1、0和1更清楚。对于
      strcmp
      情况,返回值实际上可以是除零之外的任何正值或负值。切勿与
      1
      -1
      @JoachimPileborg进行比较:同意;你会使用
      <0
      ==0
      >0
      。哦,糟糕!不“As num==0或ptr==NULL的计算结果是一个布尔值,这是目的。Java编译器强制执行此形式,但C/C++编译器不执行。”此问题标记为C。在C中,这些操作的计算结果不是布尔值。它们的计算结果为0或1,在规范中显式地为int 0或1。@JamesGreenhalgh:所以您更喜欢类似于:
      char*p=&something;if(p){…}
      ?如果必须选择第二个而不是第一个,请选择
      if(0==num)
      。第一个是最好的选择。@Als
      if(0==num)
      ,经典的尤达condition@DavidHeffernanQ:个人选择的答案。我更喜欢这个。甚至是C++ +XANATOS的技巧:当然,这个问题是关于C的。但是这不是与
      0.1
      不能在base 2中表示有关吗?@Paul是的(甚至
      0.2
      0.3
      )。但“为什么”并不是真正相关的。重要的是
      “不要使用float-an-double”
      给出的理由是错误的。“通常不包含精确值”不是真的:浮点类型包含精确值——但计算结果可能不是人们天真地假设的结果。如果将文字“0”指定给浮点,则它总是将true与“0”进行比较。对于-0,这也是一样的,比较起来等于+0。
      if (!ptr) {}
      if (!strcmp(a,b)) {}
      
      if (ptr != NULL) {}
      if (strcmp(a,b) == 0) {}
      of (0 == strcmp()) {}