嵌套循环
一、 什么是嵌套循环
嵌套循环:指在一个循环内包含另一个循环。通俗来说就是多层使用循环,可利用外循环控制一个变量,内循环控制另一个变量,达最终目的。
二、程序中的嵌套
首先,利用一个简单的程序来看看嵌套的使用——打印九九乘法表。
#include<stdio.h>
#include<Windows.h>
int main()//九九乘法表
{
for (int row = 1; row <= 9; row++)//row: 行
{
for (int col = 1; col <= row; col++)//col: 列
{
printf("%d*%d=%2d ", row, col, row * col);
Sleep(200);//延时200ms
}
printf("\n");
Sleep(200);//延时200ms
}
return 0;
}
在程序中我们加入了Sleep延时,只是为方便看清该打印程序执行的顺序。在程序中我们可以看到程序利用变量 row 控制乘法表的行,利用变量col 控制乘法表的列,但与此同时内部循环 col 的最高值又依赖于外部循环 row 的值,以此达到每行扩展列的目的,最终完成乘法表的打印。
打印圣诞树
该题来源于: 牛客网——在线编程——语法篇。
一、 题目说明
如图所示,题目要求我们输入对应的高度 h ,就要打印相对的圣诞树图形,且程序是可以多组输入的。
二、分析 > 1
先来分析树上大三角部分,根据题中 h 的变化,各个图形的变化,可看见当 h 变化时,圣诞树大三角中小三角的行数也随之相对应的变化, h == 1时,小三角为一行; h == 3时,小三角的行数为3,所以我们可以将圣诞树的高度可以看在这。因此可以定义以下循环来控制这个行数:
int h = 0; //初始化要输入的高度
scanf("%d", &h);
for (int greater_row = 1; greater_row <= h; greater_row++)
{ //利用h的值来控制大三角的最大高度
; //greater_row为循环变量,控制该高度所在的区域
}
三、分析 > 2
由图可见大三角每个 h 控制的区域都有小三角组成,每个小三角都为同一规则图形,此时,就可定义变量 little_row 来控制每个区域小三角的行,添加以下循环可见:
int main()
{
int h = 0;
scanf("%d", &h);
for (int greater_row = 1; greater_row <= h; greater_row++)//greater_row控制高度
{
for (int little_row = 1; little_row <= 3; little_row++)//little_row控制每个小三角的行
{
;
}
}
}
上述 变量 little_row 变量最大值已知,且不受外部循环变量的控制,所以循环判断部分 little_row <= 3。
四、分析 > 3
由上图可见,大三角几乎每行前面都有空格,空格数目由 8 递减至最后 0,观察可得第一行最大空格数与 h 的关系为 space_num = 3 * h - 1(space_num 变量定义为空格数),所以此时可以再次嵌入一个新的循环来控制大三角区域前面空格的打印,由以下程序可见:
int main()
{
int h = 0;
scanf("%d", &h);
int space_num = 3 * h - 1;
for (int greater_row = 1; greater_row <= h; greater_row++)//greater_row控制高度
{
for (int little_row = 1; little_row <= 3; little_row++)//little_row控制每个小三角的行
{
for (int space = 1; space <= space_num; space++)//space_num:需打印空格的最大数
{ //space: 标记循环已打印空格的个数
printf(" ");
}
space_num--;
printf("\n");
}
}
return 0;
}
程序当中,space所在循环每次执行完,space_num- -,这是因为空格每打印完一行,跳转至下一行,最大空格数就递减1。因为空格的打印并不可见,接下来在程序中加入延时Sleep,并将程序中空格替换成字符’.',代替观看空格的打印,如下图:
五、分析 > 4
单看 h == 1的区域还不能看出什么,但由 h == 2 与 h == 2的区域我们可见,大三角区域内部的小三角打印后会出现一个空格打印的倒三角部分,由此可见我们可以将一个小三角和一个空格倒三角看成一个整体菱形部分,既然如此,我们何不将所有小三角都与一个倒三角区域划分到一起去,形成一个更加规则的整体,如下图所示:
由上图可见,每个 h 控制的区域内,菱形的个数都与之相同,与此同时我们可见每个 ‘*’ 后都连着一个空格,所以与此空格分开,可见每个小三角第一行后面都跟着4个空格,第二行都跟着2个空格,第三行后面没有空格,如下图:
所以我们可以在变量 little_row 所控制的循环中再次嵌入新的循环来打印图形,如下:
int main()
{
int h = 0;
scanf("%d", &h);
int space_num = 3 * h - 1;
for (int greater_row = 1; greater_row <= h; greater_row++)//greater_row控制高度
{
for (int little_row = 1; little_row <= 3; little_row++)//little_row控制每个小三角的行
{
for (int space = 1; space <= space_num; space++)//space_num:需打印空格的最大数
{ //space: 标记循环已打印空格的个数
printf(" ");
}
space_num--;
for (int diamond = 1; diamond <= greater_row; diamond++) // 标记当前 h 区域菱形打印的个数
{
for (int diamond_row = 1; diamond_row <= little_row; diamond_row++)// 菱形的每一行
{
printf("* ");
}
if (little_row == 1)// 小三角第一行
printf(" ");//四个空格
if (little_row == 2)//小三角第一行
printf(" ");//两个空格
}
printf("\n");
}
}
return 0;
}
程序当中变量 diamond 受外部变量 greater_row 的控制,所以将最大值设为 greater_row;变量 diamond_row 受外部变量 little_row,所以将最大值设为little_row;变量 little_row 关乎倒立小三角的空格打印,所以由它的变化来控制这部分空格的打印。
接下来看看上部分打印得情况:
六、分析 > 5
由图可见,树干的高度与 h 相同,且每行前面的空格都与 3 * h - 1 相同,所以可以加入以下部分控制树干的打印:
for (int i = 1; i <= h; i++)//打印树干,i控制高度
{
for (int j = 1; j <= 3 * h - 1; j++)//j 控制打印空格
{
printf(" ");
}
printf("*\n");
}
七、结果打印
为了实现多组输入多组打印,我们可以将程序的主体部分嵌入以下部分:while (scanf("%d", &h) != EOF) { ; }
整体打印结果如下图所示:
程序
#include<stdio.h>
int main()
{
int h = 0;
while (scanf("%d", &h) != EOF)
{
int space_num = 3 * h - 1;
for (int greater_row = 1; greater_row <= h; greater_row++)//greater_row控制高度
{
for (int little_row = 1; little_row <= 3; little_row++)//little_row控制每个小三角的行
{
for (int space = 1; space <= space_num; space++)//space_num:需打印空格的最大数
{ //space: 标记循环已打印空格的个数
printf(" ");
}
space_num--;
for (int diamond = 1; diamond <= greater_row; diamond++) // 标记当前 h 区域菱形打印的个数
{
for (int diamond_row = 1; diamond_row <= little_row; diamond_row++)// 菱形的每一行
{
printf("* ");
}
if (little_row == 1)// 小三角第一行
printf(" ");//四个空格
if (little_row == 2)//小三角第一行
printf(" ");//两个空格
}
printf("\n");
}
}
for (int i = 1; i <= h; i++)//打印树干,i控制高度
{
for (int j = 1; j <= 3 * h - 1; j++)//j 控制打印空格
{
printf(" ");
}
printf("*\n");
}
}
return 0;
}