链接多个大于/小于运算符

Chaining multiple greater than/less than operators

提问人:jscode 提问时间:8/6/2011 最后编辑:Keith Thompsonjscode 更新时间:10/6/2019 访问量:50770

问:

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

if(10 < a < 0)

但通过这样做,我会得到一个警告“毫无意义的比较”。但是,这在没有任何警告的情况下工作正常:

if(a<10 && a>0)

第一种情况可以在 C 语言中实现吗?

c

评论

7赞 Keith Thompson 1/27/2012
我以前没有注意到的东西:对于任何可能的值都是假的。你是说吗?(a>10 && a<0)a(a>0 && a<10)
0赞 user202729 2/10/2018
@KeithThompson(6 年后)仅适用于本机数据类型。
1赞 Keith Thompson 2/11/2018
@user202729(12 小时后)C 不支持非本机数据类型。<>
0赞 user202729 2/11/2018
@KeithThompson 对不起,我以为C++

答:

6赞 user703016 8/6/2011 #1

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

5赞 Alok Save 8/6/2011 #2

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

-2赞 nobalG 8/6/2011 #3

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

评论

2赞 Keith Thompson 8/6/2011
它是有效的语法;看我的答案。
1赞 Steve Jessop 8/6/2011
这在句法上是有效的,它只是并不意味着提问者希望它的意思。
0赞 Keith Thompson 8/6/2011
@Alfred 诺贝尔奖:这取决于你所说的“工作”是什么意思。它等价于 ,这是真的。纯属巧合的是,它恰好产生了与 相同的结果。(我可以想象这种事情会造成一个多年未被发现的错误。if (1 < 13)if (10 < 12 && 12 < 13)
0赞 nobalG 8/6/2011
那么 if(11>12<10) 将产生 true,& 等价于 if(11>12 & 12<10) 将产生 false......那么这种狗屎声明怎么会被允许...... @keith汤普森
1赞 Keith Thompson 8/6/2011
@Alfred 诺贝尔:我完全同意;应该避免使用这样的表达方式,因为它们太令人困惑了。即使你确切地知道它们的意思,你也不能确定作者是否知道。(郑重声明,我没有对你投反对票,但不管是谁投了反对票,可能是因为你错误地说这是“无效的语法”。(a < b < c)
0赞 Steve 8/6/2011 #4

如上所述,您必须拆分支票。从编译器的角度考虑一下,编译器一次只看一个运算符。10 < A = 真或假。然后它去执行 True/False < 0,这没有意义。

评论

0赞 nobalG 8/6/2011
我不认为 if 语句甚至会检查 true/false<0 与否,即使它是否有意义......哈哈..:D
45赞 Keith Thompson 8/6/2011 #5

请注意,原始版本是完全合法的。它只是没有做你可能(合理地)认为它做的事情。你很幸运,编译器认为这是一个可能的错误,并警告你。if(10 < a < 0)

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

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

检查是否小于和小于的方法是:abbc

a < b && b < c

(有些语言,包括 Python,其中表示 ,就像在数学中一样。C语言恰好不是这些语言之一。a < b < ca<b && b<c

评论

0赞 Alex 6/21/2017
对于某些编译器,say 仍然会发出警告:将二进制布尔值的输出与 int 进行比较。你不得不说.:)(a < b) < c(int) (a < b) < c
1赞 Keith Thompson 6/22/2017
@Alex:不,你不必这样做。编译器可以警告他们喜欢的任何内容,但是一个具有明确定义语义的有效表达式。强制转换只是将已经属于 type 的表达式转换为 类型 。什么编译器警告它,警告是什么?(GCC 和 Clang 没有。(a < b) < cintint
2赞 Jerry Coffin 8/6/2011 #6

第一个值执行一个比较,然后将第一个值的结果与第二个值进行比较。在本例中,运算符从左到右分组,因此它等效于 。它给你的警告实际上是因为总是会产生 0 或 1。警告告诉您,第一次比较的结果永远不能小于 0,因此第二次比较将始终产生 false。(10<a) < 0<

尽管编译器不会抱怨它,但第二个并没有太大的改进。一个数字怎么能同时小于 0,但大于 10?理想情况下,编译器会给你一个警告,指出条件始终为 false。大概你想要和 .0<a<10a>0 && a<10

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

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

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

评论

0赞 Andreas Wenzel 1/23/2023
请注意,同时,该问题已被编辑,以至于您回答的第二段无效。