CC++ & Algorithm

循环嵌套与图形打印

中等22
语言版本:C++Python
概述:通过画三角形、正方形等图形,学会用循环里面套循环的方法控制行和列的输出。

循环嵌套——用星星画出各种图形

你有没有在美术本上画过方格?先画一行格子,再画下一行,一行一行把整个方块填满。计算机打印图形也是一样的道理:我们需要告诉它“先画第一行,再画第二行……”,而每一行又需要“从第一列画到最后一列”。在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. 新手常见错误

在编写循环嵌套时,最容易犯以下几个错误:

  1. 忘记换行:内循环结束后如果没有cout << endl;,所有星星会挤在一行。
  2. 内循环条件写错:比如想打印直角三角形,却写成col<=4,导致所有行星数一样多。
  3. 变量重复命名:内外循环的循环变量不能同名(比如都叫i),否则内循环会改变外循环的变量值,导致程序混乱。
  4. 括号不匹配:循环嵌套时,大括号要对应好,最好用缩进让代码层次清晰。

下面是一个错误示例,看你能不能找出问题:

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. 相关指引

学会循环嵌套后,你可以做很多有趣的事:

  • 打印九九乘法表:外层行19,内层列1行,输出乘积。
  • 处理二维数据:比如表格、棋盘、图像像素,都用两层循环来遍历。
  • 为后续学习二维数组打基础:二维数组的遍历方式与循环嵌套一模一样。

试试自己画一个“圣诞树”吧(多个等腰三角形叠起来),或者画一个“沙漏”(上大下小)。多动手,你很快就能成为“图形打印小高手”!

例题精讲

1单选题

以下代码用于打印一个由星号组成的直角三角形(直角在左下角),请问内层循环的条件判断应填入什么? for(int i=1; i<=5; i++) { for(int j=1; j<=___; j++) { cout << "*"; } cout << endl; }

Ai
B5-i+1
C5
Di*2-1
2判断题

在打印菱形图案时,如果总行数为奇数(例如7行),则上半部分(包括中间行)的空格数量从(行数-1)/2递减到0,星号数量从1递增到行数。

3填空题
以下代码打印一个倒三角形(直角在左上角),请填写内层循环的终止条件。

for(int i=5; i>=1; i--) {
    for(int j=1; j<=___; j++) {
        cout << "*";
    }
    cout << endl;
}
4单选题

打印九九乘法表时,通常使用两层循环,外层循环变量i从1到9,内层循环变量j从1到i。若将该程序改为输出完整的9×9矩形(即每行都输出9个乘法算式),应如何修改内层循环?

A将j<=i改为j<=9
B将j<=i改为j<=9-i+1
C将j<=i改为j<=i*2-1
D无需修改,直接运行即可
5判断题

在C++中,使用循环嵌套打印图形时,外层循环控制行数(高度),内层循环控制列数(宽度),这个说法对于打印矩形、三角形等规则图形总是正确的。