文章目录
-
- [📋 本周学习地图](#📋 本周学习地图)
- [1️⃣ 分支:if / else](#1️⃣ 分支:if / else)
-
- [1.1 基本形式](#1.1 基本形式)
- [1.2 悬空 else(dangling else)陷阱](#1.2 悬空 else(dangling else)陷阱)
- [1.3 浮点比较陷阱](#1.3 浮点比较陷阱)
- [1.4 条件运算符 `?:`](#1.4 条件运算符
?:)
- [2️⃣ 分支:switch](#2️⃣ 分支:switch)
-
- [2.1 基本形式](#2.1 基本形式)
- [2.2 三大陷阱](#2.2 三大陷阱)
- [2.3 switch vs if/else 怎么选](#2.3 switch vs if/else 怎么选)
- [2.4 枚举 + switch(工程最佳实践)](#2.4 枚举 + switch(工程最佳实践))
- [3️⃣ 循环:for](#3️⃣ 循环:for)
-
- [3.1 经典三段式](#3.1 经典三段式)
- [3.2 经典陷阱:边界 off-by-one](#3.2 经典陷阱:边界 off-by-one)
- [3.3 `for` 的三大变体](#3.3
for的三大变体) - [3.4 循环变量的作用域(C++98 vs C++11)](#3.4 循环变量的作用域(C++98 vs C++11))
- [4️⃣ 循环:while / do-while](#4️⃣ 循环:while / do-while)
-
- [4.1 `while`:先判断,后执行](#4.1
while:先判断,后执行) - [4.2 `do-while`:先执行一次,后判断](#4.2
do-while:先执行一次,后判断) - [4.3 三者怎么选](#4.3 三者怎么选)
- [4.4 常见陷阱](#4.4 常见陷阱)
- [4.1 `while`:先判断,后执行](#4.1
- [5️⃣ 范围 for(C++11)](#5️⃣ 范围 for(C++11))
-
- [5.1 基本用法](#5.1 基本用法)
- [5.2 陷阱 1:遍历时修改容器](#5.2 陷阱 1:遍历时修改容器)
- [5.3 陷阱 2:`auto` 丢了引用](#5.3 陷阱 2:
auto丢了引用)
- [6️⃣ 跳转语句](#6️⃣ 跳转语句)
-
- [6.1 `break`:跳出**最近一层**循环/switch](#6.1
break:跳出最近一层循环/switch) - [6.2 `continue`:跳过本次,进入下一次](#6.2
continue:跳过本次,进入下一次) - [6.3 `return`:直接结束函数](#6.3
return:直接结束函数) - [6.4 `goto`:慎用(几乎所有场景都能被替代)](#6.4
goto:慎用(几乎所有场景都能被替代)) - [6.5 如何跳出多层循环](#6.5 如何跳出多层循环)
- [6.1 `break`:跳出**最近一层**循环/switch](#6.1
- [7️⃣ 现代 C++ 分支特性](#7️⃣ 现代 C++ 分支特性)
-
- [7.1 `if constexpr`(C++17):编译期分支](#7.1
if constexpr(C++17):编译期分支) - [7.2 `if consteval`(C++23):判断是否在编译期求值](#7.2
if consteval(C++23):判断是否在编译期求值) - [7.3 初始化语句(C++17):把变量限定在 if 内](#7.3 初始化语句(C++17):把变量限定在 if 内)
- [7.1 `if constexpr`(C++17):编译期分支](#7.1
- [8️⃣ 本周高频面试题(5 道)](#8️⃣ 本周高频面试题(5 道))
- [9️⃣ 本周项目验收:猜数字游戏](#9️⃣ 本周项目验收:猜数字游戏)
- [🔟 本周避坑速查表(贴墙版)](#🔟 本周避坑速查表(贴墙版))
📚 本文是「C++ 全栈开发 30 周课程」阶段一第 3 周的详细讲义。本周目标:掌握分支与循环,让程序真正"会思考",写出边界正确、逻辑清晰的控制流代码。
📋 本周学习地图
#mermaid-svg-8ueq5R8ysAwZJIeY{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8ueq5R8ysAwZJIeY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8ueq5R8ysAwZJIeY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8ueq5R8ysAwZJIeY .error-icon{fill:#552222;}#mermaid-svg-8ueq5R8ysAwZJIeY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8ueq5R8ysAwZJIeY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8ueq5R8ysAwZJIeY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8ueq5R8ysAwZJIeY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8ueq5R8ysAwZJIeY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8ueq5R8ysAwZJIeY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8ueq5R8ysAwZJIeY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8ueq5R8ysAwZJIeY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8ueq5R8ysAwZJIeY .marker.cross{stroke:#333333;}#mermaid-svg-8ueq5R8ysAwZJIeY svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8ueq5R8ysAwZJIeY p{margin:0;}#mermaid-svg-8ueq5R8ysAwZJIeY .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8ueq5R8ysAwZJIeY .cluster-label text{fill:#333;}#mermaid-svg-8ueq5R8ysAwZJIeY .cluster-label span{color:#333;}#mermaid-svg-8ueq5R8ysAwZJIeY .cluster-label span p{background-color:transparent;}#mermaid-svg-8ueq5R8ysAwZJIeY .label text,#mermaid-svg-8ueq5R8ysAwZJIeY span{fill:#333;color:#333;}#mermaid-svg-8ueq5R8ysAwZJIeY .node rect,#mermaid-svg-8ueq5R8ysAwZJIeY .node circle,#mermaid-svg-8ueq5R8ysAwZJIeY .node ellipse,#mermaid-svg-8ueq5R8ysAwZJIeY .node polygon,#mermaid-svg-8ueq5R8ysAwZJIeY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8ueq5R8ysAwZJIeY .rough-node .label text,#mermaid-svg-8ueq5R8ysAwZJIeY .node .label text,#mermaid-svg-8ueq5R8ysAwZJIeY .image-shape .label,#mermaid-svg-8ueq5R8ysAwZJIeY .icon-shape .label{text-anchor:middle;}#mermaid-svg-8ueq5R8ysAwZJIeY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8ueq5R8ysAwZJIeY .rough-node .label,#mermaid-svg-8ueq5R8ysAwZJIeY .node .label,#mermaid-svg-8ueq5R8ysAwZJIeY .image-shape .label,#mermaid-svg-8ueq5R8ysAwZJIeY .icon-shape .label{text-align:center;}#mermaid-svg-8ueq5R8ysAwZJIeY .node.clickable{cursor:pointer;}#mermaid-svg-8ueq5R8ysAwZJIeY .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8ueq5R8ysAwZJIeY .arrowheadPath{fill:#333333;}#mermaid-svg-8ueq5R8ysAwZJIeY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8ueq5R8ysAwZJIeY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8ueq5R8ysAwZJIeY .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8ueq5R8ysAwZJIeY .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8ueq5R8ysAwZJIeY .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8ueq5R8ysAwZJIeY .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8ueq5R8ysAwZJIeY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8ueq5R8ysAwZJIeY .cluster text{fill:#333;}#mermaid-svg-8ueq5R8ysAwZJIeY .cluster span{color:#333;}#mermaid-svg-8ueq5R8ysAwZJIeY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8ueq5R8ysAwZJIeY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8ueq5R8ysAwZJIeY rect.text{fill:none;stroke-width:0;}#mermaid-svg-8ueq5R8ysAwZJIeY .icon-shape,#mermaid-svg-8ueq5R8ysAwZJIeY .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8ueq5R8ysAwZJIeY .icon-shape p,#mermaid-svg-8ueq5R8ysAwZJIeY .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8ueq5R8ysAwZJIeY .icon-shape .label rect,#mermaid-svg-8ueq5R8ysAwZJIeY .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8ueq5R8ysAwZJIeY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8ueq5R8ysAwZJIeY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8ueq5R8ysAwZJIeY :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 第3周 · 控制流
- 分支:if/else
- 分支:switch
- 循环:for
- 循环:while / do-while
- 范围 for(C++11)
- 跳转:break/continue/return/goto
- 现代 C++ 分支特性
避坑:悬空 else / 浮点比较
避坑:忘 break / 作用域
避坑:边界 off-by-one
避坑:do-while 至少执行一次
避坑:遍历时修改容器
避坑:goto 破坏结构
if constexpr / if consteval
本周项目:猜数字游戏
1️⃣ 分支:if / else
1.1 基本形式
cpp
#include <iostream>
int main() {
int score = 85;
if (score >= 90) {
std::cout << "优秀\n";
} else if (score >= 60) {
std::cout << "及格\n";
} else {
std::cout << "不及格\n";
}
return 0;
}
#mermaid-svg-t0BnfM4Dd8i4UsaD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-t0BnfM4Dd8i4UsaD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-t0BnfM4Dd8i4UsaD .error-icon{fill:#552222;}#mermaid-svg-t0BnfM4Dd8i4UsaD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-t0BnfM4Dd8i4UsaD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-t0BnfM4Dd8i4UsaD .marker.cross{stroke:#333333;}#mermaid-svg-t0BnfM4Dd8i4UsaD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-t0BnfM4Dd8i4UsaD p{margin:0;}#mermaid-svg-t0BnfM4Dd8i4UsaD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-t0BnfM4Dd8i4UsaD .cluster-label text{fill:#333;}#mermaid-svg-t0BnfM4Dd8i4UsaD .cluster-label span{color:#333;}#mermaid-svg-t0BnfM4Dd8i4UsaD .cluster-label span p{background-color:transparent;}#mermaid-svg-t0BnfM4Dd8i4UsaD .label text,#mermaid-svg-t0BnfM4Dd8i4UsaD span{fill:#333;color:#333;}#mermaid-svg-t0BnfM4Dd8i4UsaD .node rect,#mermaid-svg-t0BnfM4Dd8i4UsaD .node circle,#mermaid-svg-t0BnfM4Dd8i4UsaD .node ellipse,#mermaid-svg-t0BnfM4Dd8i4UsaD .node polygon,#mermaid-svg-t0BnfM4Dd8i4UsaD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-t0BnfM4Dd8i4UsaD .rough-node .label text,#mermaid-svg-t0BnfM4Dd8i4UsaD .node .label text,#mermaid-svg-t0BnfM4Dd8i4UsaD .image-shape .label,#mermaid-svg-t0BnfM4Dd8i4UsaD .icon-shape .label{text-anchor:middle;}#mermaid-svg-t0BnfM4Dd8i4UsaD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-t0BnfM4Dd8i4UsaD .rough-node .label,#mermaid-svg-t0BnfM4Dd8i4UsaD .node .label,#mermaid-svg-t0BnfM4Dd8i4UsaD .image-shape .label,#mermaid-svg-t0BnfM4Dd8i4UsaD .icon-shape .label{text-align:center;}#mermaid-svg-t0BnfM4Dd8i4UsaD .node.clickable{cursor:pointer;}#mermaid-svg-t0BnfM4Dd8i4UsaD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-t0BnfM4Dd8i4UsaD .arrowheadPath{fill:#333333;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-t0BnfM4Dd8i4UsaD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-t0BnfM4Dd8i4UsaD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-t0BnfM4Dd8i4UsaD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-t0BnfM4Dd8i4UsaD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-t0BnfM4Dd8i4UsaD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-t0BnfM4Dd8i4UsaD .cluster text{fill:#333;}#mermaid-svg-t0BnfM4Dd8i4UsaD .cluster span{color:#333;}#mermaid-svg-t0BnfM4Dd8i4UsaD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-t0BnfM4Dd8i4UsaD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-t0BnfM4Dd8i4UsaD rect.text{fill:none;stroke-width:0;}#mermaid-svg-t0BnfM4Dd8i4UsaD .icon-shape,#mermaid-svg-t0BnfM4Dd8i4UsaD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-t0BnfM4Dd8i4UsaD .icon-shape p,#mermaid-svg-t0BnfM4Dd8i4UsaD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-t0BnfM4Dd8i4UsaD .icon-shape .label rect,#mermaid-svg-t0BnfM4Dd8i4UsaD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-t0BnfM4Dd8i4UsaD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-t0BnfM4Dd8i4UsaD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-t0BnfM4Dd8i4UsaD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
是
否
score >= 90 ?
优秀
score >= 60 ?
及格
不及格
1.2 悬空 else(dangling else)陷阱
cpp
int a = 1, b = 2;
// ❌ 你以为是:if (a > 0) { if (b > 0) ... } else ...
// 实际是:if (a > 0) { if (b > 0) ... else ... }
if (a > 0)
if (b > 0)
std::cout << "都大于0\n";
else
std::cout << "a <= 0\n"; // ← 这个 else 绑定的是内层 if!
// ✅ 用大括号消除歧义
if (a > 0) {
if (b > 0) {
std::cout << "都大于0\n";
}
} else {
std::cout << "a <= 0\n";
}
💡 工程规范 :if/else 永远加
{},即使只有一行。C++ Core Guidelines 明确推荐。
1.3 浮点比较陷阱
cpp
double x = 0.1 + 0.2;
// ❌ 几乎永远为假
if (x == 0.3) { /* ... */ }
// ✅ 用 epsilon 近似
#include <cmath>
if (std::fabs(x - 0.3) < 1e-9) { /* ... */ }
1.4 条件运算符 ?:
cpp
int a = 10, b = 20;
int max = (a > b) ? a : b; // 20
// 嵌套可读性差,避免超过两层
const char* level = (a > 90) ? "A" : (a > 60) ? "B" : "C";
2️⃣ 分支:switch
2.1 基本形式
cpp
#include <iostream>
int main() {
char op = '+';
int a = 3, b = 5;
switch (op) {
case '+': std::cout << a + b << "\n"; break;
case '-': std::cout << a - b << "\n"; break;
case '*': std::cout << a * b << "\n"; break;
case '/':
if (b != 0) std::cout << a / b << "\n";
else std::cout << "除零错误\n";
break;
default: std::cout << "未知运算符\n"; break;
}
}
#mermaid-svg-vMObEMHwTTjNMJaD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vMObEMHwTTjNMJaD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vMObEMHwTTjNMJaD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vMObEMHwTTjNMJaD .error-icon{fill:#552222;}#mermaid-svg-vMObEMHwTTjNMJaD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vMObEMHwTTjNMJaD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vMObEMHwTTjNMJaD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vMObEMHwTTjNMJaD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vMObEMHwTTjNMJaD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vMObEMHwTTjNMJaD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vMObEMHwTTjNMJaD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vMObEMHwTTjNMJaD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vMObEMHwTTjNMJaD .marker.cross{stroke:#333333;}#mermaid-svg-vMObEMHwTTjNMJaD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vMObEMHwTTjNMJaD p{margin:0;}#mermaid-svg-vMObEMHwTTjNMJaD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vMObEMHwTTjNMJaD .cluster-label text{fill:#333;}#mermaid-svg-vMObEMHwTTjNMJaD .cluster-label span{color:#333;}#mermaid-svg-vMObEMHwTTjNMJaD .cluster-label span p{background-color:transparent;}#mermaid-svg-vMObEMHwTTjNMJaD .label text,#mermaid-svg-vMObEMHwTTjNMJaD span{fill:#333;color:#333;}#mermaid-svg-vMObEMHwTTjNMJaD .node rect,#mermaid-svg-vMObEMHwTTjNMJaD .node circle,#mermaid-svg-vMObEMHwTTjNMJaD .node ellipse,#mermaid-svg-vMObEMHwTTjNMJaD .node polygon,#mermaid-svg-vMObEMHwTTjNMJaD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vMObEMHwTTjNMJaD .rough-node .label text,#mermaid-svg-vMObEMHwTTjNMJaD .node .label text,#mermaid-svg-vMObEMHwTTjNMJaD .image-shape .label,#mermaid-svg-vMObEMHwTTjNMJaD .icon-shape .label{text-anchor:middle;}#mermaid-svg-vMObEMHwTTjNMJaD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vMObEMHwTTjNMJaD .rough-node .label,#mermaid-svg-vMObEMHwTTjNMJaD .node .label,#mermaid-svg-vMObEMHwTTjNMJaD .image-shape .label,#mermaid-svg-vMObEMHwTTjNMJaD .icon-shape .label{text-align:center;}#mermaid-svg-vMObEMHwTTjNMJaD .node.clickable{cursor:pointer;}#mermaid-svg-vMObEMHwTTjNMJaD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vMObEMHwTTjNMJaD .arrowheadPath{fill:#333333;}#mermaid-svg-vMObEMHwTTjNMJaD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vMObEMHwTTjNMJaD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vMObEMHwTTjNMJaD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vMObEMHwTTjNMJaD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vMObEMHwTTjNMJaD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vMObEMHwTTjNMJaD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vMObEMHwTTjNMJaD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vMObEMHwTTjNMJaD .cluster text{fill:#333;}#mermaid-svg-vMObEMHwTTjNMJaD .cluster span{color:#333;}#mermaid-svg-vMObEMHwTTjNMJaD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vMObEMHwTTjNMJaD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vMObEMHwTTjNMJaD rect.text{fill:none;stroke-width:0;}#mermaid-svg-vMObEMHwTTjNMJaD .icon-shape,#mermaid-svg-vMObEMHwTTjNMJaD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vMObEMHwTTjNMJaD .icon-shape p,#mermaid-svg-vMObEMHwTTjNMJaD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vMObEMHwTTjNMJaD .icon-shape .label rect,#mermaid-svg-vMObEMHwTTjNMJaD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vMObEMHwTTjNMJaD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vMObEMHwTTjNMJaD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vMObEMHwTTjNMJaD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} switch(op)
case '+' → 执行 → break
case '-' → 执行 → break
case '*' → 执行 → break
case '/' → 执行 → break
default → 执行 → break
跳出 switch
2.2 三大陷阱
陷阱 1:忘写 break → 贯穿(fallthrough)
cpp
int x = 1;
switch (x) {
case 1: std::cout << "1\n"; // ⚠️ 没 break
case 2: std::cout << "2\n"; // 会继续执行!
case 3: std::cout << "3\n"; // 会继续执行!
}
// 输出:1 2 3
陷阱 2:case 里定义变量需要加 {}
cpp
switch (x) {
case 1: {
int tmp = 10; // ✅ 用 {} 限定作用域
std::cout << tmp;
break;
}
case 2: break;
}
陷阱 3:case 标签必须是整型常量表达式
cpp
// ❌ 编译错误
std::string s = "abc";
switch (s) { case "abc": ... } // switch 不支持 std::string
// ✅ 用 if/else 或 std::map
if (s == "abc") { ... }
2.3 switch vs if/else 怎么选
| 场景 | 推荐 |
|---|---|
| 判断整型/枚举的多个等值分支 | switch(清晰、编译器可优化为跳转表) |
判断范围 (如 score >= 90) |
if/else |
| 判断字符串 | if/else |
| 分支数 ≥ 3 且都是等值 | switch |
2.4 枚举 + switch(工程最佳实践)
cpp
enum class Color { Red, Green, Blue };
void printColor(Color c) {
switch (c) {
case Color::Red: std::cout << "红\n"; break;
case Color::Green: std::cout << "绿\n"; break;
case Color::Blue: std::cout << "蓝\n"; break;
}
// 不写 default,编译器 -Wswitch 会提醒你漏了哪个枚举值
}
💡 技巧 :对
enum class的switch不写default,让编译器帮你检查是否覆盖所有枚举值。
3️⃣ 循环:for
3.1 经典三段式
cpp
// 打印 1 ~ 5
for (int i = 1; i <= 5; ++i) {
std::cout << i << " ";
}
// 输出:1 2 3 4 5
#mermaid-svg-S4CCoCTZvD1ueiCZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-S4CCoCTZvD1ueiCZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-S4CCoCTZvD1ueiCZ .error-icon{fill:#552222;}#mermaid-svg-S4CCoCTZvD1ueiCZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-S4CCoCTZvD1ueiCZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-S4CCoCTZvD1ueiCZ .marker.cross{stroke:#333333;}#mermaid-svg-S4CCoCTZvD1ueiCZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-S4CCoCTZvD1ueiCZ p{margin:0;}#mermaid-svg-S4CCoCTZvD1ueiCZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-S4CCoCTZvD1ueiCZ .cluster-label text{fill:#333;}#mermaid-svg-S4CCoCTZvD1ueiCZ .cluster-label span{color:#333;}#mermaid-svg-S4CCoCTZvD1ueiCZ .cluster-label span p{background-color:transparent;}#mermaid-svg-S4CCoCTZvD1ueiCZ .label text,#mermaid-svg-S4CCoCTZvD1ueiCZ span{fill:#333;color:#333;}#mermaid-svg-S4CCoCTZvD1ueiCZ .node rect,#mermaid-svg-S4CCoCTZvD1ueiCZ .node circle,#mermaid-svg-S4CCoCTZvD1ueiCZ .node ellipse,#mermaid-svg-S4CCoCTZvD1ueiCZ .node polygon,#mermaid-svg-S4CCoCTZvD1ueiCZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-S4CCoCTZvD1ueiCZ .rough-node .label text,#mermaid-svg-S4CCoCTZvD1ueiCZ .node .label text,#mermaid-svg-S4CCoCTZvD1ueiCZ .image-shape .label,#mermaid-svg-S4CCoCTZvD1ueiCZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-S4CCoCTZvD1ueiCZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-S4CCoCTZvD1ueiCZ .rough-node .label,#mermaid-svg-S4CCoCTZvD1ueiCZ .node .label,#mermaid-svg-S4CCoCTZvD1ueiCZ .image-shape .label,#mermaid-svg-S4CCoCTZvD1ueiCZ .icon-shape .label{text-align:center;}#mermaid-svg-S4CCoCTZvD1ueiCZ .node.clickable{cursor:pointer;}#mermaid-svg-S4CCoCTZvD1ueiCZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-S4CCoCTZvD1ueiCZ .arrowheadPath{fill:#333333;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-S4CCoCTZvD1ueiCZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-S4CCoCTZvD1ueiCZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-S4CCoCTZvD1ueiCZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-S4CCoCTZvD1ueiCZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-S4CCoCTZvD1ueiCZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-S4CCoCTZvD1ueiCZ .cluster text{fill:#333;}#mermaid-svg-S4CCoCTZvD1ueiCZ .cluster span{color:#333;}#mermaid-svg-S4CCoCTZvD1ueiCZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-S4CCoCTZvD1ueiCZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-S4CCoCTZvD1ueiCZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-S4CCoCTZvD1ueiCZ .icon-shape,#mermaid-svg-S4CCoCTZvD1ueiCZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-S4CCoCTZvD1ueiCZ .icon-shape p,#mermaid-svg-S4CCoCTZvD1ueiCZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-S4CCoCTZvD1ueiCZ .icon-shape .label rect,#mermaid-svg-S4CCoCTZvD1ueiCZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-S4CCoCTZvD1ueiCZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-S4CCoCTZvD1ueiCZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-S4CCoCTZvD1ueiCZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
初始化 i=1
i <= 5 ?
循环体
++i
退出循环
3.2 经典陷阱:边界 off-by-one
cpp
int arr[5] = {1, 2, 3, 4, 5};
// ❌ 越界!i <= 5 会让 i 到 5,arr[5] 不存在
for (int i = 0; i <= 5; ++i) {
std::cout << arr[i];
}
// ✅ 正确:i < 5
for (int i = 0; i < 5; ++i) {
std::cout << arr[i];
}
💡 口诀 :数组下标用
<,从 0 开始;计数用<=,从 1 开始。写之前先问"最后一个有效值是多少"。
3.3 for 的三大变体
cpp
// ① 省略初始化
int i = 0;
for (; i < 3; ++i) { }
// ② 省略条件 → 死循环(等价于 while(true))
for (;;) { break; }
// ③ 逗号表达式初始化多个变量
for (int i = 0, j = 10; i < j; ++i, --j) {
std::cout << i << "," << j << "\n";
}
3.4 循环变量的作用域(C++98 vs C++11)
cpp
for (int i = 0; i < 3; ++i) { }
// std::cout << i; // ❌ C++11 起 i 只在循环内有效
int i; // 老代码习惯在外部声明
for (i = 0; i < 3; ++i) { }
std::cout << i; // ✅ 3,但现代 C++ 不推荐
4️⃣ 循环:while / do-while
4.1 while:先判断,后执行
cpp
int n = 5;
while (n > 0) {
std::cout << n << " ";
--n;
}
// 输出:5 4 3 2 1
4.2 do-while:先执行一次,后判断
cpp
int input;
do {
std::cout << "请输入 1~10:";
std::cin >> input;
} while (input < 1 || input > 10); // ⚠️ 末尾必须有分号!
#mermaid-svg-ou1fsihRV8nYEtzO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ou1fsihRV8nYEtzO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ou1fsihRV8nYEtzO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ou1fsihRV8nYEtzO .error-icon{fill:#552222;}#mermaid-svg-ou1fsihRV8nYEtzO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ou1fsihRV8nYEtzO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ou1fsihRV8nYEtzO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ou1fsihRV8nYEtzO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ou1fsihRV8nYEtzO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ou1fsihRV8nYEtzO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ou1fsihRV8nYEtzO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ou1fsihRV8nYEtzO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ou1fsihRV8nYEtzO .marker.cross{stroke:#333333;}#mermaid-svg-ou1fsihRV8nYEtzO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ou1fsihRV8nYEtzO p{margin:0;}#mermaid-svg-ou1fsihRV8nYEtzO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ou1fsihRV8nYEtzO .cluster-label text{fill:#333;}#mermaid-svg-ou1fsihRV8nYEtzO .cluster-label span{color:#333;}#mermaid-svg-ou1fsihRV8nYEtzO .cluster-label span p{background-color:transparent;}#mermaid-svg-ou1fsihRV8nYEtzO .label text,#mermaid-svg-ou1fsihRV8nYEtzO span{fill:#333;color:#333;}#mermaid-svg-ou1fsihRV8nYEtzO .node rect,#mermaid-svg-ou1fsihRV8nYEtzO .node circle,#mermaid-svg-ou1fsihRV8nYEtzO .node ellipse,#mermaid-svg-ou1fsihRV8nYEtzO .node polygon,#mermaid-svg-ou1fsihRV8nYEtzO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ou1fsihRV8nYEtzO .rough-node .label text,#mermaid-svg-ou1fsihRV8nYEtzO .node .label text,#mermaid-svg-ou1fsihRV8nYEtzO .image-shape .label,#mermaid-svg-ou1fsihRV8nYEtzO .icon-shape .label{text-anchor:middle;}#mermaid-svg-ou1fsihRV8nYEtzO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ou1fsihRV8nYEtzO .rough-node .label,#mermaid-svg-ou1fsihRV8nYEtzO .node .label,#mermaid-svg-ou1fsihRV8nYEtzO .image-shape .label,#mermaid-svg-ou1fsihRV8nYEtzO .icon-shape .label{text-align:center;}#mermaid-svg-ou1fsihRV8nYEtzO .node.clickable{cursor:pointer;}#mermaid-svg-ou1fsihRV8nYEtzO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ou1fsihRV8nYEtzO .arrowheadPath{fill:#333333;}#mermaid-svg-ou1fsihRV8nYEtzO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ou1fsihRV8nYEtzO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ou1fsihRV8nYEtzO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ou1fsihRV8nYEtzO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ou1fsihRV8nYEtzO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ou1fsihRV8nYEtzO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ou1fsihRV8nYEtzO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ou1fsihRV8nYEtzO .cluster text{fill:#333;}#mermaid-svg-ou1fsihRV8nYEtzO .cluster span{color:#333;}#mermaid-svg-ou1fsihRV8nYEtzO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ou1fsihRV8nYEtzO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ou1fsihRV8nYEtzO rect.text{fill:none;stroke-width:0;}#mermaid-svg-ou1fsihRV8nYEtzO .icon-shape,#mermaid-svg-ou1fsihRV8nYEtzO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ou1fsihRV8nYEtzO .icon-shape p,#mermaid-svg-ou1fsihRV8nYEtzO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ou1fsihRV8nYEtzO .icon-shape .label rect,#mermaid-svg-ou1fsihRV8nYEtzO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ou1fsihRV8nYEtzO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ou1fsihRV8nYEtzO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ou1fsihRV8nYEtzO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} do-while (条件)
真
假
执行循环体
判断条件
退出
while (条件)
真
假
判断条件
执行循环体
退出
4.3 三者怎么选
| 循环 | 特点 | 适用场景 |
|---|---|---|
for |
次数已知 | 遍历数组、固定次数 |
while |
次数未知,可能 0 次 | 读文件、等待条件 |
do-while |
至少执行 1 次 | 菜单、输入校验 |
4.4 常见陷阱
cpp
// ❌ 忘记更新条件变量 → 死循环
int i = 0;
while (i < 5) {
std::cout << i; // 忘了 ++i
}
// ❌ 无符号数倒序循环 → 死循环
for (unsigned int i = 5; i >= 0; --i) { } // i 永远不会 < 0
// ✅ 正确写法
for (int i = 5; i >= 0; --i) { }
5️⃣ 范围 for(C++11)
5.1 基本用法
cpp
#include <vector>
#include <string>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// 只读遍历(零拷贝,推荐默认)
for (const auto& x : v) {
std::cout << x << " ";
}
// 修改元素
for (auto& x : v) {
x *= 2;
}
// 遍历字符串
std::string s = "C++";
for (char c : s) {
std::cout << c << "\n";
}
}
5.2 陷阱 1:遍历时修改容器
cpp
std::vector<int> v = {1, 2, 3};
// ❌ 未定义行为:迭代器失效
for (auto x : v) {
if (x == 2) v.push_back(4);
}
// ✅ 用索引 + 记录原始大小,或先收集再修改
size_t n = v.size();
for (size_t i = 0; i < n; ++i) {
if (v[i] == 2) v.push_back(4);
}
5.3 陷阱 2:auto 丢了引用
cpp
std::vector<std::string> names = {"Alice", "Bob"};
for (auto name : names) { // ❌ 拷贝每个 string
name += "!";
}
std::cout << names[0]; // Alice(没变)
for (auto& name : names) { // ✅ 零拷贝 + 可修改
name += "!";
}
💡 口诀 :只读用
const auto&,要改用auto&,小对象(int)才用auto。
6️⃣ 跳转语句
6.1 break:跳出最近一层循环/switch
cpp
for (int i = 0; i < 10; ++i) {
if (i == 3) break;
std::cout << i << " "; // 输出:0 1 2
}
6.2 continue:跳过本次,进入下一次
cpp
for (int i = 0; i < 10; ++i) {
if (i % 2 == 0) continue;
std::cout << i << " "; // 输出:1 3 5 7 9
}
6.3 return:直接结束函数
cpp
int findIndex(const std::vector<int>& v, int target) {
for (size_t i = 0; i < v.size(); ++i) {
if (v[i] == target) return (int)i; // 找到立即返回
}
return -1;
}
6.4 goto:慎用(几乎所有场景都能被替代)
cpp
// ❌ 破坏结构化编程,跳转关系难追踪
int i = 0;
loop:
std::cout << i++;
if (i < 3) goto loop;
// ✅ 用循环替代
for (int i = 0; i < 3; ++i) {
std::cout << i;
}
💡 唯一合理场景 :多层嵌套循环中一次性跳出。但更推荐封装成函数 +
return。
6.5 如何跳出多层循环
cpp
// 方法 1:标志位
bool found = false;
for (int i = 0; i < 10 && !found; ++i) {
for (int j = 0; j < 10; ++j) {
if (matrix[i][j] == target) {
found = true;
break;
}
}
}
// 方法 2:封装函数(推荐)
bool findInMatrix(...) {
for (...) for (...) {
if (...) return true;
}
return false;
}
7️⃣ 现代 C++ 分支特性
7.1 if constexpr(C++17):编译期分支
cpp
#include <type_traits>
template <typename T>
std::string typeName(T) {
if constexpr (std::is_integral_v<T>) {
return "整型";
} else if constexpr (std::is_floating_point_v<T>) {
return "浮点";
} else {
return "其他";
}
}
int main() {
std::cout << typeName(42) << "\n"; // 整型
std::cout << typeName(3.14) << "\n"; // 浮点
}
💡
if constexpr的未选中分支不会被实例化 ,这是它和普通if的本质区别。
7.2 if consteval(C++23):判断是否在编译期求值
cpp
constexpr int f(int n) {
if consteval {
return n * 2; // 编译期执行的逻辑
} else {
return n * 3; // 运行期执行的逻辑
}
}
替代了 C++20 的
if (std::is_constant_evaluated()),语法更简洁。
7.3 初始化语句(C++17):把变量限定在 if 内
cpp
// 传统写法:map 查找要写两次
auto it = m.find(key);
if (it != m.end()) { use(it->second); }
// C++17:变量作用域限定在 if/else 内
if (auto it = m.find(key); it != m.end()) {
use(it->second);
}
8️⃣ 本周高频面试题(5 道)
| # | 题目 | 考察点 | 参考答案要点 |
|---|---|---|---|
| 1 | switch 忘写 break 会发生什么? |
fallthrough | 继续执行下一个 case,直到遇到 break 或 switch 结束;可用 [[fallthrough]] 显式标注意图 |
| 2 | while 和 do-while 的区别? |
执行次数 | while 可能 0 次;do-while 至少 1 次;do-while 末尾必须加分号 |
| 3 | 如何跳出多层嵌套循环? | 控制流 | 标志位 / 封装函数 + return / goto(不推荐) |
| 4 | 范围 for 遍历时能修改容器吗? | 迭代器失效 | 不能 push_back/erase,会 UB;先收集再修改,或用索引 |
| 5 | if constexpr 和普通 if 的区别? |
编译期 | 前者未选中分支不实例化,可用于模板;后者两个分支都会编译 |
9️⃣ 本周项目验收:猜数字游戏
需求:程序随机生成 1~100 的数字,玩家循环猜,每次提示"大了/小了",猜对后显示次数并询问是否再来一局。
验收标准:
- 用
do-while实现"再来一局"的循环 - 用
while或for实现猜数循环 - 用
if/else给出提示 - 输入非法(如非数字)时用
continue跳过本次 - 用
break在猜对时退出内层循环 - 所有
if/else都带{}
参考骨架:
cpp
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(1, 100);
char again;
do {
int target = dist(gen);
int guess = 0;
int tries = 0;
std::cout << "猜一个 1~100 的数字:\n";
while (true) {
std::cout << "第 " << ++tries << " 次:";
if (!(std::cin >> guess)) {
std::cin.clear();
std::cin.ignore(10000, '\n');
std::cout << "输入无效,请重新输入\n";
--tries;
continue;
}
if (guess == target) {
std::cout << "猜对了!共 " << tries << " 次\n";
break;
} else if (guess < target) {
std::cout << "小了\n";
} else {
std::cout << "大了\n";
}
}
std::cout << "再来一局?(y/n):";
std::cin >> again;
} while (again == 'y' || again == 'Y');
return 0;
}
🔟 本周避坑速查表(贴墙版)
#mermaid-svg-FSVfgQTcqIHqnIzJ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FSVfgQTcqIHqnIzJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FSVfgQTcqIHqnIzJ .error-icon{fill:#552222;}#mermaid-svg-FSVfgQTcqIHqnIzJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FSVfgQTcqIHqnIzJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FSVfgQTcqIHqnIzJ .marker.cross{stroke:#333333;}#mermaid-svg-FSVfgQTcqIHqnIzJ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FSVfgQTcqIHqnIzJ p{margin:0;}#mermaid-svg-FSVfgQTcqIHqnIzJ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FSVfgQTcqIHqnIzJ .cluster-label text{fill:#333;}#mermaid-svg-FSVfgQTcqIHqnIzJ .cluster-label span{color:#333;}#mermaid-svg-FSVfgQTcqIHqnIzJ .cluster-label span p{background-color:transparent;}#mermaid-svg-FSVfgQTcqIHqnIzJ .label text,#mermaid-svg-FSVfgQTcqIHqnIzJ span{fill:#333;color:#333;}#mermaid-svg-FSVfgQTcqIHqnIzJ .node rect,#mermaid-svg-FSVfgQTcqIHqnIzJ .node circle,#mermaid-svg-FSVfgQTcqIHqnIzJ .node ellipse,#mermaid-svg-FSVfgQTcqIHqnIzJ .node polygon,#mermaid-svg-FSVfgQTcqIHqnIzJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FSVfgQTcqIHqnIzJ .rough-node .label text,#mermaid-svg-FSVfgQTcqIHqnIzJ .node .label text,#mermaid-svg-FSVfgQTcqIHqnIzJ .image-shape .label,#mermaid-svg-FSVfgQTcqIHqnIzJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-FSVfgQTcqIHqnIzJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FSVfgQTcqIHqnIzJ .rough-node .label,#mermaid-svg-FSVfgQTcqIHqnIzJ .node .label,#mermaid-svg-FSVfgQTcqIHqnIzJ .image-shape .label,#mermaid-svg-FSVfgQTcqIHqnIzJ .icon-shape .label{text-align:center;}#mermaid-svg-FSVfgQTcqIHqnIzJ .node.clickable{cursor:pointer;}#mermaid-svg-FSVfgQTcqIHqnIzJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FSVfgQTcqIHqnIzJ .arrowheadPath{fill:#333333;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FSVfgQTcqIHqnIzJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FSVfgQTcqIHqnIzJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FSVfgQTcqIHqnIzJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FSVfgQTcqIHqnIzJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FSVfgQTcqIHqnIzJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FSVfgQTcqIHqnIzJ .cluster text{fill:#333;}#mermaid-svg-FSVfgQTcqIHqnIzJ .cluster span{color:#333;}#mermaid-svg-FSVfgQTcqIHqnIzJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FSVfgQTcqIHqnIzJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FSVfgQTcqIHqnIzJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-FSVfgQTcqIHqnIzJ .icon-shape,#mermaid-svg-FSVfgQTcqIHqnIzJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FSVfgQTcqIHqnIzJ .icon-shape p,#mermaid-svg-FSVfgQTcqIHqnIzJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FSVfgQTcqIHqnIzJ .icon-shape .label rect,#mermaid-svg-FSVfgQTcqIHqnIzJ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FSVfgQTcqIHqnIzJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FSVfgQTcqIHqnIzJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FSVfgQTcqIHqnIzJ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 第3周避坑清单
分支
循环
跳转
范围 for
if/else 永远加 {}
浮点不用 ==
数组下标 < n
无符号别倒序
break 只跳一层
多层用函数 return
遍历中不改容器
大对象用 const auto&
🎯 一句话总结 :分支加括号、循环查边界、浮点不比等、break 只跳一层、遍历不动容器、goto 能不用就不用。 掌握这六条,第 3 周的控制流就算真正过关了。