第六章:分支语句和逻辑运算符 | C++ Primer Plus 重点带看
条件运算符的错误防范
为什么有人写 if (3 == x) 而不是 if (x == 3)?
这是一种防御性编程技巧,叫做 Yoda 条件表达式(Yoda Condition),目的是让编译器帮你发现将 == 误写成 = 的错误。
int x = 5;
// 正常写法
if (x = 3) { } // ❌ 把 3 赋给 x,然后判断 x(=3,非零为真),不会报错,但逻辑错误
// Yoda 写法
if (3 = x) { } // ✅ 编译报错!不能对字面量 3 赋值
这个技巧来自 C 语言时代,现代 C++ 中不太需要了,因为:
- 编译器会发警告:大多数编译器对 if (x = 3) 会发出警告(-Wall)。
- 建议开编译器警告:用 -Wall -Wextra 甚至 -Werror(警告视为错误)。
- 可读性差:if (3 == x) 读起来不自然。
C++ 中的关系表达式链式写法问题
为什么 if (1 < x < 6) 不是判断 x 是否在 1 到 6 之间:因为 C++ 中 < 运算符是从左到右计算的,1 < x < 6 实际上是 (1 < x) < 6,而不是数学上的 1 < x 且 x < 6。
int x = 10;
// 数学含义:x 是否在 (1, 6) 之间? → 否,10 不在
// C++ 实际执行:
// 第一步:1 < x → 1 < 10 → true → 转为 int 得 1
// 第二步:1 < 6 → true
if (1 < x < 6) { } // x = 10 时居然为 true!
// 误以为 a == b == c 表示三者相等
int a = 1, b = 1, c = 0;
if (a == b == c) { } // (a == b) == c → (1 == 1) == 0 → 1 == 0 → false
// ❌ 不是 a==b 且 b==c
// 正确写法
if (a == b && b == c) { }
// 误以为 a != b != c 表示三者互不相等
if (a != b != c) { } // (a != b) != c → (false) != 0 → true
// ❌ 语义完全错误
// 正确写法
if (a != b && b != c && a != c) { }
唯一需要三操作数的运算符:条件运算符 ?:
int max = (a > b) ? a : b; // 条件 ? 真值 : 假值 // 三个操作数: // 条件:a > b // 真值:a // 假值:b
switch 语句注意事项
1、括号里面必须是一个结果为整形的表达式,不能进行浮点测试;原因:switch 的底层实现是跳转表(jump table),编译器需要用表达式的值作为索引直接跳转。浮点数精度问题、字符串无法直接做索引,所以都不允许。
int x = 2;
switch (x) { } // ✅ int
char ch = 'a';
switch (ch) { } // ✅ char 本质上是整型
enum Color { RED, GREEN, BLUE };
switch (RED) { } // ✅ 枚举值本质上是整型
bool flag = true;
switch (flag) { } // ✅ bool 本质上是整型
double d = 1.5;
switch (d) { } // ❌ 编译报错,浮点型不允许
float f = 1.0f;
switch (f) { } // ❌ 编译报错
std::string s = "hello";
switch (s) { } // ❌ 编译报错,非整型
2、case 标签必须是整型常量表达式。
int x = 2;
switch (x) {
case 1: break; // ✅ 整数字面量
case 'a': break; // ✅ 字符常量,本质是 int(97)
case RED: break; // ✅ 枚举值,本质是 int
const int N = 3;
case N: break; // ✅ const 整型变量,编译期可知
constexpr int M = 4;
case M: break; // ✅ constexpr,编译期可知
int y = 5;
case y: break; // ❌ 编译报错,y 不是常量表达式
case 3.14: break; // ❌ 浮点常量
case "hello": break; // ❌ 字符串常量
int a = 1;
case a + 1: break; // ❌ a 不是常量
}
C++ Primer Plus 文章被收录于专栏
C++ Primer Plus 精读|从入门到面试,重点内容全程带看。 本专栏以《C++ Primer Plus》为蓝本,逐章提炼必考知识点、易错点、面试高频考点,跳过冗余示例,直击语法本质与工程实践,帮你高效吃透 C++ 基础,夯实底层开发必备能力。

查看21道真题和解析