C语言学习-循环嵌套打印字母金字塔
前言
最近博主也是在努力的学习C语言,在学习的过程当中碰到了一个对我来说的“难题”,足足控了我有半小时,不过这个问题也是挺有趣的,我也就借着本道题目来写一篇文章和大家交流交流
准备工作
- vs2022(其他编辑器当然也可以)
- c语言开发环境
- 勤劳的双手
开始
1.题目概览
原题是:
编写一个程序,提示用户输入大写字母,使用嵌套循环以下面金字塔的格式打印字母
打印这样的图形,要根据用户输入的字母来决定。例如,上面的图形是用户输入E后的结果。提示: 用外层循环处理行,每行使用三个内层循环,分别处理空格、以升序、以降序打印字母。
屏幕前的小伙伴们想到怎么做了吗?
ps:博主当时没有看到题目还有提示一直不知道怎么处理所以被硬控了很久,大家一定要仔细看清楚题目才行,不要像我一样
2.分析问题
观察图形发现,其实金字塔由三部分组成,如图所示一个有空格组成的红色三角形还有有一个升序字母组成的蓝色三角形,最后就是一个降序字母组成的绿色三角形(博主绘画水平不太好,见谅见谅)
解决红色三角形部分
首先我们要打印的就是红色三角形部分,首先定义一个外围的循环就是负责用来管理打印多少行的一个循环,那么我们怎么知道需要打印多少行呢?比如上文用户输入了E那么程序需要打印多少行合适?我们怎么去算出这个具体的行数呢?此时就需要借助ASCII码表了
查询ASCII表我们发现大写字母A对应的十进制为65而大写字母E对应的十进制为69,两数相减可得 4 而我们观察上文打印图形行数为5行说明我们要将用户输入的大写字母减去大写字母A的ASCII十进制数值再加上1便得到了我们需要打印的行数,下面是代码实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int Number = 0; //初始化储存打印行数的变量char Letter = 'A'; //初始化储存用户输入字母的变量printf("请输入一个大写字母:");scanf("%c", &Letter); //获取用户输入的字母Number = Letter - 'A' + 1; //计算打印的行数printf("%d", Number);return 0;
}
如果没有问题的话你将看到如下输出
可以看到我们成功算出总共需要打印多少行了,那么行的问题解决了接下来怎么解决红色三角形的问题呢?其实不难
我们先解决外部大循环,在上文代码基础上我们增加一个外循环和一个内循环,代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int Number = 0; //初始化储存打印行数的变量char Letter = 'A'; //初始化储存用户输入字母的变量printf("请输入一个大写字母:");scanf("%c", &Letter); //获取用户输入的字母Number = Letter - 'A' + 1; //计算打印的行数for (int i = 1; i < Number + 1; i++){for (int j = 0; j < Number - i; j++){printf("1");}printf("\n");}return 0;
}
这里我使用了1代替空格这样看起来更直观一点,如果没问题的话你将看到如下输出(红色方框是为打印字母预留的位置)
这样其实我们已经完成了红色三角形部分,接下来要进行其他部分了
附:算法部分其实也简单,外循环部分看条件就知道,当用户输入E时Number被赋值5,相信有c语言基础的小伙伴都知道外循环会循环5次,这里也给不理解的小伙伴解释一下循环5次是怎么来的(序号代表循环次数):
- i = 1
- i = 2
- i = 3
- i = 4
- i = 5
注意i = 6时不满足设置的条件i < Number + 1,所以并不会进行第六次循环,但如果是<=的条件的话是会进行第六次循环的,如果实在不理解建议系统的去学习一下for循环的规则还有作用,打印空白部分其实原理也简单就是第一次循环的时候打印Number - i个空格,这里的i代表的是某一行例如打印第二行i就是2
ps: 每次打印完一行之后记得打印换行否则都挤在一行了
解决蓝色三角形部分
实际上这一部分也跟红色部分原理类似,只不过蓝色部分是将红色部分倒置过来的一个三角形,我们在红色部分代码的基础上再增加一个循环用来打印蓝色部分,代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int Number = 0; //初始化储存打印行数的变量char Letter = 'A'; //初始化储存用户输入字母的变量printf("请输入一个大写字母:");scanf("%c", &Letter); //获取用户输入的字母Number = Letter - 'A' + 1; //计算打印的行数for (int i = 1; i < Number + 1; i++){for (int j = 0; j < Number - i; j++){printf("1");}for (int k = 0; k < i; k++){printf("%c", 'A' + k);}printf("\n");}return 0;
}
如果没有问题你将看到以下输出:
这样我们蓝色部分也完成了,算法其实也是很简单的,只要观察好规律就不难了,观察可知我们每一行需要打印的字母数量都是当前行数,例如第一行就打印一个字母,第二行就打印两个字母以此类推,不过比较不容易实现的就是字母递增,如果不了解ASCII表的同学可能想不出来,其实我们只要定义一个新变量,这里我是k,将变量初始化为0,接着就是写一个for循环了,在代码里我也有体现出来,每次打印的字母为 'A' + k
例如第一行的时候就是打印 'A' + 0
也就是A, 第二行就是 'A' + 1
也就是B,不懂原理的同学去看一下ASCII表字母对应的十进制数值就明白了
那么蓝色部分完成了,接下来就要完成绿色部分了
解决绿色三角形部分
这部分我个人感觉是三部分里面最有挑战性的一部分了,不过理解透了以后其实也不是很难
我们观察图形可知绿色部分比蓝色部分少打印了一行,还有就是顺序是跟蓝色部分刚好反过来的
知道这些信息后我们开始写代码,新建一个for循环用于打印绿色部分,具体代码如下
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int Number = 0; //初始化储存打印行数的变量char Letter = 'A'; //初始化储存用户输入字母的变量printf("请输入一个大写字母:");scanf("%c", &Letter); //获取用户输入的字母Number = Letter - 'A' + 1; //计算打印的行数for (int i = 1; i < Number + 1; i++){char temp = 'A' + i - 2; //获取当前行打印的ASCII数值最大的字母for (int j = 0; j < Number - i; j++){printf("1");}for (int k = 0; k < i; k++){printf("%c", 'A' + k);}for (int l = 0; l < i - 1; l++){printf("%c", temp - l);}printf("\n");}return 0;
}
这里解释一下temp的用处,temp是用来获取当前行要打印的ASCII数值最大的字母的,比如在第二行,我们这一部分需要打印的最大ASCII数值最大的字母是A,而第三行是B,后续以此类推,那么我们怎么知道该行需要打印的最大ASCII数值的字母是哪个呢,这就需要算法来解决,我这里的算法就是A加上当前行数再减去2就可以获得,具体原理只可意会不可言传:P
还有比较不容易理解的地方就是为什么条件是 i -1
这是因为绿色部分要比蓝色部分少打印一行所以需要条件为 i - 1
例如第一行的时候我们绿色部分就不需要打印,此时 i = 1
那么减去 1 后就是 0 而绿色部分循环变量初始值也是0所以在第一行的时候循环就不会进行,因此也就不会打印字母
最后记得把红色部分打印的1换成空格
结尾
相信看完我的文章你已经学会了如何获取用户输入的字母并根据输入的字母打印一个字母金字塔了,感谢您的阅读,如果我的文章对您有帮助的话不妨点个赞还有收藏,分享给更多需要的人,或者您对本文章有什么看法或者问题欢迎留下评论,我也会积极回复大家的(如果有看到的话)
我的企鹅交流裙:934541995,欢迎大家来学习交流