2.“计算与比较”:运算符的世界
“计算与比较”:运算符的世界 (算术, 关系, 逻辑)
本章导读 (The Hook)
在上一章,我们学会了制造各种各样的“记忆盒子”(变量)来存储数据。但如果只能存,那程序就太无聊了。一个游戏程序,需要计算你攻击后怪物还剩多少血量;一个购物网站,需要计算你买的所有商品的总价。
要完成这些任务,我们就需要一套专门的“工具”来操作这些盒子里面的数据。这些工具,就是运算符 (Operators)。
- 有些工具像计算器,负责加减乘除(算术运算符)。
- 有些工具像天平,负责比较两个盒子里的东西哪个大、哪个小、是否相等(关系运算符)。
- 还有些工具像逻辑门,能进行“与、或、非”这样更复杂的判断(逻辑运算符)。
本章,我们就来全面认识一下 C++ 工具箱里这些最常用、最重要的运算符。学会了它们,你的程序才真正拥有了“计算”和“思考”的能力!
专业术语速查表 (Glossary)
点击展开/折叠本章术语表
运算符 (Operator)
- 通俗比喻:一个执行特定操作的符号,比如
+号、>号。 - 解释:用于执行算术、关系、逻辑等运算的特殊符号。
- 通俗比喻:一个执行特定操作的符号,比如
操作数 (Operand)
- 通俗比喻:被运算符操作的“盒子”(变量)或值。在
5 + score这个表达式里,5和score都是操作数。 - 解释:运算符作用于其上的实体,可以是变量或字面量。
- 通俗比喻:被运算符操作的“盒子”(变量)或值。在
表达式 (Expression)
- 通俗比喻:由运算符和操作数组合而成的、能得出一个结果的“算式”。例如
(score + 10) * 2就是一个表达式。 - 解释:一个由变量、常量、运算符和函数调用组成的序列,它可以被计算出一个值。
- 通俗比喻:由运算符和操作数组合而成的、能得出一个结果的“算式”。例如
算术运算符 (Arithmetic Operators)
- 解释:用于执行基本数学运算,如
+(加),-(减),*(乘),/(除),%(取模/求余数)。
- 解释:用于执行基本数学运算,如
关系运算符 (Relational Operators)
- 解释:用于比较两个操作数的关系。其结果是一个
bool值 (true或false)。包括==(等于),!=(不等于),>(大于),<(小于),>=(大于等于),<=(小于等于)。
- 解释:用于比较两个操作数的关系。其结果是一个
逻辑运算符 (Logical Operators)
- 解释:用于组合或修改布尔表达式。包括
&&(逻辑与, AND),||(逻辑或, OR),!(逻辑非, NOT)。
- 解释:用于组合或修改布尔表达式。包括
赋值运算符 (Assignment Operators)
- 解释:用于给变量賦值。最基本的是
=。还有复合赋值运算符,如+=,-=,*=,/=,%=。
- 解释:用于给变量賦值。最基本的是
自增/自减运算符 (Increment/Decrement)
- 解释:用于将变量的值加 1 (
++) 或减 1 (--)。
- 解释:用于将变量的值加 1 (
优先级 (Precedence)
- 通俗比喻:就像数学里的“先乘除后加减”规则一样,它规定了哪个运算符应该被优先计算。
- 解释:运算符被执行的先后顺序。
核心概念讲解 (The Core Concept)
1. 算术运算符 (The Calculator Tools)
这是最简单、最直观的一类工具,就像你的计算器一样。
#include <iostream>
int main() {
int a = 10;
int b = 3;
std::cout << "a + b = " << a + b << std::endl; // 输出 13
std::cout << "a - b = " << a - b << std::endl; // 输出 7
std::cout << "a * b = " << a * b << std::endl; // 输出 30
// --- 注意力集中!除法和取模有玄机 ---
// 整数除法:结果会舍去小数部分,不是四舍五入!
std::cout << "a / b = " << a / b << std::endl; // 输出 3, 而不是 3.333
// 取模(求余数):计算 a 除以 b 后的余数
std::cout << "a % b = " << a % b << std::endl; // 10 除以 3 商 3 余 1,所以输出 1
// 要想得到精确的小数结果,操作数中至少要有一个是浮点数
double c = 10.0;
std::cout << "c / b = " << c / b << std::endl; // 输出 3.33333
return 0;
}算术天坑:整数除法
int / int 的结果永远是 int!5 / 2 在 C++ 中等于 2,小数部分会被直接截断。这是无数新手 bug 的来源。
解决方案:确保参与除法运算的至少有一个是 double 类型,比如写成 5.0 / 2。
2. 赋值运算符 (The Organizer Tools)
我们已经用过最基础的赋值运算符 = 了。C++ 还提供了一系列“快捷方式”,让代码更简洁。
| 快捷方式 | 等价于... | 示例 (假设 int score = 10;) | 结果 |
|---|---|---|---|
+= | score = score + 5 | score += 5; | 15 |
-= | score = score - 2 | score -= 2; | 8 |
*= | score = score * 3 | score *= 3; | 30 |
/= | score = score / 4 | score /= 4; | 2 (整数除法!) |
%= | score = score % 3 | score %= 3; | 1 |
3. 自增/自减运算符 (The Counter Clicks)
++ (加一) 和 -- (减一) 是非常常用的快捷方式,尤其在循环中。
int apples = 5;
apples++; // 等价于 apples = apples + 1; 现在 apples 是 6
std::cout << apples << std::endl;
apples--; // 等价于 apples = apples - 1; 现在 apples 是 5
std::cout << apples << std::endl;知识点拓展:前缀 vs 后缀
++ 和 -- 可以放在变量前面(前缀)或后面(后缀),它们有细微但重要的区别:
- 前缀
++apples:先给apples加 1,然后使用apples的新值。 - 后缀
apples++:先使用apples的旧值,然后再给apples加 1。
int a = 5;
int b = ++a; // a 先变成 6, 然后把 6 赋值给 b。结果: a=6, b=6
int c = 5;
int d = c++; // 先把 c 的旧值 5 赋值给 d, 然后 c 再变成 6。结果: c=6, d=5新手建议:在完全理解之前,始终将自增/自减单独作为一行代码来写(如 apples++;),可以有效避免混淆。
4. 关系运算符 (The Scales)
这类工具用来比较,结果总是 bool 类型的 true 或 false。
#include <iostream>
int main() {
int myScore = 100;
int passingScore = 60;
std::cout << std::boolalpha; // 让输出显示 true/false 而不是 1/0
std::cout << "Is my score > passing score? " << (myScore > passingScore) << std::endl; // true
std::cout << "Is my score == passing score? " << (myScore == passingScore) << std::endl; // false
std::cout << "Is my score != 100? " << (myScore != 100) << std::endl; // false
return 0;
}史上最强天坑:== (等于) vs = (赋值)
这是足以摧毁你一下午的 Bug!
==是比较,像天平,问:“这两个东西相等吗?”=是赋值,像搬运工,说:“把右边的东西装到左边的盒子里去!”
如果你在需要比较的地方误写成了 =,例如在 if (score = 60) 中,程序不会报错,但逻辑会全错!它会先把 60 赋值给 score,然后整个表达式的结果是 60(在逻辑判断中非零即为真),导致判断恒为 true。
务必反复检查你的比较语句,确保用的是 ==!
5. 逻辑运算符 (The Logicians)
这类工具用于组合多个关系表达式,形成更复杂的判断。
| 运算符 | 名称 | 含义 | 示例 |
|---|---|---|---|
&& | 逻辑与 (AND) | 两边都为 true,结果才为 true。 | (age > 18) && (hasTicket == true) |
| ` | ` | 逻辑或 (OR) | |
! | 逻辑非 (NOT) | 把 true 变 false,false 变 true。 | !isGameOver (如果游戏没结束,则为 true) |
6. 运算符优先级 (The Rules of Engagement)
当一个表达式里有多个运算符时,谁先算?C++ 有一套严格的规则,但你不需要全背下来。
简化版规则:
- 括号
()拥有最高优先级。 - 自增
++、自减--、逻辑非!优先级很高。 - 乘
*、除/、模%优先于 加+、减-。 - 关系运算符
><==优先于 逻辑运算符&&||。 - 赋值运算符
=的优先级通常最低。
黄金法则:如果不确定优先级,就用括号 () 把你想先计算的部分括起来! 这不仅能保证计算顺序正确,还能让代码更容易阅读。int result = (a + b) * c; 永远比 int result = a + b * c; 清晰。
动手试试 (Try It Yourself!)
超市结账
- 创建一个
double变量price并设为12.5。 - 创建一个
int变量quantity并设为3。 - 计算并打印总价
totalCost。
- 创建一个
电影院入场
- 创建
int变量age并设为15。 - 创建
bool变量withAdult并设为true。 - 写一个表达式,判断一个
15岁的孩子,在有成年人陪同的情况下,是否满足“年龄大于 12 岁或者有成年人陪同”的入场条件?打印这个表达式的结果(true或false)。
- 创建
时间换算
- 创建一个
int变量totalSeconds并设为3661。 - 计算并打印出
totalSeconds等于多少分钟 (minutes) 和多少秒 (seconds)。提示:你会需要/和%。
- 创建一个
“防坑”指南与常见错误 (The Pitfalls)
再次强调:== vs =
这个错误太常见了,值得我们再次警告。在写条件判断时,如果你想问“是否等于”,请使用 ==!
再次强调:整数除法
10 / 3 的结果是 3!如果你需要小数,请确保至少有一个操作数是 double 或 float,例如 10.0 / 3。
本章小结 (The Summary)
我们今天为自己的“记忆盒子”配备了一整套强大的“工具”——运算符。
- 算术运算符 (
+ - * / %) 负责数学计算,要特别小心整数除法。 - 赋值运算符 (
= += -=) 负责给变量存入和更新值。 - 自增自减运算符 (
++ --) 是加一减一的便捷写法。 - 关系运算符 (
== != > <) 负责比较,返回true或false,要和赋值=区分开。 - 逻辑运算符 (
&& || !) 负责组合逻辑判断。 - 不确定优先级时,使用括号
()是最佳选择。
现在,我们既能存储数据,又能处理数据并得到 true 或 false 的判断结果了。
