Skip to content

第 6 章 做算术题


🏗️ 前情回顾:第 4 章掌握了六种类型,第 5 章让程序能对话。有了类型和输入输出,还缺什么?计算。 这章让程序做算术——这才是程序真正的本事。


🎯 本章目标

学完这一章,你能:

  • 使用 C++ 中的所有算术运算符
  • 理解运算符的优先级和结合性
  • 区分整数除法和取模运算
  • 写出复合赋值语句(+=-= 等)
  • 正确使用括号控制运算顺序

📖 故事引入

小华在写一个"分糖果"程序。有 17 颗糖,要平均分给 5 个小朋友。

"17 ÷ 5 = 3.4,每人 3.4 颗?"小华犯难了——糖果不能掰成 0.4 颗啊。

他需要的其实是两个答案:

  1. 每人能分到几颗?(整数除法)
  2. 还剩几颗?(求余数)

这两个问题,C++ 各有一个运算符能直接解决。而且不只是糖果——取余数这个操作在编程里比你想象的常用得多。


🧱 知识讲解

6.1 算术运算符一览

C++ 有 7 种算术运算符:

运算符名称例子结果
+5 + 38
-5 - 32
*5 * 315
/5 / 22(整数除法)
%取模(余数)5 % 21
++自增a++++aa 加 1
--自减a----aa 减 1

6.2 整数除法 vs 小数除法

这是本章最重要的一点:

cpp
int a = 5 / 2;      // a = 2(小数部分丢弃,不是四舍五入!)
double b = 5 / 2;   // b = 2.0(先做整数除法得 2,再转成 double)
double c = 5.0 / 2; // c = 2.5(5.0 是 double,所以做小数除法)

规则很简单:两个操作数都是整数 → 整数除法;任何一个操作数是浮点数 → 浮点除法。

cpp
// ❌ 错误理解:以为声明 double 就万事大吉
double b = 5 / 2;   // b = 2.0!先做整数除法得 2,再转成 double

// ✅ 正确写法:至少有一个操作数是浮点数
double c = 5.0 / 2; // c = 2.5(5.0 是 double,所以做小数除法)

这个规则会跟你好几年。请把它刻进脑子里。

6.3 取模运算 %

% 是"求余数"。17 ÷ 5 = 3 余 2,所以 17 % 5 = 2

取模的经典用法:

判断奇偶: 一个数除以 2,余数如果是 0,它就是偶数;余数如果是 1,它就是奇数。等后面学了条件判断语句,你就可以让程序自动告诉你一个数是奇数还是偶数了。

循环到头后回到起点

cpp
int day = (today + 100) % 7;  // 今天星期几,100 天后星期几?

提取个位数字

cpp
int ge = n % 10;  // 123 % 10 = 3

⚠️ % 只能用于整数,不能用于浮点数。

6.4 自增和自减

这是一个让初学者困惑的地方:

cpp
int a = 5;
int b = a++;   // b = 5, a = 6  (先赋 b,a 再加 1)
int c = ++a;   // c = 7, a = 7  (a 先加 1,再赋给 c)
写法含义执行顺序
a++后置自增先用 a 的值,用完再加 1
++a前置自增先加 1,再用新的值
a--后置自减同 a++,但是减 1
--a前置自减同 ++a,但是减 1

最佳实践:如果只是单独让变量加 1(a++++a 独占一行),选哪种都一样。初学者建议就用 a++,等熟练了再玩花样。

6.5 复合赋值运算符

这些是"运算 + 赋值"的简写:

写法等价于
a += 5a = a + 5
a -= 5a = a - 5
a *= 5a = a * 5
a /= 5a = a / 5
a %= 5a = a % 5
cpp
int score = 90;
score += 5;   // score = 95
score *= 2;   // score = 190
score /= 10;  // score = 19

不仅简洁,而且在复杂表达式中更不容易出错(变量名只出现一次)。

6.6 运算符优先级

如果你写 3 + 5 * 2,C++ 会先算 5 * 2 再算 3 + 10——和数学课一样,乘除优先级高于加减。

完整的优先级从高到低:

优先级运算符
最高() 括号
++ --(前置)
* / %
+ -
最低= += -= 等赋值

记不住全部优先级怎么办?——加括号。

cpp
// 不确定优先级的时候,用括号明确意图:
int result = (a + b) * (c - d);

💡 括号不仅让程序正确,也让读你代码的人轻松。额外多敲两个括号,比猜优先级划算一万倍。

6.7 整数运算的范围陷阱

cpp
int a = 100000;
int b = 100000;
int c = a * b;  // 100 亿!int 装不下,溢出成垃圾值
cout << c;      // 输出奇怪的东西

一旦乘法可能超出 int 范围,立即用 long long

cpp
long long a = 100000;
long long b = 100000;
long long c = a * b;  // 正确:10 亿,在 long long 范围内

常用的安全范围速记:两个 10 万相乘 = 100 亿,必超 int。两个 46340 以下的安全。


✋ 动手试试

试试 1:运行下面的代码,看输出:

cpp
int a = 10, b = 3;
cout << a / b << endl;   // ?
cout << a % b << endl;   // ?
cout << 10.0 / 3 << endl; // ?

试试 2:验证 a++++a 的区别。

cpp
int x = 5, y = 5;
int r1 = x++;
int r2 = ++y;
cout << r1 << " " << x << endl;
cout << r2 << " " << y << endl;

试试 3:用手算的方式判断 2024 和 2025 分别是闰年还是平年。判断规则:能被 4 整除但不能被 100 整除,或者能被 400 整除的,是闰年。想一下,这个规则如果写成 C++ 代码,% 运算符会怎么用?(暂时不用写代码,先思考。)


⚠️ 你踩过这些坑吗

  • [ ] 坑 1:整数除法误以为会得到小数double x = 5 / 2; 得到 2.0,不是 2.5。用 double x = 5.0 / 2;
  • [ ] 坑 2:取模用于浮点数double x = 5.5 % 2; 编译错误。取模只能用整数。
  • [ ] 坑 3:用 / 取数位时忘了整数特性 — 想取 123 的十位:123 / 10 = 12(整数除法),12 % 10 = 2。正确!但别写成 123 / 10.0
  • [ ] 坑 4:复合赋值误以为是数学等式x *= y + 1 等价于 x = x * (y + 1),不是 x = x * y + 1

📝 练习

基础题

1. 计算题

(1)17 / 4 = ____
(2)17 % 4 = ____
(3)17.0 / 4 = ____
(4)7 + 3 * 4 = ____
(5)(7 + 3) * 4 = ____

2. 代码题

写出以下代码的输出:

cpp
int a = 10;
a += 5;
a *= 2;
a -= 3;
a /= 3;
cout << a << endl;   // ?

3. 选择题

(1)7 / 2 的结果是?   A. 3.5   B. 3   C. 4   D. 3.0

(2)int x = 5; int y = x++; 执行后 xy 的值分别是?   A. x=5, y=5   B. x=6, y=5   C. x=6, y=6   D. x=5, y=6

(3)a %= 3 等价于?   A. a = a % 3   B. a = 3 % a   C. a = a / 3   D. a = 3 / a

4. 填空题

(1)int a = 5; a += 3; a *= 2; 执行后 a = ____。 (2)int n = 123; int ge = n % 10; 执行后 ge = ____。 (3)判断一个整数 n 是偶数的条件是 n % 2 == \_\_\_\_

提高题

5. 编程题 — 三位数拆解

输入一个三位整数(如 368),分别输出它的百位、十位、个位。

示例运行:

请输入一个三位数:368
百位:3
十位:6
个位:8

6. 编程题 — 时间计算

输入一个总分钟数(如 135),转换成"X 小时 Y 分钟"的格式。

7. 分析题

以下代码分别输出什么?先推算,再上机验证。

cpp
int a = 10, b = 3;
cout << a / b << " " << a % b << endl;
cout << 10.0 / 3 << endl;

a = 5; b = a++;
cout << a << " " << b << endl;

a = 5; b = ++a;
cout << a << " " << b << endl;

挑战题

8. 编程题 — 数字反转

输入一个三位整数,输出它反转后的数字(如输入 123,输出 321)。

(提示:先取出个位、十位、百位,再重新组合。)

9. 编程题 — 平均速度

小明骑自行车去学校。去的时候上坡,速度 12 km/h;回来下坡,速度 20 km/h。路程来回各 6 公里。求全程的平均速度(保留 2 位小数)。

注意:平均速度 ≠ (12 + 20) / 2。想想为什么?需要总路程除以总时间。


🧠 本章小结

算术运算:+ - * / %

/ 整数除法:丢小数,不四舍五入
% 取模:求余数,仅限整数
5.0 / 2 → 2.5(有浮点数参与就是小数除法)

++ / --  自增自减(前置先加后用,后置先用后加)
+= -= *= /= %=  复合赋值(简写)

优先级:记不住就加括号 → ( )

📝 配套练习

共10题。M1题量最大的章节——运算符是所有后续代码的"螺丝刀",必须每种运算符都练到。。★核心(课堂必做) ◆拓展(课后练习) ★★★挑战(选做)

级别题号链接覆盖知识点
★ 核心J0006https://hydro.ac/d/srqc/p/J0006算术运算符、优先级、类型转换
◆ 拓展J0009https://hydro.ac/d/srqc/p/J0009取模%、整除/、同一输入→两个输出
◆ 拓展J0010https://hydro.ac/d/srqc/p/J0010方程建模、算术→条件翻译
◆ 拓展luogu-B2035https://hydro.ac/p/luogu-B2035关系运算符(> <)、if判断
◆ 拓展luogu-B2037https://hydro.ac/p/luogu-B2037取模%、奇偶判断
◆ 拓展luogu-B2039https://hydro.ac/p/luogu-B2039关系运算符、三种结果输出
◆ 拓展luogu-B2042https://hydro.ac/p/luogu-B2042逻辑运算符&&、同时整除判断
◆ 拓展luogu-B2049https://hydro.ac/p/luogu-B2049三目运算符?:、if-else等价写法
◆ 拓展J0012https://hydro.ac/d/srqc/p/J0012复合赋值、+=、自增模式
★★★ 挑战luogu-P2433https://hydro.ac/p/luogu-P2433综合运算、多题型、格式多样性

💡 练习建议:先完成 2 道★核心题,确保掌握本章基本方法;再完成 8 道◆拓展题,覆盖不同变式和细节;★★★挑战题建议在完成拓展题后再做,涉及多知识点综合。


配套练习

共10题。M1题量最大的章节——运算符是所有后续代码的"螺丝刀",必须每种运算符都练到。★核心(课堂必做) · ◆拓展(课后练习) · ★★★挑战(选做)

级别题号链接覆盖知识点
★ 核心J0006https://hydro.ac/d/srqc/p/J0006算术运算符、优先级、类型转换
◆ 拓展J0009https://hydro.ac/d/srqc/p/J0009取模%、整除/、同一输入→两个输出
◆ 拓展J0010https://hydro.ac/d/srqc/p/J0010方程建模、算术→条件翻译
◆ 拓展luogu-B2035https://hydro.ac/p/luogu-B2035关系运算符(> <)、if判断
◆ 拓展luogu-B2037https://hydro.ac/p/luogu-B2037取模%、奇偶判断
◆ 拓展luogu-B2039https://hydro.ac/p/luogu-B2039关系运算符、三种结果输出
◆ 拓展luogu-B2042https://hydro.ac/p/luogu-B2042逻辑运算符&&、同时整除判断
◆ 拓展luogu-B2049https://hydro.ac/p/luogu-B2049三目运算符?:、if-else等价写法
◆ 拓展J0012https://hydro.ac/d/srqc/p/J0012复合赋值、+=、自增模式
★★★ 挑战luogu-P2433https://hydro.ac/p/luogu-P2433综合运算、多题型、格式多样性

练习建议:先在课堂完成 1 道★核心题,掌握本章基本方法;课后完成 8 道◆拓展题,覆盖不同变式和细节;★★★挑战题建议在完成拓展题后再做,涉及多知识点综合。

自查清单

  • [ ] 我能区分整数除法和浮点除法
  • [ ] 我知道 % 的用法(奇偶、循环、取位)
  • [ ] 我能用 ++--
  • [ ] 我会用复合赋值运算符
  • [ ] 我知道什么时候该换 long long 防止溢出

🚀 下章预告:加减乘除都会了。下一章打开 C++ 的数学工具箱——绝对值、平方根、随机数。