【C语言】打印图案问题(上卷)

目录

前言

初出茅庐:金字塔图案

提示:

题目:

分析:

金字塔完整代码参考:

小有成就:菱形图案 

提示:

题目:

分析: 

陷阱:

菱形图案完整代码参考:

更进一步,游刃有余


前言

打印图案的问题,刚拿到时,看着题目里的图案,总觉得超有感觉,许多不同的灵感一瞬间涌入大脑,一顿操作猛如虎,最终发现哪个思路好像都有点问题,抓耳挠腮硬是写不出来,甚至都想对着图案暴力打好了直接输出了。这是不是你?反正,这就是我。不甘心就这样输给这类题目,我决定总结一下这类打印图案的问题。

关于打印图案的题目我将循序渐进给出四道例题(对于初学C语言的我们来说都不太容易)的讲解,其中前两题由于相似度很高且难度刚好由低到高,写为打印图案问题(上卷),后两题写成打印图案问题(下卷),可以当作闯关。

我的讲解应该够细致,包你听得懂!那么话不多说,闯关开始吧!

初出茅庐:金字塔图案

提示:

需要的“武器”是嵌套循环,不过,是在一个外循环里一前一后嵌套两个并列等级的内循环哦!

题目:

怎么打印一个下图中的图案?

(可别想着暴力输出啊喂!)

分析:

首先我们分析最表面的东西:我们需要打印的行数是5。

然后,既然是图案相关的问题,必然少不了找规律。但是有一个这样的点是,规律不是乱找的。因为我们不是在做数学题,我们要用C语言来实现,所以我们要找的规律应该要能对写代码起到作用。比如我想,规律就是每一行在左边加上一个星号,右边加上一个星号,很容易看得出这个规律,但却无法转化成具体的代码。

所以我们想,既然我们不能想在哪里打印就随意地在哪打印(比如第一行我就想打在中间,中间是哪里?没有办法这么随心所欲),那我们可以先打印空格,再打印星号。由此把这个问题一分为二,只要每一行我们控制打印几个空格再打印几个星号,我们就能得到想要的效果。

所以我们要找的规律不再是单纯直观从图案形状出发,而是我们要打印的空格和星号数量对于行数来说,有什么变化规律?

行数总是用创建的变量i来表示,这没什么好多说,重要的是我们在找空格和星号的规律时,要注意去找其与行数i之间的关联!通俗点说,就是让这个空格数与星号数能直接写成i相关的表达式,5-i和2*i-1,在得到这个规律后,我们就只剩下根据逻辑写出代码了。

金字塔完整代码参考:

(为了辅助理解,注释写得有点多)

​
#include <stdio.h>
int main()
{
	int i, j, k;//i控制行数,j控制空格,k控制星号
	for (i = 1; i <= 5; i++)//为了更好代表行数,直接从1开始取值、循环
	{
		//j的取值从1~5-i,即取了5-i次值,循环了5-i次,
		//每一次打印一个空格,所以打印了5-i个空格。
		//随着i每轮循环,打印的空格数量也跟着改变。
		for (j = 1; j <= 5-i; j++)
			printf(" ");
		for (k = 1; k <= 2 * i - 1; k++)//k也是同样的道理
			printf("*");
		printf("\n");//每一行打印完空格和星号后记得换行
	}
	return 0;
}

​

在vs2022运行效果: 

小有成就:菱形图案 

提示:

这个问题和前一个金字塔有点像,做法也没有什么高深的变化,但是操作起来更复杂。

题目:

怎么打印一个下图中的菱形?

 

分析: 

如果你像我一样,在刚开始的时候绞尽脑汁去想能有一个大循环把整个图案的规律都涵盖了,你就会发现好像怎么都找不到这个规律。

确实,这题应该一分为二,把这个菱形分为上半部分和下半部分。中间最长的这一行其实分到上或者下都行,不妨就划分到上半部分吧。那么上半部分是7行,下半部分是6行。我们先来看上班部分。

上半部分不正是我们上一道题里的金字塔吗?一样的,我们还是去找空格数、星号数各自与行数之间的关系:

所以我们可以很快得到上半部分的代码:

	int i, j, k;//i控制行数,j控制空格数,k控制星号数
	for (i = 1; i <= 7; i++)
	{
		for (j = 1; j <= 7 - i; j++)
			printf(" ");
		for (k = 1; k <= 2 * i - 1; k++)
			printf("*");
		printf("\n");//每一行内容打印完记得换行
	}
	return 0;

接下来就是处理下半部分:

空格数与行数的关系一目了然,但是这个星号数则比较棘手。好像怎么看都与i没什么关系。但是我们心里明白11、9、7、5、3、1是有规律的,我们很容易想到数学里的2n-1,只可惜i不是6、5、4、3、2、1,如果是的话就刚好是2*i-1了,但是我们可以人为去弥补这个遗憾:去找i和6、5、4、3、2、1之间的关系,我们发现就是一个7-i的关系,于是星号数就可以写成2*(7-i)-1。

由此,我们就可以得出下半部分的代码:

	for (i = 1; i <= 6; i++)
	{
		for (j = 1; j <= i; j++)
		{
			printf(" ");
		}
		for (k = 1; k <= 2 * (7 - i) - 1; k++)
		{
			printf("*");
		}
		printf("\n");
	}
陷阱:

在处理下半部分时,第一行的起始位置是有一个空格的,如果忘了的话,打出来会是这样的效果:

打印图案的题总是在前几次尝试运行时发现打印出来奇奇怪怪的,这很正常,不要急躁,耐心地寻找问题并解决就行啦!

菱形图案完整代码参考:

 

在vs2022上运行效果:

更进一步,游刃有余

其实,在把这个菱形图案分为上下两部分时,我们是预先知道上半部分总共7行,下半部分6行,基于此来写的。我们可以改进一下我们的代码,一方面加强上下部分之间的关联性,另一方面也是更重要的方面:增强这个代码的普适性,在打印更大或者更小的菱形时都可以用。

那么我们不妨直接这样写:

int line = 0;//line代表上半部分的总行数,本题中是7
scanf("%d", &line);

然后再去修改我们循环中的代码:

运行效果:

那么现在我们可以随意打印更大或者更小的菱形了: 

至此,打印图案问题(上卷)就讲解完毕,敬请期待下卷!相信和我一样初学C语言的小伙伴看完一定能有所收获!欢迎指正本文的错误,共同进步! 

  • 44
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值