====== 第三章 控制结构 ======
本章将详细介绍C++中的控制结构,包括条件语句、循环语句、跳转语句和switch语句,这些是控制程序流程的基本工具。
===== 3.1 条件语句 =====
=== 3.1.1 if语句 ===
if语句是C++中最基本的条件控制结构。
#include
using namespace std;
int main() {
int score = 85;
// 简单if语句
if (score >= 60) {
cout << "Passed" << endl;
}
// if-else语句
if (score >= 60) {
cout << "Passed" << endl;
} else {
cout << "Failed" << endl;
}
// if-else if-else链
if (score >= 90) {
cout << "Grade: A" << endl;
} else if (score >= 80) {
cout << "Grade: B" << endl;
} else if (score >= 70) {
cout << "Grade: C" << endl;
} else if (score >= 60) {
cout << "Grade: D" << endl;
} else {
cout << "Grade: F" << endl;
}
return 0;
}
=== 3.1.2 嵌套if语句 ===
#include
using namespace std;
int main() {
int age = 25;
bool hasLicense = true;
// 嵌套if
if (age >= 18) {
if (hasLicense) {
cout << "You can drive" << endl;
} else {
cout << "You need a license" << endl;
}
} else {
cout << "You are too young to drive" << endl;
}
// 使用逻辑运算符简化
if (age >= 18 && hasLicense) {
cout << "You can drive" << endl;
}
// 悬空else问题
int x = 5, y = 10;
if (x > 0)
if (y > 0)
cout << "Both positive" << endl;
else // 这个else匹配内层的if
cout << "y not positive" << endl;
// 使用花括号避免歧义
if (x > 0) {
if (y > 0) {
cout << "Both positive" << endl;
}
} else {
cout << "x not positive" << endl;
}
return 0;
}
=== 3.1.3 if语句的注意事项 ===
#include
using namespace std;
int main() {
int* ptr = nullptr;
// 常见错误:赋值而不是比较
int x = 5;
if (x = 10) { // 警告:赋值操作,x变为10,条件为真
cout << "This will always print" << endl;
}
// 安全做法:常量在前
if (10 == x) { // 如果写成 = 会编译错误
cout << "x is 10" << endl;
}
// 检查空指针
if (ptr) { // 等价于 ptr != nullptr
cout << "Pointer is valid" << endl;
}
// C++17 if with initializer
if (int value = someFunction(); value > 0) {
cout << "Positive: " << value << endl;
} // value在这里超出作用域
return 0;
}
===== 3.2 switch语句 =====
=== 3.2.1 基本语法 ===
#include
using namespace std;
int main() {
int day = 3;
switch (day) {
case 1:
cout << "Monday" << endl;
break;
case 2:
cout << "Tuesday" << endl;
break;
case 3:
cout << "Wednesday" << endl;
break;
case 4:
cout << "Thursday" << endl;
break;
case 5:
cout << "Friday" << endl;
break;
case 6:
case 7:
cout << "Weekend" << endl;
break;
default:
cout << "Invalid day" << endl;
break;
}
return 0;
}
=== 3.2.2 switch的注意事项 ===
#include
using namespace std;
int main() {
// switch表达式必须是整数类型
// char、short、int、long、enum都可以
char grade = 'B';
switch (grade) {
case 'A':
cout << "Excellent" << endl;
break;
case 'B':
cout << "Good" << endl;
// 注意:这里没有break,会fall-through到case 'C'
case 'C':
cout << "Average" << endl;
break;
case 'D':
cout << "Poor" << endl;
break;
case 'F':
cout << "Fail" << endl;
break;
default:
cout << "Invalid grade" << endl;
}
// C++17 [[fallthrough]] 属性
int x = 1;
switch (x) {
case 1:
cout << "One" << endl;
[[fallthrough]]; // 明确表示故意fall-through
case 2:
cout << "Two" << endl;
break;
}
// 不能使用字符串
// string name = "hello";
// switch (name) { } // 错误!
return 0;
}
=== 3.2.3 枚举与switch ===
#include
using namespace std;
enum class Color {
Red,
Green,
Blue
};
enum Direction {
North,
South,
East,
West
};
int main() {
Direction dir = East;
switch (dir) {
case North:
cout << "Going North" << endl;
break;
case South:
cout << "Going South" << endl;
break;
case East:
cout << "Going East" << endl;
break;
case West:
cout << "Going West" << endl;
break;
}
// C++11强类型枚举
Color c = Color::Red;
switch (c) {
case Color::Red:
cout << "Red" << endl;
break;
case Color::Green:
cout << "Green" << endl;
break;
case Color::Blue:
cout << "Blue" << endl;
break;
}
return 0;
}
===== 3.3 循环语句 =====
=== 3.3.1 while循环 ===
#include
using namespace std;
int main() {
// 基本while循环
int count = 0;
while (count < 5) {
cout << "Count: " << count << endl;
count++;
}
// 读取输入直到遇到特定值
int number;
cout << "Enter numbers (0 to stop): " << endl;
while (cin >> number && number != 0) {
cout << "You entered: " << number << endl;
}
// 无限循环(需要break)
int sum = 0;
int n;
while (true) {
cout << "Enter a number (-1 to stop): ";
cin >> n;
if (n == -1) break;
sum += n;
}
cout << "Sum: " << sum << endl;
// do-while循环(至少执行一次)
int choice;
do {
cout << "\nMenu:" << endl;
cout << "1. Option 1" << endl;
cout << "2. Option 2" << endl;
cout << "3. Exit" << endl;
cout << "Enter choice: ";
cin >> choice;
switch (choice) {
case 1: cout << "Option 1 selected" << endl; break;
case 2: cout << "Option 2 selected" << endl; break;
case 3: cout << "Goodbye" << endl; break;
default: cout << "Invalid choice" << endl;
}
} while (choice != 3);
return 0;
}
=== 3.3.2 for循环 ===
#include
using namespace std;
int main() {
// 基本for循环
for (int i = 0; i < 5; i++) {
cout << "i = " << i << endl;
}
// 多种变体
// 1. 省略初始化
int j = 0;
for (; j < 5; j++) {
cout << "j = " << j << endl;
}
// 2. 省略条件(无限循环)
for (int k = 0; ; k++) {
if (k >= 5) break;
cout << "k = " << k << endl;
}
// 3. 省略更新
for (int m = 0; m < 5; ) {
cout << "m = " << m << endl;
m++;
}
// 4. 多重初始化(C++允许)
for (int a = 0, b = 10; a < b; a++, b--) {
cout << "a = " << a << ", b = " << b << endl;
}
// 5. 范围for循环(C++11)
int arr[] = {1, 2, 3, 4, 5};
for (int x : arr) {
cout << x << " ";
}
cout << endl;
// 使用引用修改元素
for (int& x : arr) {
x *= 2;
}
// 使用auto(C++11)
for (auto x : arr) {
cout << x << " ";
}
cout << endl;
return 0;
}
=== 3.3.3 嵌套循环 ===
#include
#include
using namespace std;
int main() {
// 打印乘法表
cout << "Multiplication Table:" << endl;
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
cout << j << "x" << i << "=" << setw(2) << i * j << " ";
}
cout << endl;
}
// 打印金字塔
int rows = 5;
for (int i = 1; i <= rows; i++) {
// 打印空格
for (int j = 1; j <= rows - i; j++) {
cout << " ";
}
// 打印星号
for (int k = 1; k <= 2 * i - 1; k++) {
cout << "*";
}
cout << endl;
}
// 使用break跳出内层循环
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (i * j > 20) {
break; // 只跳出内层循环
}
cout << i * j << " ";
}
cout << endl;
}
return 0;
}
===== 3.4 跳转语句 =====
=== 3.4.1 break语句 ===
#include
using namespace std;
int main() {
// 在switch中使用
int choice = 2;
switch (choice) {
case 1:
cout << "One" << endl;
break;
case 2:
cout << "Two" << endl;
break; // 跳出switch
case 3:
cout << "Three" << endl;
break;
}
// 在循环中使用
for (int i = 0; i < 100; i++) {
if (i == 10) {
break; // 跳出循环
}
cout << i << " ";
}
cout << endl;
// 查找第一个能被7和13整除的数
int num = 1;
while (true) {
if (num % 7 == 0 && num % 13 == 0) {
cout << "Found: " << num << endl; // 91
break;
}
num++;
}
return 0;
}
=== 3.4.2 continue语句 ===
#include
using namespace std;
int main() {
// 跳过偶数
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue; // 跳过本次循环剩余部分
}
cout << i << " "; // 只打印奇数
}
cout << endl;
// 只处理正数
int numbers[] = {1, -2, 3, -4, 5, -6, 7};
int sum = 0;
for (int num : numbers) {
if (num < 0) {
continue; // 跳过负数
}
sum += num;
}
cout << "Sum of positives: " << sum << endl; // 16
// 在while中使用continue要小心
int x = 0;
while (x < 10) {
x++; // 先递增!
if (x % 3 == 0) {
continue;
}
cout << x << " ";
}
cout << endl;
return 0;
}
=== 3.4.3 goto语句 ===
#include
using namespace std;
int main() {
// goto语句(尽量避免使用)
int i = 0;
loop_start:
if (i >= 5) {
goto loop_end;
}
cout << "i = " << i << endl;
i++;
goto loop_start;
loop_end:
cout << "Loop finished" << endl;
// goto的一个合理使用场景:跳出多层循环
for (int a = 0; a < 10; a++) {
for (int b = 0; b < 10; b++) {
for (int c = 0; c < 10; c++) {
if (a * b * c == 27) {
cout << "Found: a=" << a << ", b=" << b << ", c=" << c << endl;
goto found; // 跳出所有循环
}
}
}
}
found:
cout << "Search complete" << endl;
// 更好的替代:使用函数和return
// 或使用标志变量
bool found2 = false;
for (int a = 0; a < 10 && !found2; a++) {
for (int b = 0; b < 10 && !found2; b++) {
for (int c = 0; c < 10; c++) {
if (a * b * c == 27) {
cout << "Found: " << a << ", " << b << ", " << c << endl;
found2 = true;
break;
}
}
}
}
return 0;
}
=== 3.4.4 return语句 ===
#include
using namespace std;
// 从函数返回值
int max(int a, int b) {
if (a > b) {
return a; // 提前返回
}
return b;
}
// void函数中的return
void printPositive(int n) {
if (n <= 0) {
cout << "Not positive" << endl;
return; // 提前结束函数
}
cout << "Positive: " << n << endl;
}
// main函数中的return
int main() {
cout << max(10, 20) << endl;
printPositive(5);
printPositive(-3);
// return 0表示程序成功结束
return 0;
// 或者省略,C++会自动return 0
}
===== 3.5 C++17新特性 =====
=== 3.5.1 if和switch的初始化语句 ===
#include
#include
===== 3.6 最佳实践 =====
=== 3.6.1 代码风格建议 ===
#include
using namespace std;
int main() {
// 1. 总是使用花括号,即使只有一条语句
if (true) {
cout << "Good practice" << endl;
}
// 避免这样:
// if (true)
// cout << "Risky" << endl;
// cout << "This always executes!" << endl; // 不是if的一部分
// 2. 避免深层嵌套,使用提前返回
int value = 10;
// 不好的写法
if (value > 0) {
if (value < 100) {
if (value % 2 == 0) {
cout << "Valid even number" << endl;
}
}
}
// 好的写法
if (value <= 0) {
cout << "Not positive" << endl;
} else if (value >= 100) {
cout << "Too large" << endl;
} else if (value % 2 != 0) {
cout << "Not even" << endl;
} else {
cout << "Valid even number" << endl;
}
// 或者使用guard clause
if (value <= 0 || value >= 100) {
cout << "Out of range" << endl;
} else if (value % 2 != 0) {
cout << "Not even" << endl;
} else {
cout << "Valid even number" << endl;
}
// 3. switch中使用枚举代替整数
enum class Operation { Add, Subtract, Multiply, Divide };
Operation op = Operation::Add;
switch (op) {
case Operation::Add: /* ... */ break;
case Operation::Subtract: /* ... */ break;
case Operation::Multiply: /* ... */ break;
case Operation::Divide: /* ... */ break;
}
// 4. 范围for循环优先
int arr[] = {1, 2, 3, 4, 5};
// 推荐
for (int x : arr) {
cout << x << " ";
}
// 不推荐
for (int i = 0; i < 5; i++) {
cout << arr[i] << " ";
}
return 0;
}
===== 3.7 本章小结 =====
本章我们学习了:
* if语句的各种形式:简单if、if-else、if-else if链
* switch语句的用法和注意事项(break、fall-through)
* 三种循环:while、do-while、for
* 范围for循环(C++11)
* 跳转语句:break、continue、goto、return
* C++17的if/switch初始化语句
* 控制结构的最佳实践
===== 练习题 =====
**基础练习:**
1. 编写程序判断一个年份是否是闰年。闰年条件:
- 能被4整除但不能被100整除,或
- 能被400整除
2. 使用switch语句实现简单计算器,支持+、-、*、/运算
3. 编写程序打印斐波那契数列的前n项(使用循环)
4. 编写程序判断一个数是否是质数
**进阶练习:**
5. 实现数字猜测游戏:
- 程序随机生成1-100的数字
- 用户猜测,程序提示"太大"或"太小"
- 记录猜测次数
- 允许用户选择是否继续游戏
6. 打印菱形图案,用户可以输入行数
7. 编写程序找出1-1000之间的所有完数(等于其因子之和的数)
**思考题:**
8. 分析以下代码的输出:
int i = 0;
while (i++ < 5) {
cout << i << " ";
}
9. 比较for、while、do-while的适用场景,各举一例
10. 研究C++20的ranges库如何改变循环的写法
===== 参考答案 =====
**练习1参考:**
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
**练习4参考:**
bool isPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
**练习6参考:**
#include
using namespace std;
int main() {
int n;
cout << "Enter number of rows (odd): ";
cin >> n;
int half = n / 2;
// 上半部分
for (int i = 0; i <= half; i++) {
for (int j = 0; j < half - i; j++) cout << " ";
for (int j = 0; j < 2 * i + 1; j++) cout << "*";
cout << endl;
}
// 下半部分
for (int i = half - 1; i >= 0; i--) {
for (int j = 0; j < half - i; j++) cout << " ";
for (int j = 0; j < 2 * i + 1; j++) cout << "*";
cout << endl;
}
return 0;
}
===== 下一章 =====
继续学习:[[第四章_函数|第四章 函数]]