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 单步调试截图