🔷 第三章 运算符与表达式
📄 一句话概括

关系运算符六个——> < >= <= == !=——干的事就一件:比较两边,回答"真"或"假"。它的产出是 bool 值(1/0),而 == 与 = 的手滑混淆,是全宇宙 C++ 新手的头号坑。

一、六个符号一张表

设 a=5, b=3:

运算符 读作 例子 结果
> 大于 a > b 1(真)
< 小于 a < b 0(假)
>= 大于等于 a >= 5 1(等于也算真)
<= 小于等于 a <= 3 0
== 等于 a == 5 1
!= 不等于 a != 3 1

三个写法细节:

二、产出是 bool,不是"对错"二字

关系运算的结果是 bool 类型:真 = true = 1,假 = false = 0。

cout << (5 > 3) << endl;      // 输出 1
cout << (5 < 3) << endl;      // 输出 0
bool isAdult = 18 <= 20;      // isAdult 存的是 true

注意第一行要加括号——cout << 5 > 3 会被理解为"先把 5 输出,再拿输出结果和 3 比",因为 << 的优先级比 > 高(优先级 3.2 节专讲)。关系表达式拿去输出或赋值时,习惯性套一层括号。

三、头号坑:== 与 = 手滑

两个符号长得像,干的活天差地别:

手滑会怎样?看这段:

int score = 3;
if (score = 5)          // 手滑:写成了赋值!
    cout << "优秀";

这一行干了两件事:先把 score 改成 5(数据被偷偷改了),然后判断"赋值结果的真假"——5 非 0 即真,条件恒成立,永远输出"优秀"。更糟的是,编译器多半只给个警告,不报错——程序照样编译通过,bug 就此潜伏。

防手滑神技:常量放左边。

if (5 == score)    // 推荐写法

万一手滑写成 if (5 = score),就是"给常数 5 赋值"——编译器直接报错,当场抓获。这个写法叫 Yoda 条件(像《星球大战》Yoda 的语序),不强制,但值得养成习惯。

四、浮点比较:== 基本不可靠

回看 2.2.2 的硬知识:浮点是近似值。所以:

double x = 0.1 + 0.2;
cout << (x == 0.3) << endl;   // 输出 0!0.1+0.2 = 0.30000000000000004

浮点判断相等要用"差值够小":

#include <cmath>                          // fabs 在这里
if (fabs(x - 0.3) < 0.0000001)            // |x - 0.3| 小于十的负七次方
    cout << "算相等";

整数用 == 没问题(整数是精确的),浮点一律用差值——把它当铁律。

五、动手 Demo:比较器试验台

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    int a = 5, b = 3;
    cout << (a > b) << endl;              // 1
    cout << (a == b) << endl;             // 0
    cout << (a >= 5) << endl;             // 1(等于也算)

    double x = 0.1 + 0.2;
    cout << (x == 0.3) << endl;           // 0(坑!)
    cout << (fabs(x - 0.3) < 0.0000001) << endl;  // 1(正确姿势)

    int score = 3;
    if (score = 5) cout << "被手滑赋值了,恒真" << endl;
    cout << score << endl;                // 5 —— 数据被偷改了!
    return 0;
}

看到什么算成功:1 0 1 0 1 被手滑赋值了,恒真 5。亲眼看到 score 从 3 变 5,比背一百遍印象深刻。

30 秒实验:把 if (score = 5) 改成 if (5 == score),再把 == 改成 =——if (5 = score) 编译器当场报错。这就是常量放左边的保险。

六、常见误区

  1. "5 > 3 输出的是'真'字"——输出的是 1。程序里真假就是数字。
  2. ">= 里的等于不算"——算!a >= 5 在 a 等于 5 时为真。"含等于"的边界条件是 bug 高发区,写条件时先问自己:边界值到底归哪边?
  3. "if (score = 5) 能编译,所以没问题"——能编译只说明语法合法,不代表逻辑对。警告也值得看一眼。
  4. "浮点比较偶尔会不准"——不是偶尔,是基本必然。浮点比相等一律用差值。
自测四问(点开对答案) 1. `a >= 5` 在 `a = 5` 时的结果?——`true`(1),含等于。 2. `if (a = 0)` 手滑后,条件是真是假?——**假**(赋的值是 0,非 0 即真反过来说 0 即假)。注意:不是所有手滑都恒真,取决于赋的值。 3. 为什么浮点判断相等不用 `==`?——浮点是近似值,`0.1+0.2` 存的是 `0.30000000000000004`。 4. 关系运算的产出类型是什么?——`bool`。

相关笔记