C:图案打印

引言

本篇文章讲了一些常见的图形编程题,并总结了一些规律。

1、打印空心正方形

1.1 代码展示:

cpp 复制代码
#include<stdio.h>
int main()
{
	int a = 0;//边长初始化
	scanf("%d", &a);//输入边长的值
	{
		int i = 0;
		for (i = 0; i < a; i++)//控制行数
		{
			int j = 0;
			for (j = 0; j < a; j++)//控制列数
			{
				if (i == 0 || i == a - 1)//判断行数是否打印 *
				{
					printf("* ");//*后面留一个空格
				}
				else if (j == 0 || j == a - 1)//判断列数是否打印 *
				{
				    printf("* ");//*后面留一个空格
			    }
			    else
			    {
				    printf("  ");//这里留两个空格
			    }				
			}
			printf("\n");//换行
		}			
	}
	return 0;
}

图案展示:

1.2 代码解析:

1.通过scanf函数获得输入的边长值

2.通过两层循环来控制每行每列的输出

  • 外层循环控制行数,当行号为 0(第一行)或 a - 1(最后一行)时,整行打印 *。
  • 内层循环控制列数,当列号为 0(第一列)或 a - 1(最后一列)且当前行不是第一行和最后一行时,打印 * ,其他位置打印两个空格。

3.每行打印完换行。

1.3 分析i == 0 || i == a - 1

为什么满足这个条件就打印*就可以得到空心正方形?看下图:

这里就用图解释了,如果还有些不明白,可以私我

2、空心三角形

2.1 思路分析

  1. 使用两个嵌套的循环,外层循环控制行数,内层循环控制每行的输出。
  2. 对于每行,先打印一定数量的空格,使得三角形对齐。
  3. 然后判断当前行的位置,如果是第一行、最后一行或者是每行的第一个和最后一个字符位置,打印 * ,否则打印空格。

2.2 代码展示:

cpp 复制代码
#include <stdio.h>

int main() {
    int rows = 0;
    scanf("%d", &rows);//输入行数

    for (int i = 1; i <= rows; i++) {  // 外层循环控制行数
        for (int j = 1; j <= rows - i; j++) {  // 打印每行前面的空格
            printf(" ");
        }
        for (int k = 1; k <= 2 * i - 1; k++) {  // 处理每行的字符输出
            if (k == 1 || k == 2 * i - 1 || i == rows) {  // 第一行、最后一行、每行的首尾位置打印*
                printf("*");
            } else {  // 中间位置打印空格
                printf(" ");
            }
        }
        printf("\n");  // 换行
    }
    return 0;
}

2.3 代码解析:

  1. 定义一个变量rows用来存储行数
  2. 内层的第一个 for 循环**for (int j = 1; j <= rows - i; j++)** 用于在每行的开头打印适当数量的空格,以使三角形对齐。
  3. 内层的第二个**for** 循环**for (int k = 1; k <= 2 * i - 1; k++)** 处理每行的字符输出。if (k == 1 || k == 2 * i - 1 || i == rows)这个条件判断用于确定是否打印* 。当是每行的第一个字符**(k == 1)** 、最后一个字符**(k == 2 * i - 1)** 或者是最后一行**(i == rows)** 时,打印 * ,否则打印空格。

3、X形图案

3.1代码展示:

cpp 复制代码
#include <stdio.h>

int main()
{
	int size = 0;  // 初始化
    scanf("%d", &size);//输入值
    int i = 0;
	for ( i = 0; i < size; i++)  // 行循环
	{ 
        int j = 0;
		for ( j = 0; j < size; j++)// 列循环
		{  
			if (i == j || i + j == size - 1)// 判断是否为对角线上的位置
			{  
				printf("*");  // 打印 '*'
			}
			else 
			{
				printf(" ");  // 否则打印空格
			}
		}
		printf("\n");  // 换行
	}
	return 0;
}

图案展示:

3.2 代码解析:

1.先定义一个变量size来表示图案的大小;

2.使用两个嵌套的for循环,外层控制行数,内层控制列数;

3.你可以将图案看作在一张表格上,对于每个位置( i , j ),通过条件判断 i == j 表示主对角线(从左上角到右下角)上的位置,

i + j == size - 1表示副对角线(从右上角到左下角)上的位置。

4.如果当前位置在对角线上,则打印***,**否则打印空格。

5.每行打印完后,记得换行。

3.3 i == j || i + j == size - 1解释

假设我们有一个 size*``size 的二维矩阵(例如 5×5)。

对于主对角线(从左上角到右下角),行索引**i** 和列索引**j** 是相等的,即**i == j** 。(索引即下标);

例如,在 5*5 的矩阵中,主对角线上的点为 (0, 0)、(1, 1)、(2, 2)、(3, 3)、(4, 4) ,都满足**i == j 。**

对于副对角线(从右上角到左下角),行索引**i** 与列索引 j 的和等于矩阵的边长减 1,即 i + j == size - 1

例如,在 5*5 的矩阵中,副对角线上的点为 (0, 4)、(1, 3)、(2, 2)、(3, 1)、(4, 0) ,都满足 i + j == 4 (因为 5 - 1 = 4)。

所以,当满足 **(i == j || i + j == size - 1)**这个条件时,就可以确定是在这两条对角线上。

3.4 注意事项:

**printf("\n"); //换行不要写到内循环里面去了,**否则会出现下面这种情况

4.沙漏

4.1 代码展示:

cpp 复制代码
#include <stdio.h>
int main() {
    int a = 0;
    printf("请输入沙漏的行数(奇数): ");
    scanf("%d", &a);//输入行数

    for (int i = 1; i <= a; i++) {  //外层循环控制上半部分沙漏的行数,从第 1 行到第 a 行
        for (int j = 1; j < i; j++) { //内层循环打印每行开头的空格,空格数量逐行递增
            printf(" ");
        }
        for (int k = 1; k <= 2 * (a - i + 1) - 1; k++) {
            printf("*");//内层循环打印星号,星号数量逐行递减
        }
        printf("\n");//换行
    }
    for (int i = a - 1; i >= 1; i--) { // 外层循环控制下半部分沙漏的行数,从倒数第 2 行到第 1 行
        for (int j = 1; j < i; j++) { // 内层循环打印每行开头的空格,空格数量逐行递减
            printf(" ");
        }
        for (int k = 1; k <= 2 * (a - i + 1) - 1; k++) {
            printf("*");// 内层循环打印星号,星号数量逐行递增
        }
        printf("\n");
    }
    return 0;
}

图案演示:

4.2 分析(结合注释)

对于上半部分:

  • 随着 i 的增加,每行前面的空格数量也增加,因为**j < i 。**
  • 同时,星号的数量通过**2 * (a - i + 1) - 1** 计算得到,随着 i 的增加而减少。

对于下半部分:(对称)

  • 随着 **i**的减小,每行前面的空格数量减少。
  • 星号的数量通过相同的公式计算,随着**i**的减小而增加,从而形成与上半部分对称的沙漏形状。

5、一些规律

1 使用嵌套的循环结构

外层循环通常控制图形的行数。内层循环控制每行的输出内容,比如空格数量、特定字符的数量等。

2 利用对称性

对于对称的图形,常常可以利用上半部分和下半部分的对称关系,通过修改循环的条件和范围来减少重复的代码。

3 注意边界条件

例如对于三角形、矩形等图形,要正确处理第一行、最后一行、第一列和最后一列的输出,以确保图形的形状完整和准确。

4 使用控制语句

if-else 语句来区分不同的行或列的输出模式。

5 以行列的思想为基础

学会逐行逐列构造图形。


结语:

图形化编程题目对于帮助我们熟悉循环和控制结构的使用非常有帮助。通过这些题目,我们可以更加深入地理解循环和控制结构的工作原理,并且能够在实践中更好地应用它们。

明天开始更新C语言的知识模块!!!

相关推荐
卡尔特斯1 天前
Android Kotlin 项目代理配置【详细步骤(可选)】
android·java·kotlin
白鲸开源1 天前
Ubuntu 22 下 DolphinScheduler 3.x 伪集群部署实录
java·ubuntu·开源
ytadpole1 天前
Java 25 新特性 更简洁、更高效、更现代
java·后端
纪莫1 天前
A公司一面:类加载的过程是怎么样的? 双亲委派的优点和缺点? 产生fullGC的情况有哪些? spring的动态代理有哪些?区别是什么? 如何排查CPU使用率过高?
java·java面试⑧股
JavaGuide1 天前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
用户3721574261351 天前
Java 轻松批量替换 Word 文档文字内容
java
白鲸开源1 天前
教你数分钟内创建并运行一个 DolphinScheduler Workflow!
java
CoovallyAIHub1 天前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
Java中文社群1 天前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试
代码匠心1 天前
从零开始学Flink:数据源
java·大数据·后端·flink