顺序结构程序设计
简单8顺序结构程序设计:像做菜一样,一步一步来
程序就像我们在厨房里做一道菜:先洗菜、切菜,再开火、放油,最后下锅翻炒。每一步都有固定的顺序,不能颠倒,否则可能会做出黑暗料理。在C++里,顺序结构就是让代码从上往下一条一条地执行,就像按顺序完成菜谱上的步骤一样。
什么是顺序结构?
顺序结构是编程中最简单、最基础的控制结构。它没有分叉、没有循环,只是一行一行地往下走。你可以想象成在排队买冰淇淋:先付钱,再拿到券,然后去窗口取冰淇淋。如果顺序搞反了,可能两手空空。C++程序默认就是顺序执行的,除非你用了if、while等改变流程的语句。
为什么顺序很重要?
因为计算机很“死板”,它只会老老实实地按代码的顺序执行。如果顺序错了,结果就会完全不一样。比如下面这个例子:
#include <iostream>
using namespace std;
int main() {
int a = 3; // 定义变量a,赋值为3
int b = 5; // 定义变量b,赋值为5
int sum = a + b; // 计算a+b,结果存入sum
cout << "两个数的和是:" << sum << endl; // 输出sum
return 0;
}
这段代码先定义a和b,再计算和,最后输出。如果我把第三行和第四行的顺序交换:
int a = 3;
cout << "两个数的和是:" << sum << endl; // 此时sum还没有定义,会报错!
int sum = a + b;
计算机就会报错,因为它在用到sum时还没定义。即使先定义sum但不赋值,输出也会是一个随机的垃圾值。就像你还没给手机充电就想开机,结果当然不对劲。
顺序结构中的常见操作
顺序结构通常包含三类操作:
- 输入:从键盘读取数据(比如用
cin) - 处理:进行计算或逻辑操作(比如加减乘除、字符串拼接)
- 输出:把结果显示出来(比如用
cout)
一个典型的“输入-处理-输出”程序是这样的:
#include <iostream>
using namespace std;
int main() {
int num1, num2; // 定义两个整数变量
cout << "请输入两个整数:";
cin >> num1 >> num2; // 从键盘读入两个数
int product = num1 * num2; // 计算乘积
cout << "它们的乘积是:" << product << endl; // 输出结果
return 0;
}
这个程序先让用户输入,再计算,最后输出。如果先把计算结果放在输入之前,就会出错。
生活中顺序结构的例子
顺序结构在生活中无处不在:
- 数学考试:先读题,再列式,最后计算答案。
- 吃早餐:先盛粥,再夹菜,最后喝粥。如果先喝粥再盛粥,桌子就脏了。
- 玩游戏:先打开游戏,再选择角色,最后开始战斗。如果跳过前面的步骤,游戏可能无法正常启动。
新手容易犯的错误
-
变量使用前未定义或未赋值
比如下面的代码会输出一个随机数(甚至编译错误):int x; cout << x; // x没赋值,输出不确定 -
顺序颠倒导致逻辑错误
想要交换两个变量的值,必须用第三个变量暂存,顺序很重要:int a = 5, b = 3, temp; // temp是临时变量 temp = a; // temp = 5 a = b; // a = 3 b = temp; // b = 5如果写成
a = b; b = a;,结果就会变成a=3,b=3,因为第一个赋值把a原来的值覆盖了。 -
忘记换行导致输出挤在一起
cout默认不会自动换行,需要用endl或\n。cout << "第一行"; // 不带换行 cout << "第二行"; // 输出结果:第一行第二行
完整可运行的示例:计算圆的面积和周长
下面是一个用顺序结构解决问题的完整程序:
#include <iostream>
using namespace std;
int main() {
double radius; // 半径
const double PI = 3.14159; // 常量PI
cout << "请输入圆的半径:";
cin >> radius; // 输入半径
double area = PI * radius * radius; // 计算面积
double perimeter = 2 * PI * radius; // 计算周长
cout << "圆的面积是:" << area << endl;
cout << "圆的周长是:" << perimeter << endl;
return 0;
}
这个程序严格按照“输入→计算→输出”的顺序执行,每一步都不能调换。
相关指引
- 如果你想给程序增加判断能力(比如根据考试分数输出不同评语),可以学习 if-else分支语句
- 如果想让程序重复执行某一件事(比如计算全班同学的平均分),可以学习 for循环 或 while循环
- 顺序结构是所有程序的基础,掌握好它,再学习其他结构就会轻松很多。
if-else分支语句:让电脑学会“做选择”
生活中我们经常要做选择:如果今天下雨,就带伞;否则就不带。如果这次考试及格了,就奖励自己一个冰淇淋;否则就继续努力。C++中的 if-else 语句正好帮我们实现这种“二选一”的判断逻辑。
if-else 的基本结构
想象你在一个十字路口,面前有两个方向:左边是“条件为真”的路,右边是“条件为假”的路。if-else 就是那个路牌,它告诉你走哪条路。
if (条件) {
// 条件成立时执行的代码
} else {
// 条件不成立时执行的代码
}
流程:先判断括号里的条件是否成立(true),如果成立就执行大括号里的代码;否则执行 else 后面的代码。
生活中的例子:判断成绩是否及格
小明这次考了85分,老师说不低于60分就算及格。我们可以用程序来模拟:
#include <iostream>
using namespace std;
int main() {
int score = 85; // 小明的分数
if (score >= 60) {
cout << "恭喜你,及格了!" << endl;
} else {
cout << "继续努力,下次一定行!" << endl;
}
return 0;
}
因为85≥60,所以计算机执行第一个分支,输出“恭喜你”。如果分数是45,就会输出“继续努力”。
只有 if 没有 else 的情况
有时候我们只需要在条件成立时做一件事,不成立时什么都不做。那就不用写 else:
if (score >= 60) {
cout << "及格了!" << endl;
}
// 如果不及格,这里什么也不输出
多个条件:else if
如果判断不止两个分支,比如考试成绩分三档:
- 90分以上:优秀
- 60~89分:及格
- 60分以下:不及格
我们可以用 else if 连接多个条件:
#include <iostream>
using namespace std;
int main() {
int score = 85;
if (score >= 90) {
cout << "优秀!" << endl;
} else if (score >= 60) {
cout << "及格!" << endl;
} else {
cout << "不及格!" << endl;
}
return 0;
}
注意:条件检查是从上往下依次判断的。一旦某个条件成立,就会执行对应的代码块,然后跳过后面的所有 else if 和 else。所以上面的例子中,85分虽然满足 score>=60,但不会执行“优秀”,因为先判断了 score>=90 不成立。
嵌套的 if-else
if-else 里面可以再放一个 if-else,这叫嵌套。比如我们要判断一个数是正数、负数还是零:
#include <iostream>
using namespace std;
int main() {
int num;
cout << "请输入一个整数:";
cin >> num;
if (num > 0) {
cout << "正数" << endl;
} else {
// num <= 0 的情况
if (num < 0) {
cout << "负数" << endl;
} else {
cout << "零" << endl;
}
}
return 0;
}
嵌套时要注意花括号的配对,就像俄罗斯套娃一样,每个内层括号都要完整匹配。初学者常常忘记写内层的花括号,导致代码逻辑混乱。
新手容易犯的错误
-
if 后面的条件忘了加括号
正确:if (score >= 60)
错误:if score >= 60 -
条件里用等号(=)和双等号(==)混淆
=是赋值,==才是判断相等
错误:if (a = 5)会把5赋值给a,然后条件永远为true(因为非零值为真),逻辑完全错了。 -
else 后面不要加条件
else 表示“所有其他情况”,不能写成else (条件),但可以写成else if (条件) -
花括号省略导致意外
如果 if 或 else 后面只有一行代码,可以省略花括号,但新手容易误以为后面多行都属于该分支。比如:if (score >= 60) cout << "及格" << endl; cout << "这句话不受if控制,始终输出" << endl;这里第二行在 if 体之外,所以不论分数多少都会输出。建议即使一行也加上花括号。
完整可运行的示例:简单计算器(加减法)
这个程序让用户输入两个数和运算符(+或-),然后输出结果:
#include <iostream>
using namespace std;
int main() {
double a, b; // 两个操作数
char op; // 运算符
cout << "请输入两个数和运算符(如 3 + 5):";
cin >> a >> op >> b;
if (op == '+') {
cout << "结果:" << a + b << endl;
} else if (op == '-') {
cout << "结果:" << a - b << endl;
} else {
cout << "不支持的运算符!" << endl;
}
return 0;
}
相关指引
- 如果判断的条件非常多(比如星期几对应不同活动),用
if-else if可能会很长,这时可以学习 switch多分支语句 让代码更清晰。 - 如果你想在循环里做判断(比如猜数字游戏),可以结合 while循环 一起使用。
- if-else 让程序有了“大脑”,能根据情况做出不同动作,是编写智能程序的基础。
switch多分支语句:像游乐园里的多个滑梯
当你需要根据一个整数的值来决定做什么,而且有很多种可能时,用一连串的 if-else if 可能很啰嗦。这时候 switch 语句就像游乐园里的多道滑梯:你手里拿着一张数字票,走到对应的滑梯口,滑下去玩对应的项目。
switch 的基本结构
switch (变量) {
case 值1:
// 代码1
break;
case 值2:
// 代码2
break;
// 更多 case ...
default:
// 其他情况
}
工作原理:计算机计算变量(必须是整数、字符或枚举类型)的值,然后从上到下匹配每个 case 后的值。一旦匹配,就会从那个 case 开始执行,直到遇到 break 才跳出整个 switch。如果所有 case 都不匹配,就执行 default 部分的代码(default 可以省略)。
生活中的例子:星期几做什么事
比如一个学生按星期几安排课外活动:
#include <iostream>
using namespace std;
int main() {
int day = 3; // 假设今天是星期三
switch (day) {
case 1:
cout << "星期一:写代码" << endl;
break;
case 2:
cout << "星期二:看书" << endl;
break;
case 3:
cout << "星期三:跑步" << endl;
break;
case 4:
cout << "星期四:画画" << endl;
break;
case 5:
cout << "星期五:打游戏" << endl;
break;
case 6:
case 7:
cout << "周末:尽情玩" << endl;
break;
default:
cout << "输入错误,请输入1~7" << endl;
}
return 0;
}
当 day 是3时,输出“星期三:跑步”。注意 case 6: 后面没有代码也没有 break,它会“穿透”到 case 7: 并执行那里的代码,所以星期六和星期日都会输出“周末:尽情玩”。这就是 穿透fall-through 特性,可以让我们把多个 case 合并成同一个操作。
为什么需要 break?
如果没有 break,程序执行完当前 case 后不会跳出 switch,而是继续执行下一个 case 的代码,不管值是否匹配。这就像滑梯底部没有刹车,你会直接滑到下一个滑梯的起点。有时候我们故意利用穿透(如上例的 case 6 和 case 7),但更多时候需要加上 break 防止错误。
switch 能判断哪些类型?
switch 只能判断整型(int、char、short、long、enum等),不能判断浮点数(float/double)或字符串(string)。如果你想判断浮点数或范围(比如 score >= 60),只能用 if-else。
新手容易犯的错误
-
忘记写 break 导致意外穿透
比如写了一个星期几判断,忘记写 break,结果星期三会输出“星期三跑步”和“星期四画画”等,逻辑全乱。所以一般要在每个 case 末尾加 break,除非特意想穿透。 -
case 后面忘记空格
正确:case 1:
错误:case1:(会被当作变量名) -
default 的位置
default 可以放在 switch 的任何位置,但习惯放在最后。注意 default 后面也要加 break,虽然它后面通常没有 case了,但为了风格统一建议加上。 -
case 值重复
两个 case 不能用相同的值。 -
变量类型不匹配
如果 switch 的变量是 char 类型,case 值要用单引号:case 'A':
完整可运行的示例:简易菜单程序
学校食堂的午餐有几种选择,用 switch 实现点餐:
#include <iostream>
using namespace std;
int main() {
int choice; // 用户选择的编号
cout << "欢迎用餐!请选择今日午餐:" << endl;
cout << "1. 红烧肉饭" << endl;
cout << "2. 鸡腿饭" << endl;
cout << "3. 牛肉面" << endl;
cout << "4. 饺子" << endl;
cout << "请输入数字(1-4):";
cin >> choice;
switch (choice) {
case 1:
cout << "您选择了红烧肉饭,美味!" << endl;
break;
case 2:
cout << "您选择了鸡腿饭,营养均衡!" << endl;
break;
case 3:
cout << "您选择了牛肉面,热乎!" << endl;
break;
case 4:
cout << "您选择了饺子,管饱!" << endl;
break;
default:
cout << "没有这个选项,请重新选择。" << endl;
}
return 0;
}
相关指引
- switch 适用于离散的、固定的值判断。如果条件更复杂(比如范围、多个条件组合),请使用 if-else分支语句。
- 在循环中经常用 switch 处理菜单选择,可以结合 循环嵌套 实现反复点餐直到退出。
- 学会 switch,你的程序就拥有像自动售货机一样的能力——根据按键分配不同的商品。
for循环:像数数一样,重复固定次数
在编程中,我们经常需要重复做同一件事很多遍,比如输出1到100的数字,或者把全班同学的分数加起来。for循环 就是专门用来做“固定次数”重复的利器。它就像老师带着学生数数:“从1数到10,一个接一个,数完就停。”
for循环的三个部分
for循环的语法有三个关键部分,用分号隔开:
for (初始化; 条件; 更新) {
// 循环体
}
- 初始化:在循环开始前执行一次,通常用来定义循环变量并赋初值(比如
int i = 1)。 - 条件:每次循环开始前检查,如果条件为真则继续循环,否则退出。
- 更新:每次循环体执行完后执行,通常用来改变循环变量(比如
i++让 i 增加1)。
你可以把 for 循环想象成上学期的跑步打卡:第一天开始(初始化),每天检查是否已经够100天(条件),每天结束后在日历上打个勾(更新),然后继续。
例子:输出1到10的数字
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 10; i++) {
cout << i << " ";
}
cout << endl;
return 0;
}
执行过程:
int i = 1执行一次。- 检查
i <= 10,成立则进入循环体输出 i。 - 执行
i++,i 变为2。 - 回到第2步检查,直到 i=11 时条件不成立,循环结束。
输出:1 2 3 4 5 6 7 8 9 10
用 for 循环做累加
比如计算1+2+...+100:
#include <iostream>
using namespace std;
int main() {
int sum = 0; // 累加器,初始为0
for (int i = 1; i <= 100; i++) {
sum += i; // 相当于 sum = sum + i
}
cout << "1+2+...+100 = " << sum << endl;
return 0;
}
这里 sum 就像存钱罐,每循环一次就往里扔一枚面值为 i 的硬币。最后 sum = 5050。
循环变量可以递减
for 循环不一定非要从1递增到N,也可以从大到小。比如倒着输出:
for (int i = 10; i >= 1; i--) {
cout << i << " ";
}
// 输出:10 9 8 7 6 5 4 3 2 1
新手容易犯的错误
-
死循环:条件永远为真,比如忘记写更新部分,或者更新写反了。
for (int i = 1; i <= 10; ) { // 没写 i++,i 永远为1,条件永远真 cout << i; }程序会疯狂输出1,卡死。
-
在循环体里修改循环变量导致意外
比如在循环体里写i = 100,可能会提前结束或跳过一些迭代。 -
分号错误
三个部分之间必须用分号,但不能有多余分号。比如for (int i=1; i<=10; i++);多了一个分号,循环体变成空语句,后面的花括号只执行一次。 -
循环变量作用域
C++11之后,在 for 初始化部分定义的变量(如int i)只在循环内部有效。如果循环结束后还想用 i,需要在外面定义。
完整可运行的示例:打印九九乘法表(部分)
下面用 for 循环嵌套(先不深入)实现一行乘法表:
#include <iostream>
using namespace std;
int main() {
int n;
cout << "请输入一个数字(1-9):";
cin >> n;
for (int i = 1; i <= n; i++) {
cout << i << " * " << n << " = " << i * n << endl;
}
return 0;
}
输入 5 输出:
1 * 5 = 5
2 * 5 = 10
3 * 5 = 15
4 * 5 = 20
5 * 5 = 25
相关指引
- 如果循环次数不确定,只知道什么时候停止,用 while循环 更合适。
- 如果你需要在循环里再套一层循环(比如打印一个矩形),学习 循环嵌套。
- for 循环配合之前学的 if 语句可以解决很多实际问题,比如找出1到100之间的所有偶数。
while循环:只要条件满足,就会一直做
你听说过“还没做完作业不能看电视”吗?这句话里就藏着 while循环 的思想:只要“还没做完作业”这个条件成立,你就得一直做(重复写作业),而电视(循环体外的动作)就一直不能做。while循环就是“先检查条件,条件为真就做,然后再检查”的重复结构。
基本语法
while (条件) {
// 循环体
}
执行过程:
- 先判断条件。
- 如果条件为真,则执行一次循环体,然后回到第1步。
- 如果条件为假,则跳过循环体,执行后面代码。
所以,如果一开始条件就是假,循环体一次都不会执行。
与 for 循环的区别
- for 循环通常用于循环次数已知的情况(如“从1到100”)。
- while 循环更灵活,常用于“不知道具体次数,但知道什么时候结束”的情况。比如,不断询问用户密码直到正确为止。
例子:用 while 循环计算1到100的和
#include <iostream>
using namespace std;
int main() {
int i = 1; // 循环变量,从1开始
int sum = 0; // 累加器
while (i <= 100) {
sum += i; // 累加
i++; // 更新变量,非常重要!
}
cout << "1+2+...+100 = " << sum << endl;
return 0;
}
注意:一定要有 i++,否则 i 永远等于1,条件永远为真,程序会死循环。很多新手忘记写更新语句,导致程序卡死。
生活中的例子:密码验证
假设你设置的密码是 123456,程序要求用户输入密码,输错就重试,直到正确为止:
#include <iostream>
using namespace std;
int main() {
int password;
cout << "请输入密码:";
cin >> password;
while (password != 123456) {
cout << "密码错误,请重新输入:";
cin >> password;
}
cout << "登录成功!" << endl;
return 0;
}
这里循环次数不确定,可能试一次就正确,也可能试很多次。while 循环完美适合这种场景。
什么时候用 while 而不是 for?
- 如果循环次数由输入或计算决定,且事先不知道,用 while。
- 如果循环需要同时初始化、条件检查和更新,用 for 更紧凑。
- 实际上,两者可以相互转换,但选择哪个取决于哪段代码更易读。
新手容易犯的错误
-
忘记写更新语句导致死循环
这是最常见的 while 错误。循环体内没有改变条件中变量的语句,条件永远为真。 -
条件写反了
比如while (i > 100)想实现从1累加到100,结果条件一开始就不成立,循环体一次都不执行。 -
在条件中用赋值号=而不是双等号==
while (a = 5)会把5赋值给a,然后因为5非零,条件永远为真,死循环且逻辑错误。
完整可运行的示例:猜数字游戏(简化版)
计算机想一个1~10的整数,你猜,直到猜中为止(这里只用了while,没有if-else做提示,后面会增强):
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(0)); // 随机种子
int target = rand() % 10 + 1; // 生成1~10的随机数
int guess;
cout << "我心里想了一个1到10之间的数字,你来猜猜看!" << endl;
cout << "请输入你的猜测:";
cin >> guess;
while (guess != target) {
cout << "猜错了,再试一次:";
cin >> guess;
}
cout << "恭喜你,猜对了!" << endl;
return 0;
}
这个程序只用 while 循环实现了“猜不对就重复”的逻辑。如果结合 if 语句,可以给出“大了/小了”的提示。详见 分支与循环综合应用。
相关指引
- 如果希望循环体至少执行一次(比如先输出菜单再询问是否继续),用 do-while循环 更合适。
- while 循环经常与 if 联合使用,实现更复杂的重复操作。
- 学习 for循环 可以掌握另一种重复模式。
do-while循环:先做一次,再决定要不要继续
你有没有听过“先尝后买”这句话?商家让你先吃一小口,好不好吃再决定买不买。do-while循环 就是这样:先执行一次循环体,然后再判断条件是否继续。它保证循环体至少会执行一次,这一点和 while 循环不同。
语法
do {
// 循环体
} while (条件);
注意:后面有一个分号!这是很多新手容易忘的。
执行过程:
- 执行一次循环体。
- 判断条件,如果为真,回到第1步;否则退出。
与 while 的对比
- while:先判断,可能一次都不执行。
- do-while:先执行一次,再判断,至少执行一次。
生活中的例子:先吃一口再说
你妈妈煮了一锅汤,让你尝一下咸淡。你先喝一口(do),如果觉得不够咸,就再加盐(循环体),然后再尝一口,直到满意为止。
在程序中,假设我们想反复询问用户“是否继续?”但至少先显示一次菜单:
#include <iostream>
using namespace std;
int main() {
char choice;
do {
cout << "请输入你的选择(y/n):";
cin >> choice;
} while (choice != 'y' && choice != 'n');
cout << "你输入的是:" << choice << endl;
return 0;
}
这个程序先让用户输入一次,然后判断是否既不是 y 也不是 n,如果是就继续要求输入。注意:这里条件写的是“当输入不是 y 且不是 n 时继续”,所以输入 y 或 n 都会退出。
用 do-while 输出1到5
#include <iostream>
using namespace std;
int main() {
int i = 1;
do {
cout << i << " ";
i++;
} while (i <= 5);
cout << endl;
return 0;
}
如果初始 i = 6,循环体也会先执行一次(输出6,i变为7),然后判断 i<=5 不成立退出。输出结果为:6(仅一个数字)。
什么时候用 do-while?
当程序逻辑要求“先做一次再决定”时,do-while 是最自然的。比如:
- 菜单循环:至少显示一次菜单让用户选择。
- 游戏回合:至少进行一轮游戏再询问是否继续。
- 校验输入:先读取一次输入,如果无效则重试。
新手容易犯的错误
-
忘记写分号
while (条件);这个分号很容易忘,编译器会报错。 -
循环体只有一行时忘记花括号
虽然 do-while 的循环体可以只有一行不加大括号,但为了清晰和扩展,建议始终加花括号。 -
条件写反
比如想要“当密码错误时继续”,却写成while (password == 123456);,结果正确密码反而会让循环继续。
完整可运行的示例:反复计算直到退出
一个简单的计算器,每次让用户输入两个数和操作符,输出结果,然后问是否继续:
#include <iostream>
using namespace std;
int main() {
char ch; // 是否继续
do {
double a, b;
char op;
cout << "输入表达式(如 3.5 + 2.1):";
cin >> a >> op >> b;
if (op == '+') {
cout << "结果:" << a + b << endl;
} else if (op == '-') {
cout << "结果:" << a - b << endl;
} else {
cout << "不支持的运算符!" << endl;
}
cout << "是否继续计算?(y/n):";
cin >> ch;
} while (ch == 'y' || ch == 'Y');
cout << "再见!" << endl;
return 0;
}
这里用 do-while 确保至少计算一次。
相关指引
循环嵌套:循环里面套循环,就像做课间操
想象一下学校做课间操的情景:全校有3个年级(外层循环),每个年级有4个班(内层循环),每个班的学生依次做动作。这就是循环嵌套——一个循环的循环体里又包含另一个完整的循环。外层循环每执行一次,内层循环就要完整执行一遍。
最经典的例子:打印一个矩形
用 * 打印一个3行4列的矩形:
#include <iostream>
using namespace std;
int main() {
// 外层循环:控制行数(3行)
for (int i = 1; i <= 3; i++) {
// 内层循环:控制每行的星号数(4个)
for (int j = 1; j <= 4; j++) {
cout << "*";
}
cout << endl; // 每行结束后换行
}
return 0;
}
运行结果:
****
****
****
执行过程:
- i=1时,内层循环执行j从1到4,输出4个*,然后换行。
- i=2时,同样内层循环再完整执行一遍,输出第二行。
- i=3时,输出第三行。
内层循环像钟表的分针,外层像时针,分针转一圈(4次),时针才走一步(1行)。
打印乘法表
外层控制乘数,内层控制被乘数,且内层循环次数依赖于外层变量:
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) { // 内层循环到i为止
cout << j << "*" << i << "=" << i*j << "\t";
}
cout << endl;
}
return 0;
}
输出:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
...
注意内层循环的条件是 j <= i,所以第一行只有1个等式,第二行2个,……第九行9个。
两种常见的嵌套形式
- 内外层独立:内层循环次数固定(如矩形)。
- 内层依赖于外层:内层循环次数随外层变化(如乘法表)。
新手容易犯的错误
-
内外层变量名相同
如果内层也定义一个int i,会覆盖外层变量,导致逻辑混乱(C++允许,但容易错)。建议内层用不同的名字,如 j, k。 -
忘记重置内层变量
如果内层循环用 while 实现,且在内层结束后没有重置条件变量,第二次外层循环时内层条件可能已经不满足,导致内层不执行。例如:int i = 1; while (i <= 3) { int j = 1; while (j <= 4) { cout << "*"; j++; // 每行内层后j=5 } // 这里正常,但如果是while(j <= 4)且j没有在每行前重置,就会出问题 i++; } -
嵌套层次太深
3层以上嵌套容易让代码难以理解,也影响效率。如果必须多层,考虑用函数分解。
完整可运行的示例:打印菱形图案
用循环嵌套打印一个简单菱形(上半部分+下半部分):
#include <iostream>
using namespace std;
int main() {
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;
}
// 下半部分
for (int i = rows - 1; i >= 1; i--) {
for (int j = 1; j <= rows - i; j++) {
cout << " ";
}
for (int k = 1; k <= 2 * i - 1; k++) {
cout << "*";
}
cout << endl;
}
return 0;
}
相关指引
- 循环嵌套经常与 顺序结构 和 分支结构 结合,解决更复杂的问题。
- 学习完基本的循环嵌套,可以挑战 分支与循环综合应用 中的猜数字、求最大公约数等问题。
- 注意:嵌套循环的时间复杂度是乘积关系,层次过多或循环次数过大可能导致程序运行缓慢。
分支与循环综合应用:让程序解决真实问题
你已经学会了 if-else 分支、switch 多分支、for/while/do-while 循环以及循环嵌套。现在,把这些武器组合起来,就能编写出解决实际问题的程序了。就像做一道复杂的菜,你需要同时控制火候(循环重复)和调料(条件判断)。
综合应用一:猜数字游戏
计算机随机想一个1~100之间的数字,你猜,它会提示“大了”或“小了”,直到猜对为止。这里用到了:
srand+rand生成随机数(需要#include <cstdlib>和#include <ctime>)- do-while 循环保证至少猜一次
- if-else 分支给出提示
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(0)); // 随机种子
int target = rand() % 100 + 1; // 生成1~100的随机数
int guess; // 玩家猜测的数
int attempts = 0; // 猜的次数
cout << "我在想一个1到100之间的数字,你来猜猜看!" << endl;
do {
cout << "请输入你的猜测:";
cin >> guess;
attempts++; // 每次猜测计数加1
if (guess > target) {
cout << "太大了!再试试。" << endl;
} else if (guess < target) {
cout << "太小了!再试试。" << endl;
} else {
cout << "恭喜你,猜对了!你一共猜了 " << attempts << " 次。" << endl;
}
} while (guess != target); // 没猜对就继续
return 0;
}
这个程序把 do-while 和 if-else 完美结合,每次循环都根据猜测结果输出不同提示。注意:attempts 变量记录次数,在循环内累加。
综合应用二:辗转相除法求最大公约数
数学中的欧几里得算法:两个正整数a和b,反复用大数除以小数取余,直到余数为0,这时除数就是最大公约数。
#include <iostream>
using namespace std;
int main() {
int a, b;
cout << "输入两个正整数:";
cin >> a >> b;
int original_a = a; // 保存原始值用于输出
int original_b = b;
while (a % b != 0) {
int remainder = a % b; // 余数
a = b; // 把原来的b赋给a
b = remainder; // 把余数赋给b
}
cout << original_a << " 和 " << original_b << " 的最大公约数是:" << b << endl;
return 0;
}
这里用了 while 循环,因为不知道要循环多少次,只知道什么时候停止(余数为0)。循环体内进行了赋值交换,这是顺序结构的应用。
综合应用三:统计班级成绩
假设一个班有30个学生,输入他们的数学成绩,输出最高分、最低分和平均分。这需要:
- for 循环循环30次
- 每次输入一个分数,同时用 if 判断更新最大值和最小值
- 累加分数最后计算平均分
#include <iostream>
using namespace std;
int main() {
const int NUM_STUDENTS = 30; // 学生人数
double score; // 当前输入的分数
double sum = 0; // 总分
double maxScore = 0; // 最高分(初始设为0,假设分数非负)
double minScore = 100; // 最低分(初始设为100,假设满分100)
cout << "请输入 " << NUM_STUDENTS << " 个学生的成绩(0~100):" << endl;
for (int i = 1; i <= NUM_STUDENTS; i++) {
cout << "第" << i << "个学生:";
cin >> score;
sum += score; // 累加总分
if (score > maxScore) { // 更新最高分
maxScore = score;
}
if (score < minScore) { // 更新最低分
minScore = score;
}
}
double average = sum / NUM_STUDENTS; // 平均分
cout << "平均分:" << average << endl;
cout << "最高分:" << maxScore << endl;
cout << "最低分:" << minScore << endl;
return 0;
}
这里 for 循环控制次数,if 分支在循环体内做判断。注意 maxScore 和 minScore 的初值设定要合理,否则可能无法正确记录。
新手容易犯的错误
- 忘记初始化累加器或计数器
如sum没有赋初始值 0,会导致结果随机。 - 在循环内重置了需要保留的值
比如把maxScore放在循环内每次都赋0,就永远得不到真正最大值。 - 逻辑条件错误
比如猜数字中条件写成了while (guess == target),会变成“猜对了继续”,死循环。 - 随机数种子只调用一次
srand(time(0))应放在程序开头,如果放在循环内,会每次生成相同“随机”数(因为 time 变化慢)。
完整可运行的示例:猜数字的增强版(带有次数限制)
加一个限制:最多只能猜5次,超过则失败:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
srand(time(0));
int target = rand() % 100 + 1;
int guess;
const int MAX_ATTEMPTS = 5; // 最多猜5次
cout << "我在想一个1~100之间的数字,你只有" << MAX_ATTEMPTS << "次机会哦!" << endl;
for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
cout << "第" << attempt << "次猜测:";
cin >> guess;
if (guess == target) {
cout << "猜对了!你真厉害!" << endl;
return 0; // 直接结束程序
} else if (guess > target) {
cout << "太大了!" << endl;
} else {
cout << "太小了!" << endl;
}
}
cout << "很遗憾,次数用完了。正确答案是:" << target << endl;
return 0;
}
这里用了 for 循环控制次数,内部用 if-else 判断,并用 return 0 在猜对时提前退出程序(注意:在 main 函数中 return 会结束整个程序)。
相关指引
- 想进一步学习更复杂的数据结构(如数组、字符串),可以关注后续内容。
- 分支与循环是编程的“两板斧”,几乎所有程序都离不开它们。
- 推荐实践项目:制作一个简易计算器、猜单词游戏、生成随机验证码等。
掌握了分支和循环,你就已经拥有了编写大部分小型程序的能力!接下来可以挑战更多有趣的算法和数据结构。
例题精讲
以下C++程序在顺序结构下运行时,输出结果是什么? int a = 5; int b = 10; a = a + b; b = a - b; a = a - b; cout << a << " " << b;
在顺序结构程序中,任何一个语句都可以任意调换顺序而不影响最终结果。
请补全以下C++程序,使其实现从键盘输入两个整数,然后输出它们的和。
int main() {
int a, b;
cin >> a >> b;
int sum = ___;
cout << sum << endl;
return 0;
}关于顺序结构的描述,正确的是?
以下程序段是顺序结构的典型例子: int x = 1; x = x + 2; x = x * 3; cout << x;