最常见方式是 a == b && b == c;c++ 不支持 a == b == c,因会先算 a == b 得 0/1 再与 c 比较;需注意类型一致、浮点数用误差判断、自定义类型重载 operator== 并满足等价关系。

直接用 == 比较三个数是否相等
最常见也最直接的方式是写 a == b && b == c。C++ 中没有三元等值运算符(比如 Python 的 a == b == c),所以不能写成 a == b == c——这会先算 a == b 得到 true 或 false(即 1 或 0),再跟 c 比较,结果完全不可靠。
实际使用时注意:
-
a、b、c类型要一致或可隐式转换,否则可能触发意外的类型提升(比如int和double比较) - 浮点数慎用
==,应改用误差范围判断(见下一条) - 自定义类型需重载
operator==,且保证其满足自反性、对称性、传递性
浮点数比较必须用 abs(diff)
直接用 == 判断 float 或 double 是否相等几乎总是错的,因为浮点计算存在舍入误差。正确做法是检查差值的绝对值是否小于一个极小阈值。
例如:
double a = 0.1 + 0.2; double b = 0.3; double c = 0.3; bool all_equal = (std::abs(a - b) <p>关键点:</p>
- 别用固定
1e-9硬编码,更稳妥的是用std::numeric_limits<double>::epsilon()</double>做相对误差(尤其当数值很大或很小时) - 不要写成
std::abs(a - b) 这类形式来处理 <code>b == 0的情况,得单独分支或用std::max(1.0, std::abs(b))归一化 - 如果三个数都是
NaN,任何比较都返回false,包括NaN == NaN,需额外用std::isnan()处理
模板函数封装可复用的三值等值判断
重复写 a == b && b == c 容易出错,也难维护。可以封装成函数模板,支持任意可比较类型,并自动处理浮点特例。
简单版本示例:
template <typename t>
bool are_equal(T a, T b, T c) {
if constexpr (std::is_floating_point_v<t>) {
auto eps = std::numeric_limits<t>::epsilon() * 10;
return std::abs(a - b) <p>使用时注意:</p>
<ul>
<li>
<code>if constexpr</code> 要求 C++17 及以上;若用旧标准,得用 SFINAE 或函数重载</li>
<li>该模板不处理用户自定义浮点类,只覆盖内置 <code>float</code>/<code>double</code>/<code>long double</code>
</li>
<li>传入引用(<code>const T&</code>)更安全,避免大对象拷贝,但模板推导时要注意 const/volatile 修饰</li>
</ul>
<h3>宏或 constexpr 函数不适合做通用判断</h3>
<p>有人想用宏如 <code>#define EQUAL3(a,b,c) ((a)==(b) && (b)==(c))</code> 图省事,但宏有严重隐患:</p>
<ul>
<li>参数带副作用会出错,比如 <code>EQUAL3(i++, i++, i++)</code> 行为未定义</li>
<li>无法做类型检查,编译器不会报类型不匹配错误</li>
<li>调试时看不到宏展开逻辑,堆栈里只有原始调用行号</li>
</ul>
<p>而 <code>constexpr</code> 函数虽能编译期求值,但对浮点数仍受限于 IEEE 754 表达精度——<code>constexpr double x = 0.1 + 0.2;</code> 在不同编译器上可能生成不同 bit 模式,导致 <code>constexpr</code> 版本在编译期就“误判”。</p>
<p>真正需要编译期判断三个整型常量是否相等?用 <code>static_assert(a == b && b == c, "...")</code> 更直接可靠。</p></t></t></typename>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











