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

= 不是"等于",是"从右往左装盒子"。复合赋值 += -= *= /= %= 是"先算术、再装回原盒子"的偷懒简写——循环计数里天天见。

一、= 的规矩:从右往左

2.3.2 讲过:= 的执行顺序是先算右边,再把结果装进左边的盒子。

两个推论:

  1. 左边必须是个"盒子"(能装东西的地方)。2 = a 编译报错——常数 2 没有盒子。这正好呼应 3.1.2 的"常量放左边"防手滑神技:5 = score 必报错。
  2. 连等号从右往左依次装:a = b = c = 0; 等价于先 c = 0,再 b = c,最后 a = b。三个盒子同时清零,一行搞定。

为什么连等号能成立? 因为赋值表达式本身有值——c = 0 这个式子算完的"值"就是 0(顺便把 0 装进了 c)。这个值再被 = 装进 b,以此类推。3.3.1 讲表达式时你会再见到"赋值也有值"这件事。

二、复合赋值家族:先算术,再装回原盒

写法 等价于 含义
a += 3 a = a + 3 在 a 原来的值上加 3,装回 a
a -= 3 a = a - 3 减 3 装回
a *= 3 a = a * 3 乘 3 装回
a /= 3 a = a / 3 除 3 装回(整数除法丢小数)
a %= 3 a = a % 3 取余装回

五个复合符号的后半截,正好对应 3.1.1 的算术五兄弟——一个不少。

两个细节:

三、为什么会有这套简写?

不是卖弄语法,是真用得频繁:

count += 1;        // 计数器 +1(循环里每转一圈数一个)
sum += score;      // 累加器:把新分数加进总和
product *= n;      // 累乘器:阶乘、连乘

"把某变量的新值,基于旧值算出来再存回去"——这个动作在程序里到处都是,所以每个语言都给它配了简写。第 5 章 for 循环里,i += 1(或 i++)几乎是每段循环的标配零件。

四、动手 Demo:累加器 + 累乘器

#include <iostream>
using namespace std;

int main() {
    int a = 10;
    a += 5;   cout << a << endl;   // 15
    a -= 3;   cout << a << endl;   // 12
    a *= 2;   cout << a << endl;   // 24
    a /= 5;   cout << a << endl;   // 4(24/5=4.8 丢小数!)
    a %= 3;   cout << a << endl;   // 1

    // 连等号:三个盒子同时清零
    int x = 1, y = 2, z = 3;
    x = y = z = 0;
    cout << x << y << z << endl;   // 000
    return 0;
}

看到什么算成功:输出 15 12 24 4 1 和 000。重点盯 24 / 5 = 4——复合赋值里的整数除法照样丢小数,坑不因为你换了写法就绕开。

30 秒实验:把 a /= 5 改成 a = a / 5.0;——注意 a 是 int,结果还是 4(先算出 4.8,装进 int 盒子时再砍一次)。类型转换的完整规矩在 3.3.2 细讲。

五、常见误区

  1. "a += 3 只是少打几个字,没区别"——多数情况等价,但右边是复杂式子时,a[f(x)] += 1 保证"取盒子"这个动作只做一次。现阶段记住简写常用、可读性好即可。
  2. "a *= b + 2 是先乘 b 再加 2"——反了,右边整体先算:a = a * (b + 2)。
  3. "连等号是从左往右"——从右往左。a = b = c = 0 先装 c。
  4. "= 和 == 混着用没事"——3.1.2 头号坑,本节再敲一次黑板:= 改盒子、== 问相等。
自测四问(点开对答案) 1. `a = 7; a %= 4;` 之后 a 是多少?——`3`(7 除 4 余 3)。 2. `x = y = z = 0;` 的执行顺序?——先 `z = 0`,再 `y = z`,最后 `x = y`(从右往左)。 3. `a = 5; a *= 2 + 1;` 之后 a 是多少?——`15`(右边整体先算:5×3)。 4. `2 = a;` 会怎样?——编译报错,常数 2 不是可赋值的盒子(呼应 3.4 的"左值"概念)。

相关笔记