【问题标题】:Chaining multiple greater than/less than operators链接多个大于/小于运算符
【发布时间】:2011-10-21 03:46:27
【问题描述】:

if 语句中,我想包含一个范围,例如:

if(10 < a < 0)

但是这样做,我收到一个警告“毫无意义的比较”。但是,这可以正常工作而没有任何警告:

if(a<10 && a>0)

第一种情况可以用C实现吗?

【问题讨论】:

  • 我之前没有注意到的事情:(a&gt;10 &amp;&amp; a&lt;0) 对于a 的任何可能值都是错误的。你的意思是(a&gt;0 &amp;&amp; a&lt;10)
  • @KeithThompson(6 年后)仅适用于原生数据类型。
  • @user202729(12 小时后)C 不支持非本地数据类型的 &lt;&gt;
  • @KeithThompson Sorry, I thought it was C++.

标签: c


【解决方案1】:

请注意,原始版本if(10 &lt; a &lt; 0) 是完全合法的。它只是没有做你可能(合理地)认为它做的事情。您很幸运,编译器将其识别为可能的错误并警告您。

&lt; 运算符从左到右关联,就像 + 运算符一样。所以就像a + b + c 真的意味着(a + b) + ca &lt; b &lt; c 真的意味着(a &lt; b) &lt; c&lt; 运算符在条件为假时产生 int 值 0,如果条件为真,则产生 1。因此,您要么测试 0 是否小于 c,要么测试 1 是否小于 c。

在不太可能的情况下,您确实想要这样做,添加括号可能会使警告静音。它还将让以后阅读您的代码的任何人放心,您知道自己在做什么,因此他们不会“修复”它。 (同样,这仅适用于您真的想要(a &lt; b) &lt; c)的不太可能发生的情况。)

判断a是否小于bb是否小于c的方法是:

a < b && b < c

(有一些语言,包括 Python,其中 a &lt; b &lt; c 表示 a&lt;b &amp;&amp; b&lt;c,这在数学中很常见。C 恰好不是其中一种语言。)

【讨论】:

  • 对于某些编译器,(a &lt; b) &lt; c 仍然会给出警告:将二进制布尔值的输出与 int 进行比较。你必须说(int) (a &lt; b) &lt; c。 :)
  • @Alex:不,你不必这样做。编译器可以警告任何他们喜欢的东西,但(a &lt; b) &lt; c 是一个具有明确语义的有效表达式。强制转换只是将已经是 int 类型的表达式转换为 int 类型。什么编译器警告它,警告是什么? (gcc 和 clang 没有。)
【解决方案2】:

第一个进行一次比较,然后将第一个的结果与第二个值进行比较。在这种情况下,运算符从左到右分组,因此相当于(10&lt;a) &lt; 0。它给你的警告实际上是因为&lt; 总是会产生 0 或 1。警告是告诉你第一次比较的结果永远不会小于 0,所以第二次比较总是会产生 false。

尽管编译器不会抱怨它,但第二个并没有太大的改进。一个数如何同时小于 0,但大于 10?理想情况下,编译器会警告您条件始终为假。大概你想要0&lt;a&lt;10a&gt;0 &amp;&amp; a&lt;10

您可以只使用一个比较来获得第二个效果:if ((unsigned)a &lt; 10) 仅当数字在 0..10 范围内时才会为真。范围比较通常可以简化为单个比较,代码如下:

if ((unsigned)(x-range_start)<(range_end-range_start))
    // in range
else
    // out of range.

曾经,这是体面的汇编语言编程的主要内容。不过,我怀疑很多人会再这样做(我当然不会)。

【讨论】:

    【解决方案3】:

    如上所述,您必须拆分支票。从编译器的角度考虑它,一次只查看一个运算符。 10

    【讨论】:

    • 我不认为 if 语句甚至会检查 true/false
    【解决方案4】:

    不,这不是 if 语句的有效语法,它应该有一个有效的常量表达式,或者其中可能有逻辑运算符,并且仅在括号中的表达式计算为真或非零值时执行

    【讨论】:

    • 语法有效;看我的回答。
    • 它在句法上是有效的,只是它并不意味着提问者希望它的意思。
    • @Alfred Nobel:取决于您所说的“工作”是什么意思。相当于if (1 &lt; 13),这是真的。纯属巧合,它恰好产生与if (10 &lt; 12 &amp;&amp; 12 &lt; 13) 相同的结果。 (我可以想象这种事情会造成多年未被发现的错误。)
    • 那么 if(11>1212 && 12
    • @Alfred Nobel:我完全同意;应该避免使用像 (a &lt; b &lt; c) 这样的表达式,因为它们太混乱了。即使您确切地知道它们的意思,您也不能确定作者确实做到了。 (为了记录,我没有对你投反对票,但可能是因为你错误地说这是“无效的语法”。)
    【解决方案5】:

    不,这是不可能的。
    您必须通过拆分两个条件检查来使用第二种方式。

    【讨论】:

      【解决方案6】:

      这是不可能的,你必须像案例 2 那样拆分支票。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-16
        • 2020-12-01
        • 2012-10-14
        • 2021-11-28
        • 2019-02-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多