循环嵌套与图形打印
中等22循环嵌套——用星星画出各种图形
你有没有在美术本上画过方格?先画一行格子,再画下一行,一行一行把整个方块填满。计算机打印图形也是一样的道理:我们需要告诉它“先画第一行,再画第二行……”,而每一行又需要“从第一列画到最后一列”。在C++里,我们可以用循环嵌套(一个循环里面再套一个循环)来轻松完成这件事。
什么是循环嵌套?
循环嵌套就像“排队的时候,每一排又有一列一列的人”。外层的循环负责“第几排”,内层的循环负责“这一排的第几个人”。比如,我们要打印一个4行4列的正方形,外层循环跑4次(行数),内层循环每次跑4次(列数),内层循环每跑一次就打印一个星,跑完一行就换行。
生活中也很常见:你和朋友玩“跳房子”,每一层(行)要跳固定几个格子(列),这就是嵌套的思想。
1. 打印正方形:行数固定,每行列数也固定
先看一个最简单的例子:打印一个4行4列的正方形。
#include <iostream>
using namespace std;
int main() {
for (int row = 1; row <= 4; row++) { // 外循环:控制行数,从1到4
for (int col = 1; col <= 4; col++) { // 内循环:控制每行列数,每行固定4列
cout << "* "; // 打印一个星和一个空格
}
cout << endl; // 一行结束,换行
}
return 0;
}
运行结果:
* * * *
* * * *
* * * *
* * * *
小关键:外循环每执行一次,内循环就要完整地执行一轮(从col=1走到col=4)。内循环全部结束后,才换到下一行。
2. 打印直角三角形:列数随行数变化
现在,我们想要一个直角三角形,第一行1个星,第二行2个星……第n行n个星。只要让内循环的结束条件从固定col<=4变成col<=row就可以,因为row的值刚好等于当前行需要的星数。
#include <iostream>
using namespace std;
int main() {
for (int row = 1; row <= 4; row++) { // 外循环:控制行数
for (int col = 1; col <= row; col++) { // 内循环:列数等于当前行号,col <= row
cout << "* ";
}
cout << endl; // 换行
}
return 0;
}
运行结果:
*
* *
* * *
* * * *
想一想:如果想让三角形倒过来(第一行4个,第二行3个……),该怎么做?把内循环条件改成col <= 5 - row试试看。
3. 更多创意图形——找规律是关键
只要找到每一行星的个数与行号之间的关系,你就能画出各种有趣的图形。例如:
- 倒直角三角形:行号row从1到4,第row行星数 = 5 - row
- 等腰三角形(对称的树形):第row行前面先打几个空格,再打星。空格的个数 = 总行数 - row,星的个数 = 2 * row - 1
- 菱形:上半部分等腰三角形,下半部分倒等腰三角形
下面打印一个5行的等腰三角形:
#include <iostream>
using namespace std;
int main() {
int total_rows = 5; // 总行数
for (int row = 1; row <= total_rows; row++) { // 外循环:每一行
// 先打印空格:空格数 = total_rows - row
for (int space = 1; space <= total_rows - row; space++) { // 内循环1:打印空格
cout << " "; // 两个空格让图形更清晰
}
// 再打印星星:星星数 = 2 * row - 1
for (int star = 1; star <= 2 * row - 1; star++) { // 内循环2:打印星星
cout << "* ";
}
cout << endl; // 换行
}
return 0;
}
运行结果:
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
4. 新手常见错误
在编写循环嵌套时,最容易犯以下几个错误:
- 忘记换行:内循环结束后如果没有
cout << endl;,所有星星会挤在一行。 - 内循环条件写错:比如想打印直角三角形,却写成
col<=4,导致所有行星数一样多。 - 变量重复命名:内外循环的循环变量不能同名(比如都叫i),否则内循环会改变外循环的变量值,导致程序混乱。
- 括号不匹配:循环嵌套时,大括号要对应好,最好用缩进让代码层次清晰。
下面是一个错误示例,看你能不能找出问题:
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= i; j++) {
cout << "* ";
}
// 忘记换行
}
// 结果会打印成一行:* * * * * * * * * *
5. 完整可运行示例:打印菱形
把等腰三角形和倒等腰三角形组合起来,就能画出菱形。下面的代码打印一个5行高的菱形(中间最宽9颗星,注意空格对齐)。
#include <iostream>
using namespace std;
int main() {
int n = 5; // 菱形的行数(上半部分行数),总行数 = 2*n-1
// 上半部分(包括中间一行)
for (int row = 1; row <= n; row++) { // 外循环:行数1到n
// 打印空格
for (int space = 1; space <= n - row; space++) { // 内循环:空格数递减
cout << " "; // 两个空格
}
// 打印星
for (int star = 1; star <= 2 * row - 1; star++) { // 内循环:星数递增
cout << "* ";
}
cout << endl; // 换行
}
// 下半部分(不包括中间一行,因为已经在上面打印了)
for (int row = n - 1; row >= 1; row--) { // 外循环:行数从n-1到1
// 打印空格
for (int space = 1; space <= n - row; space++) { // 内循环:空格数递增
cout << " ";
}
// 打印星
for (int star = 1; star <= 2 * row - 1; star++) { // 内循环:星数递减
cout << "* ";
}
cout << endl; // 换行
}
return 0;
}
运行结果(空格可能显示为两个空格,实际打印位置对齐):
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
* * * * * * *
* * * * *
* * *
*
6. 相关指引
学会循环嵌套后,你可以做很多有趣的事:
- 打印九九乘法表:外层行1
9,内层列1行,输出乘积。 - 处理二维数据:比如表格、棋盘、图像像素,都用两层循环来遍历。
- 为后续学习二维数组打基础:二维数组的遍历方式与循环嵌套一模一样。
试试自己画一个“圣诞树”吧(多个等腰三角形叠起来),或者画一个“沙漏”(上大下小)。多动手,你很快就能成为“图形打印小高手”!
例题精讲
以下代码用于打印一个由星号组成的直角三角形(直角在左下角),请问内层循环的条件判断应填入什么? for(int i=1; i<=5; i++) { for(int j=1; j<=___; j++) { cout << "*"; } cout << endl; }
在打印菱形图案时,如果总行数为奇数(例如7行),则上半部分(包括中间行)的空格数量从(行数-1)/2递减到0,星号数量从1递增到行数。
以下代码打印一个倒三角形(直角在左上角),请填写内层循环的终止条件。
for(int i=5; i>=1; i--) {
for(int j=1; j<=___; j++) {
cout << "*";
}
cout << endl;
}打印九九乘法表时,通常使用两层循环,外层循环变量i从1到9,内层循环变量j从1到i。若将该程序改为输出完整的9×9矩形(即每行都输出9个乘法算式),应如何修改内层循环?
在C++中,使用循环嵌套打印图形时,外层循环控制行数(高度),内层循环控制列数(宽度),这个说法对于打印矩形、三角形等规则图形总是正确的。