C博客作业01--分支、顺序结构

第一次C博客作业


Q0.展示PTA总分


Q1.本章学习总结

1.1 学习内容总结

  • 数据的输入和输出
    • 列表了比较常见的几种数据类型;
    • 有小数的在输出中可用如%.3f表示保留3位小数,也可以在前面加数字表示占的位数(找不到一个好的表示的词了)如%6.3f;
    • 字符常量在使用时要记得加单引号。
数据类型 在scanf()中表示 在printf()中表示 备注
int %d %d 整型变量,计算时只保留整数
long %ld %ld 长整型变量,现在和int基本一致?
float %f %f 单精度浮点数,可输入小数,但不常用
double %lf %f/%lf 输出时默认带6位小数
char %c %c 也可用getchar()输入,但注意两者都只能读入一个字符
  • 数据处理中会运用的数学函数
    • 开平方根:sqrt(x),x为被开方的数
    • 取绝对值:fabs(x),x为被取绝对值的数
    • 求幂:pow(x,n),x为底数,n为幂(e为底数则用exp(x),x为幂)
    • 取e为底的对数:log(x)
    • 注意:多次使用这些函数会影响程序的效率,有时候可以通过其他办法来避免使用这些函数。
  • 分支结构(if/else-if/switch)
    • 虽然三者都能进行分支但也有很多不同。
      1.if-else需要判断每个分支。而switch只会进入满足条件分支,程序效率高。
      2.若要对变量进行判断时,switch语句只能判断一个变量,而if语句可以用与和或号判断多个变量。
      3.if语句可以判断变量是否在区间内,而switch只能判断变量的值是否为某个常量。
int main()
{
    if (表达式1)    //若表达式1为真则执行语句1,否则跳过
    {
        语句1;
    }

    if (表达式1)    //若表达式1为真,执行语句1并跳出该else-if结构
    {
        语句1;
    }
    else if (表达式2)   //若表达式1为假,则直接执行到这里,并与表达式2进行判断,为真执行语句2并跳出结构
    {
        语句2;
    }
    else   //若表达式1、2都不符合则执行语句3
    {
        语句3;
    }

    /*要注意else与前面最近的if匹配,不是只看大括号的位置!!*/

    return 0;
}
int main()
{
    switch (表达式) //取该表达式的值与case中的常量表达式对比
    {
    case 常量表达式1:语句1; break;   //若表达式的值=常量表达式1的值执行语句1并跳出switch语句
    case 常量表达式2:语句2; break;   //若表达式的值=常量表达式2的值执行语句2并跳出switch语句
        ...
    default:语句n; break;   //若表达式的值不符合上面任何一个,执行语句n
    }

    /* default在switch语句中并不是必须的。
    break也不是必须的,但要注意在不用break语句的情况下,若表达式与常量表达式2的值相等,会执行语句2和后面所有的语句!*/

    return 0;
}
  • 循环结构(for/while/do-while)
    • for一般用于知道循环次数的情况,while和do-while多用于循环次数不确定时,当然确定时也可以用。
    • 当第一次进入循环就不满足条件时,for和while都不会执行循环,而do-while会执行一次。
    • 部分情况下三种循环可以相互代替。
int main()
{
    for (表达式1; 表达式2; 表达式3)   //表达式1赋予初值,只执行一次;表达式2用于判断循环条件,为真执行循环体语句,否则结束循环;执行循环体语句后执行表达式3,然后回到表达式2
    {
        循环体语句;    //需要被多次执行的内容
    }
    
    return 0;
}
int main()
{
    while (表达式1)   //每次执行循环前与表达式1判断,为真则执行循环,为假则跳出循环执行接下来的内容
    {
        循环语句1;
    }

    do
    {
        循环语句2;
    } while (表达式2);   //先执行一遍循环语句,再与表达式2判断,为真继续循环,为假跳出循环

    /*所以无论如何,do-while循环一定会执行一次*/
    
    return 0;
}

1.2 本章学习体会

  • 因为前面部分自己有先自学过,在上课之前觉得问题不是很大,但实际在课堂和作业中会发现有些细节是之前根本没注意到的
  • 个人觉得PTA/课堂派的部分作业可以在课堂上进行讲评
  • 总结下来最重要的还是自己动手打代码,有些不会的必须得上手才能解决掉
  • 然后代码量的话……嗯…因为我的PTA是9月19号才开通20号开始打题的,所以这两周打了很多题,就不统计了吧……?(我觉得挺多的)
    C博客作业01--分支、顺序结构_第1张图片

Q2.PTA实验作业

2.1 计算天数

2.1.1 数据处理

  • 数据表达
    • int year:用户输入的年份
    • int month:用户输入的月份
    • int day:用户输入的日期
    • int total:用于统计总天数
  • 数据处理
    • 先用switch语句对month进行判断,按照输入的月份将total加上已经经过月份的天数
    • 再对year进行判断是否为闰年,若为闰年且月份大于2,则天数+1
    • 最后将total加上day即为所求天数

2.1.2 代码截图

C博客作业01--分支、顺序结构_第2张图片

2.1.3 本题可扩展功能

我的代码和该题的要求并不严谨,若输入的日期不正确,如输入32号或输入2019/02/29仍然可以输出正确的日期,该题可扩展先判断日期是否合法,若合法再输出天数
C博客作业01--分支、顺序结构_第3张图片

C博客作业01--分支、顺序结构_第4张图片

2.1.4 PTA提交列表及说明


虽然PTA提交列表里一遍过,但是在VS里面还是遇到一些问题的

Q1.纠结输入01、05这样子前面带0的数据怎么处理
A1.询问之后了解了int类型数据会自己处理掉前面的0

Q2.闰年判断错误
A2.判断顺序搞错,在能被4整除但不能被100整除这句话上加上括号就过了


2.2 二进制转十进制

2.2.1 数据处理

  • 数据表达
    • long num10:用于记录换算后的数
    • int count:记录输入了几位数(从0开始)
    • int flag:记录是否出现了不合法的数
    • int i:用于数组
    • char ch[100]:定义一个长度为100的数组储存输入的字符
  • 数据处理
    • 运用循环和数组将用户输入的每个字符存起来,遇到回车时停止
    • 询问得知可以用这个方法转换进制:从最后一位开始算,依次列为第0、1、2...位,第n位的数(0或1)乘以2的n次方,得到的结果相加就是答案
    • 将数组中的字符转换成数字,运用上面的方法转化

2.2.2 代码截图

C博客作业01--分支、顺序结构_第5张图片

2.2.3 本题可扩展功能

该题的功能已经较完善了,我就增添了一个十进制转二进制的功能(限定正数)
C博客作业01--分支、顺序结构_第6张图片

C博客作业01--分支、顺序结构_第7张图片

2.2.4 PTA提交列表及说明

C博客作业01--分支、顺序结构_第8张图片

Q1.多个1测试点过不了
A1.将代码中scanf改成了getchar,用字符来做这道题

Q2.第一个测试点过不了
A2.这个卡了很久,一直测试都没问题,还去问了老师测试数据是什么,然后发现因为我选择的数据正好都是从左往右读都一样(忽略首部的0)所以都没测出来错误。。
知道测试数据以后发现我的代码是从左往右读,而上面的方法是要求从右往左读(scanf就没有这个问题),所以一直出错。。最终用上了数组来倒序。。肯定有更简单的方法,只是我想不到。。


2.3 于龙遇见日期,又哭了

2.3.1 数据处理

  • 数据表达
    • int x,y,z:储存输入的三个数字
    • int year,month,day:等待xyz给它们赋值,用于输出
    • char a,b:只用于处理输入时的奇形怪状的符号
  • 数据处理
    • 先判断x y z的大小,将最大的赋给年份
    • 然后按顺序,第一个在1-12间的赋值给月份(如果x是年份但在12以内也排除)
    • 两个值赋给年份月份了,剩下的就是日期
    • 最后在输出结果前做一堆判断。。

2.3.2 代码截图

C博客作业01--分支、顺序结构_第9张图片

C博客作业01--分支、顺序结构_第10张图片

2.3.3 本题可扩展功能

这题我真的想不到怎么扩展它了
只能说一下自己对这道题的感受了
首先就是题目的文字量很大,读了好多遍才知道他想要干啥
这道题难的不是对年月日的赋值和比大小什么的,而是对非法日期的判断真的很烦(还有测试点还看不出哪个错哪个对)
但是只是抢分的话这题目标还是比较明确的,几个比较简单的非法可以先写(有次我写完了分还没有只写了几行多)
还有就是代码量的问题,这题需要的代码行数比较多,进行改动的话一行行过去还是很麻烦的,有可能扫完一遍还剩个地方没改到
所以在这题中F11测试非常好用,添加监视一行行走下去,错误发现还是比较快的
但这道题总体还是没有偏离我们学的if-else分支,主要还是考察分支结构,if的条件能否写清楚,能否读通题目意思以及运气好不好能不能猜到测试点是什么

2.3.4 PTA提交列表及说明

(这题在test01题库中我看不到自己的提交情况?)

Q1.符号读不进去!
A1.刚开始做题时机房电脑的VS我还没有改SDL,用不了scanf,导致我用scanf_s的情况下中间的两个符号一直读不进去。所以以后打开VS第一件事还是得把SDL检查关了!

Q2.2月29号的判断!
A2.这个比较麻烦,很多与号和或号还有括号连接,绕的有点晕,又是少括号又是打错与或号的……

Q3.这个测试点是什么啊我怎么都过不去!
A3.看运气10个测试点对应着从它题目中的7个到他下面输入样例的3个(不说还真不知道)当时错着改着突然就过了也是有点惊讶……还是希望老师在这些地方能加点提示…
回归正题,要在没有31号的月份却输入了31号、闰年、没有按照顺序输入等这种小问题一个个排查,才能一步步改到正确答案


Q3.阅读代码

我选择了poj 1972 Dice Stacking

C博客作业01--分支、顺序结构_第11张图片

C博客作业01--分支、顺序结构_第12张图片

  • 代码功能
    • 首先输入骰子的组数,然后输入该组骰子的个数,再输入骰子每面的数字
    • 输出该组骰子叠起来后的一整面数字的和最大的值(上面骰子的底面与其下面骰子的顶面点数相同,骰子可以在底部确定的情况下平面旋转)
  • 代码优点和可以学习的地方
    • 自定义了函数getmax()寻找这颗骰子的在这面的最大值
    • 使用二维数组保存了每组骰子的每面数字,在后续使用中方便
    • 使用嵌套循环计算和,外部循环先初始化,内部循环再叠加,十分清楚
    • 使用了max()函数,比较一遍变量ans与max的大小再保存更大的数,不需要再繁琐的使用if-else语句
    • for(scanf("%d",&T);T;T--)的写法十分新奇,可以自定义初始值,并且该for循环里中间的表达式又相当于T>0
    • 开头的#include< cstdio>,#include< cstring>,#include< algorithm>和我们现在使用的都不同。经查阅似乎cstdio是将stdio.h的内容用C++头文件的形式表示出来(我们使用的stdio.h则是C标准函数库中的头文件),而cstdio中的函数又是在名称空间std中的,故在后面加上了using namespace std; (我也有点晕)

你可能感兴趣的:(C博客作业01--分支、顺序结构)