各种原因, 总会导致在程序中你希望把一个 if 语句中的条件永远置为true为false, 比如为了测试的目的强制执行.
最容易想到的:
if( true || complex_condition )
不管 complex_condition 是什么, 前面的true || 会让它永远为真, 而
if( false && (complex_condition) )
则永远为假, 注意要把 (complex_condition) 用括号包围起来, 否则结果未必一定是false, 如
if( false && 3 < 2 || 2 > 1)
如果对 3 < 2 || 2> 1 不加理会, 只是把false && 放在前面, 是有漏洞的.
事情并没有就此这么简单.
我坚持使用编译器的最高等级的警告, 并且把所有警告视为错误, 以后我也会一直坚持这一原则.
这样一来, 前面的bool 表达式就是永远为true为永远为false, 而一个这样的表达式出现在程序中往往表明一个潜在的逻辑错误, 所以编译器对这面的语句给出一条警告:
if(true)
{
puts("Yes");
}
test.cpp(183) : warning C4127: conditional expression is constant
(这一警告只有/W4 时才给出)
这样一来, 直接使用true / false 或1, 0 这样的方法就不行了. 如何在C库中找出一个优雅的无副作用的最简单的true/false 语句, 同时绕过上述的警告?
在C#中我最先有这样的需求, 最直接的想法, 比较整数大小, 2 > 1永远为true, 反之为false,
但在C#中或C/C++中 2 > 1这样的表达式一样是编译期求值, 所以它们跟 true/false, 0/1 效果一样. 我最先的办法是这样:
if( Math.Max(1, 2) == 2)
稍假思索, 就容易看出这永远是true, 因为涉入了一个BCL中的函数调用, 所以编译器无法知道其返回结果是什么. 不会有编译警告.
类似的方法, if( Math.Max(1, 2) == 1) 来表达false.
然而, 后来我发现了一个狗屎定律, 跟莫菲定律很像: 对程序员, 只要有一个犯错的微弱机会, 他都能捕捉得到这个机会. 也就是说, 上面这样表达式, 有时候你就是会把它整反. 我就整反了, 往往是在简单的bool表达式上, 清醒的时候以为绝不会有如此愚蠢的错误, 偏偏就发生了...
所以经过一点思考之后, 我认为下面这样的C#表达式, 可以把这种犯错的机会减至最小:
if( Math.Max(1,1) == 0)
这个式子在视觉上是一个冲击, 它使得我们不必再定睛看仔细是Max, 还是Min, 3个数, 1和1找出最大, 或最小的, 无论如何不可能出来一个0. 类似地
if( Math.Max(1, 1) == 1)
无论它是其中的哪一个. 都是正确的, 因为被比较的两个数都是1.
这是目前我在C#中的解决方法.
性能?
我根本不关心这事.
现实一点说, Math.Max 这样的函数对你程序的整体性能影响力几乎为0, 除非你在一个循环里做这事无数次. 没有做profile, 我决不自以为是地瞎猜性能瓶颈在哪
回到开始的问题, C/C++中如何做?
我眼前的办法是:
if(isdigit('1') )
{
puts("yes");
}
表示永远为true
if(isspace('1') )
{
puts("yes");
}
我有意挑选这两个任何人都不太可能有所犹豫的问题, 1一定是数字, 1一定不是空格, 对isalpha('1') 或 isupper('1') 你未必能说对答案.
阅读(1802) | 评论(2) | 转发(0) |