C博客作业02--循环结构

| 这个作业属于哪个班级 |


| ---- | ---- | ---- |
| 这个作业的地址 |
| 这个作业的目标 | 学习循环结构内容,包括for循环、while循环、循环嵌套 |
|姓名|张静雯|

0.展示PTA总分(0----2)

1.本章学习总结(2分)

整理这两周学习主要知识点,并能对每个知识点介绍简单案例或语法。不要截图ppt,自己文字书写。知识点包含:

1.1 for循环语法

for(表达式1;表达式2;表达式3)
{
    循环体语句
}

注意:for语句中,用分号分隔三个表达式,但for的后面没有分号,因为与其后的循环体语句合起来作为一条完整的语句。

1.2 while、do while循环语法

-while循环语法

while(表达式)
   循坏体结构;

whlie与for循环的选择
一般情况下,如果题目中指定了循环次数,用for语句更加清晰,循环的4个组成部分一目了然;其他情况下多使用while语句
-do while循环语法

do{
    循环体语句
}while(表达式);

do-whlie适合于什么情况?
do-while语句适合于先循环后判断条件的情况,一般在循环体的执行过程明确循环控制条件。

1.3 跳出循环相关语句break\continue

区别
1.break结束循环,而continue只是跳过后面的语句继续循环
2.break除了可以中止循环外,还用于switch语句,而continue只能用于循环。

案例

假设有10个同学在玩唱歌游戏,从一号同学开始轮,到遇到号数为三的倍数时,游戏终止,输出需要唱歌的号码。

#include<stdio.h>
int main()
{
    
    for (int i = 1; i<=10; i++)
    {
        if (i % 3 == 0)
        {
            break;
        }
        printf("%d号同学需要唱歌\n", i);
    }
    return 0;
}

代码运行结果如下

可以看出,当遇到break时,循环结束,不再执行循环体后其他语句,所以三号同学之后的同学都不需要唱歌
假如换成continue会发生什么?

#include<stdio.h>
int main()
{
    
    for (int i = 1; i<=10; i++)
    {
        if (i % 3 == 0)
        {
            continue;
        }
        printf("%d号同学需要唱歌\n", i);
    }
    return 0;
}

此时输出结果如下

可以看出此时除了3号,6号,9号,其他7名同学都需要唱歌,因此,continue只是跳过了continue之后的其他语句,也就是唱歌的环节,并没有结束整个循环。

1.4 循环嵌套

先展示一个简单的案例

#include<stdio.h>
int main()
{
    
    for (int i = 1; i<=2; i++)
    {
        for (int j = 1; j <= 3; j++)
        {
            printf("i=%d,j=%d\n", i, j);
        }
    }
    return 0;
}

程序运行的结果如下

这是一个简单的嵌套循环(或多重循环),可以看出大循环中嵌套了小循环,在这个循环中大循环重复了2次,小循环重复了6次。

易犯的错误

1.错误案例:并列for

sum=0;
item=1;
for(j=1;j<=i;j++)
item=item*j;
for(i=1;i<=100;i++)
sum=sum+item;

2.错误案例:初值混乱

sum=0,item=1;
for(j=1;j<=100;j++)
{
  for(i=1;i<=j;i++)
  item=item*i;
  sum=sum+item;
}  

3.错误案例:循环混乱,循环变量不能相同

sum=0;
for(i=1;i<=100;i++)
{ item=1;
  for(i=1;i<=j;i++)
  item=item*i;
  sum=sum+item;
}  

正确示范

sum=0;
for(j=1;j<=100;j++)
{
  item=1;
  for(i=1;i<=j;i++)
  item=item*i;
  sum=sum+item;
}  

学习体会

2 编程技巧总结(2分)

列举本周写代码过程,PTA题目或课本知识点的编程技巧。如
各种数列求和问题

2.1字符如何转数字

a=a-'0'

2.2大写字母如何转换为小写

ch=ch-'A'+'a'

2.3小写字母如何转换为大写

ch=ch-'a'+'A'

2.4图像打印问题

解题思路:

1.外循环控制行数i
2.内循环控制空格数k
3.内循环控制“*”个数j

打印正三角形

展示代码

打印菱形

方法一:
先按打印上半个正三角形,依照打印上半个三角形的方法,再用一个相似的for循环嵌套结构,打印下半个三角形
方法二:
利用菱形的对称性,应用abs()绝对值函数,统一上下两个三角形的打印规律
对比相对于方法一,方法二的代码量较少,相对优化

2.5四则运算

2.5.1解题思路

定义一个字符型变量ch,用于存放运算符,通过if语句实现
每次遇到

3.PTA实验作业(6分)

介绍下面3个题目的做法。

3.1 数列求和问题

3.1.1 流程图或伪代码介绍思路

3.1.2 代码截图

贴图展示代码,不要复制

3.1.3 PTA提交列表及说明



PTA显示格式错误,经过复制题目的输出样例,发现是输出的时候空格和题目所给的不相同,修改以后答案正确



总结
这道题总的的来说比较简单,只用到了单层循环,需要注意的时累加的时候sum的初值为0,而累乘的时候sum的初值为1,另外需要注意的是经过每一次循环需要累加的数从a,aa,aaa,aaaa...这个数据要怎么处理,我的处理方法是,经过观察,每个数的值都为上一个数的值乘于10再加上a,因此我引入了变量b来表示需要累加的数,每经过一次循环对b赋值一次,达到b=a,b=aa...的效果。


3.2 图形打印问题

3.2.1 数据处理

1.输入字母和高度
2.根据规律判断这一行每一列是空格或者字母,并输出
3.字母递增
4.重复2,3直到进入下半行(这里我把中间行归于上半行)
5.根据规律判断这一行每一列是空格或者字母,并输出
6.字母递减
7.重复5,6,直到行数等于高度时结束

3.2.2 代码截图





3.2.3 PTA提交列表及说明


第一次提交的代码展示

#include<stdio.h>
int main()
{
	char letter;
	letter = getchar();
	int height;//高度
	scanf("%d", &height);
	int column;//列数
	column = (height + 1) / 2 * 2 - 1;
	for (int i = 1; i <= height; i++)//控制行数
	{
		if (i <= (height + 1) / 2)//上半行
		{
			for (int j = 1; j <= column; j++)//控制列数
			{
				if (j >= (column + 1) / 2 - (i - 1) && j <= (column + 1) / 2 + (i - 1))
				{
					if (j >= (column + 1) / 2 - (i - 2) && j <= (column + 1) / 2 + (i - 2))
					{
						printf(" ");
					}
					else
					{
						printf("%c", letter);
					}
				}
				else if (j > (column + 1) / 2 + (i - 1))
				{
					break;
				}
				else
				{
					printf(" ");
				}
			}
			printf("\n");
			letter = letter + 1;
		}
		else//下半行
		{
			for (int j = 1; j <= column; j++)//控制列数
			{
				if (j >= (column + 1) / 2 - (height - i) && j <= (column + 1) / 2 + (height - i))
				{
					if (j >= (column + 1) / 2 - (height - i - 1) && j <= (column + 1) / 2 + (height - i - 1))
					{
						printf(" ");
					}
					else
					{
						printf("%c", letter);
					}
				}
				else if (j > (column + 1) / 2 + (height - i))
				{
					break;
				}
				else
				{
					printf(" ");
				}
			}
			printf("\n");
			letter = letter + 1;
		}
	}

return 0;
}

运行结果

可以看出在下半行的时候出现问题,仍然使用了字母的递增,然而此时应该是字母的递减,所以我把下半行的letter=letter+1修改为letter=letter-1
第二个明显的问题是我没有对‘Z’和“A”进行特殊处理,当遇到“Z”时要怎么加一?遇到“A”时怎么减一?我选择用分支结构单独列出这两种情况
运行结果

可以看出又出现了新的问题,由于上半行每次循环的时候都令字母向后移一位,进入下半行的时候,字母其实还是按照原来上半行的规律,输出了后一个字母,经过一次循环以后才开始进行递减的规律。

于是我想能不能用利用flag,在第一次进入循环时把字母变为原来的值,也就是让字母往前移一位,以此消除上半行最后一个循环字母往后移一位的影响
选取数据B 6进行调试

答案是正确的,那选取B 5试试看吧

明显又出了一些小问题,原来是因为如果高度是奇数时,从上半行到下半行字母不是不变的,而应该是减一,在这里应该用到分支结构处理

这次顺利通过了

自我反思
这段代码似乎有点冗长,有没有什么可以省略的地方?在这里我只用了两个控制循环的变量,通过看了超星视频里面的老师的讲解以后,我似乎有了新的思路,老师运用了3个控制循环的变量来分别控制行,输出“ ”,输出“*”,虽然变量增加了,但是代码变得简洁了不少,另外,老师运用字母的ASIC码和绝对值函数,巧妙的将上下三角形的规律统一,相当于少了一半的代码量,这里展示一下视频里老师的代码

运用老师的这种方法来做这道题,代码量应该就不会那么多了

3.3 自选一题,介绍printf调试如何检查错误

3.3.1 单步调试截图

有精力同学研究上传动态git图。可以动态展示单步调试过程。

可以看出程序没有进入过 printf("%d", sum); 这条语句

所以检查进入这条语句的时是否出现了问题,于是我在if的判断语句前造一个 printf,进行调试,来观察进入语句之前c和oldc的值变化

运行结果如下

可以看出最后一次进入循环的时候oldc的值为'+',c的值为'=',所以当然不会进入这条判断语句,因此我应该判断的是c是否等于‘=’,当c是等于‘=’时输出sum,代码修改如下:

运行结果如下:

显然这次还是出现了一些小问题,虽然输出了1+1的答案2,但是同时也多了几个不应该出现的ERROR,应该要想办法控制ERROR的输出,可以将输出的语句放在整个循环外进行,输出的情况只有两种sum或者ERROR因此可以引入flag来区分这两种情况,事实证明这种想法时正确的,详细代码见3.3.2 代码截图

3.3.2 代码截图



3.3.3 PTA提交列表及说明





在运算输出的时候出现问题,具体解决方法见3.3.1 单步调试截图

posted @ 2020-11-22 14:26  min小王  阅读(159)  评论(0编辑  收藏  举报