C语言程序设计第四次作业——选择结构(2)

一、改错题

题目:输出三角形的面积和周长,输入三角形的三条边a、b、c,如果能构成一个三角形,输出面积area和周长perimeter(保留2位小数);否则,输出“These sides do not correspond to a valid triangle”。
源程序(有错误的程序):
#include <stdio.h>
#include <math.h>
int main(void)
{
    double a,b,c;
    double area,perimeter,s;
    printf("Enter 3 sides of the triangle: ");
    scanf( "%lf%lf%lf",&a,&b,&c );

    if( a + b > c || b + c > a || a + c > b) 
    s = ( a + b + c ) / 2;
    area = sqrt( s * ( s - a ) * ( s - b ) * ( s - c );
    perimeter = a + b + c;
        printf("area = %.2f; perimeter = %.2f\n",area,perimeter);

    else
        printf("These sides do not correspond to a valid triangle\n");

    return 0;        
}
错误信息1:

1242864-20171031210321873-1125222407.png

错误原因:area = sqrt( s * ( s - a ) * ( s - b ) * ( s - c );的;前面少了一个半括号)
改正方法:在( s - c )的后面加上一个)
错误信息2:

1242864-20171031210959045-457791869.png

错误原因:if后面没有加上大括号{},else找不到可以与它匹配的if语句
改正方法:在if和else之间的语句用大括号括起来
错误信息3:

1242864-20171031212359138-1620839866.png

错误原因:if后的条件中不应用||的符号,写程序者混淆了||与&&的含义
改正方法:将if条件后中的||换成&&
单独改正:为了规范,将else后面的语句加上大括号
改正完毕输入样例,结果如下:

1242864-20171031213203248-1780577425.png
1242864-20171031213125560-829184985.png

与样例一致。再次输入其它数据:

1242864-20171031213747607-945938476.png
1242864-20171031213807795-1145373387.png
1242864-20171031213822763-1476020422.png

符合期望,认为改正完毕。
附上改正后的源代码:
#include <stdio.h>
#include <math.h>
int main(void)
{
    double a,b,c;
    double area,perimeter,s;
    printf("Enter 3 sides of the triangle: ");
    scanf( "%lf%lf%lf",&a,&b,&c );

    if( a + b > c && b + c > a && a + c > b) 
    {
        s = ( a + b + c ) / 2;
        area = sqrt( s * ( s - a ) * ( s - b ) * ( s - c ));
        perimeter = a + b + c;
        printf("area = %.2f; perimeter = %.2f\n",area,perimeter);
    }

    else
    {
        printf("These sides do not correspond to a valid triangle\n");
    }

    return 0;        
}

二、学习总结

1.if...else if... 语句以及switch语句的区别
①只需要判断一个条件的时候,if...else语句是最方便有效的,当判断条件很多的时候,我们就需要使用多个if语句或者if...else if语句或者switch case语句。

比如PTA选择结构(1)中的7-7题只有一个判断条件就可以用if...else语句:

#include <stdio.h>
int main()
{
    int N,a;
    scanf("%d",&N);
    a=N%5;
    if(a>=1 && a<=3)
    {
        printf("Fishing in day %d",N);
    }
    else
    {
        printf("Drying in day %d",N);
    }
    return 0;
}
②if...else if语句比多个if语句的效率要高,因为if...else if语句遇到满足的条件就会终止判断,而多个if语句则是无论是否满足条件都会继续判断下一个条件,这样如果有很多数据时效率就会低得多。

比如PTA选择结构(2)中的7-9中需要判断的条件很多就可以用if...else if语句来提高效率:

#include <stdio.h>
#include <math.h>
int main()
{
    double a,b,c,d,e,ans1,ans2,ans3,ans4,del1,del2;
    scanf("%lf %lf %lf",&a,&b,&c);
    d=(double)b*b-4*a*c;
    del1=sqrt(d);
    e=(double)-b/(2*a);
    if(a == 0 && b == 0 && c == 0)
    {
        printf("Zero Equation");
    }
    else if(a == 0 && b == 0 && c != 0)
    {
        printf("Not An Equation");
    }
    else if(d == 0)
    {
        printf("%.2f",e);
    }
    else if(a == 0)
    {
        printf("%.2f",(-c)/b);
    }
    else if(d > 0)
    {
        ans1=(-b+del1)/(a*2.0);
        ans2=(-b-del1)/(a*2.0);
        printf("%.2f\n%.2f\n",ans1,ans2);
    }
    else if(d < 0)
    {
        del2=sqrt(-d);
        if(b != 0)
        {
            ans3=-b/(2.0*a);
        }
        else
        {
            ans3=0;
        }
        ans4=del2/(2*a);
        printf("%.2f+%.2fi\n%.2f-%.2fi",ans3,ans4,ans3,ans4);
    }
    return 0;
}
③当判断条件较多的情况下,使用switch case语句的效率会高于使用if...else if语句。

比如PTA选择结构(2)中的7-3数据较多,就可以用swith case语句:

#include <stdio.h>
int main()
{
    int year,month,day,n;
    scanf("%d/%d/%d",&year,&month,&day);
    switch(month-1)
    {
        case 11:
            day=30+day;
        case 10:
            day=31+day;
        case 9:
            day=30+day;
        case 8:
            day=31+day;
        case 7:
            day=31+day;
        case 6:
            day=30+day;
        case 5:
            day=31+day;
        case 4:
            day=30+day;
        case 3:
            day=31+day;
        case 2:
            {
        
            if((year % 4==0 && year % 100!=0) || (year % 400==0))
            {
                day=29+day;
            }  
            else
            {
                day=28+day;
            }
        }
        case 1:
            day=31+day;
            break;
}
        printf("%d",day);
    return 0;
}
④各自使用的场景:
switch建议判断固定值的时候用

比如PTA选择结构(2)中的7-3题目中月份固定,就可以用swith case语句:

#include <stdio.h>
int main()
{
    int year,month,day,n;
    scanf("%d/%d/%d",&year,&month,&day);
    switch(month-1)
    {
        case 11:
            day=30+day;
        case 10:
            day=31+day;
        case 9:
            day=30+day;
        case 8:
            day=31+day;
        case 7:
            day=31+day;
        case 6:
            day=30+day;
        case 5:
            day=31+day;
        case 4:
            day=30+day;
        case 3:
            day=31+day;
        case 2:
            {
        
            if((year % 4==0 && year % 100!=0) || (year % 400==0))
            {
                day=29+day;
            }  
            else
            {
                day=28+day;
            }
        }
        case 1:
            day=31+day;
            break;
}
        printf("%d",day);
    return 0;
}
if建议判断区间或范围的时候用

比如PTA选择结构(1)中的7-1题目中就需要判断n的大小,就可以用if语句:

#include <stdio.h>
int main()
{
    int n,a;
    scanf("%d",&n);
    if(n<0)
    {
        a=-1;
    }
    else if(n==0)
    {
        a=0;
    }
    else
    {
        a=1;
    }
    printf("sign(%d) = %d",n,a);
    return 0;
}
用switch能做的,用if都能做,但反过来则不行

比如PTA选择结构(1)中的7-6题目中要求判断两边之和大于第三边的要求就不可以用switch语句:

#include <stdio.h>
#include <math.h>
int main()
{

    int a,b,c;
    scanf("%d %d %d",&a,&b,&c);
    if(a<b+c && b<a+c && c<a+b)
    {
        double s,area,perimeter;
        s=(a+b+c)/2.00;
        area=sqrt(s*(s-a)*(s-b)*(s-c));
        perimeter=a+b+c;
        printf("area = %.2f; perimeter = %.2f",area,perimeter);
    }
    else
    {
        printf("These sides do not correspond to a valid triangle");
    }
    return 0;
}

参考资料http://www.cnblogs.com/wankun/p/4989831.html

2.其他内容总结
(1)我们需要掌握的:①字符常量②字符串常量和字符变量③switch语句④字符型数据的输入输出⑤复合语句
(2)我们在写程序是需要注意的:①在if和else后面总要用到{ },即使只有一条语句。②当使用switch语句时为了保证各分支的正确执行,必须用break语句跳出。③“%c”输入时,空格字符和“转义字符”作为有效字符输入。在“%c”前加一个空格,忽略缓冲区内的空白字符(空格、回车、tab键)。

三、实验总结

1.成绩转换
(1)题目

本题要求编写程序将一个百分制成绩转换为五分制成绩。转换规则:

  • 大于等于90分为A;
  • 小于90且大于等于80为B;
  • 小于80且大于等于70为C;
  • 小于70且大于等于60为D;
  • 小于60为E。
(2)流程图

1242864-20171031234454560-436009114.png

(3)源代码
#include <stdio.h>
int main()
{
    int grade;
    scanf("%d",&grade);
    switch(grade/10)
    {
        case 10:
        case 9:
        printf("A\n");
        break;
        case 8:
        printf("B\n");
        break;
        case 7:
        printf("C\n");
        break;
        case 6:
        printf("D\n");
        break;
        default:
        printf("E\n");
    }
    return 0;
}
(4)实验分析

问题1:首次输入switch(grade/10)时忘记除以10了,导致程序不对

原因:做题不细心

解决办法:grade后面加上/10

(5)本题PTA提交列表

1242864-20171031235949826-1934498539.png

2.三角形判断
(1)题目

给定平面上任意三个点的坐标(x1 ,y1)、(x2,y2)、(x3,y3),检验它们能否构成三角形。

(2)流程图

1242864-20171102105533451-1317245253.png
1242864-20171102105732341-1555129987.png

(3)源代码
#include <stdio.h>
#include <math.h>
int main()
{
    double d,f,g,s,A,L,x1,x2,x3,y1,y2,y3;
    scanf("%lf %lf %lf %lf %lf %lf",&x1,&y1,&x2,&y2,&x3,&y3);
    d=sqrt((y2-y1)*(y2-y1)+(x2-x1)*(x2-x1));
    f=sqrt((y3-y1)*(y3-y1)+(x3-x1)*(x3-x1));
    g=sqrt((y3-y2)*(y3-y2)+(x3-x2)*(x3-x2));
    if(d+f>g && d+g>f && f+g>d)
    {
        L=d+f+g;
        s=(double)L/2;
        A=sqrt(s*(s-d)*(s-f)*(s-g));
        printf("L = %.2f, A = %.2f",L,A);
    
    }
    else
    {
        printf("Impossible");
    
    }
    return 0;
}
(4)实验分析

问题1:

1242864-20171102110611873-2025868142.png

原因:用了开根的数学符号sqrt,但头文件却没有包含数学函数的头文件

解决办法:在第二行加上#include <math.h>

(5)本题PTA提交列表

1242864-20171102143322841-2108591520.png

3.两个数的简单计算器
(1)题目

本题要求编写一个简单计算器程序,可根据输入的运算符,对2个整数进行加、减、乘、除或求余运算。题目保证输入和输出均不超过整型范围。

(2)流程图

1242864-20171102145223076-1530781458.png

(3)源代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a,b,d;
    char c;
    scanf("%d %c %d",&a,&c,&b);
    if(c == '+')
    {
        d=a+b;
    }
    else if(c == '-')
    {
        d=a-b;
    }
    else if(c == '*')
    {
        d=a*b;
    }
    else if(c == '/')
    {
        if(b != 0)
        {
            d=a/b;
        }
        else 
            {
            printf("输入错误!"); 
            exit(0);
            }
        }
    else if(c == '%')
    {
        d=a%b;
    }
    else
    {
        printf("ERROR");
        exit(0);
    }
    printf("%d",d);
    return 0;
}
(4)实验分析

错误1:程序测试时,无论如何输入正确的数据都显示ERROR

原因:在输入字符c时将%c写成了%d

解决办法:将%d改成%c

错误2:在提交的时候结果求余不对

原因:读题不仔细,没有看到要求求余,导致没有求余的程序

解决办法:补上求余的程序

(5)本题PTA提交列表

1242864-20171102152321076-1093540430.png

4.求一元二次方程的根
(1)题目

本题目要求一元二次方程的根,结果保留2位小数。

(2)流程图

1242864-20171102164909716-123622476.png

(3)源代码
#include <stdio.h>
#include <math.h>
int main()
{
    double a,b,c,d,e,ans1,ans2,ans3,ans4,del1,del2;
    scanf("%lf %lf %lf",&a,&b,&c);
    d=(double)b*b-4*a*c;
    del1=sqrt(d);
    e=(double)-b/(2*a);
    if(a == 0 && b == 0 && c == 0)
    {
        printf("Zero Equation");
    }
    else if(a == 0 && b == 0 && c != 0)
    {
        printf("Not An Equation");
    }
    else if(d == 0)
    {
        printf("%.2f",e);
    }
    else if(a == 0)
    {
        printf("%.2f",(-c)/b);
    }
    else if(d > 0)
    {
        ans1=(-b+del1)/(a*2.0);
        ans2=(-b-del1)/(a*2.0);
        printf("%.2f\n%.2f\n",ans1,ans2);
    }
    else if(d < 0)
    {
        del2=sqrt(-d);
        if(b != 0)
        {
            ans3=-b/(2.0*a);
        }
        else
        {
            ans3=0;
        }
        ans4=del2/(2*a);
        printf("%.2f+%.2fi\n%.2f-%.2fi",ans3,ans4,ans3,ans4);
    }
    return 0;
}
(4)实验分析

问题1:读题时没读懂复数根的意思,导致这部分程序写了错,错了改,改了还错!

原因:不明白复数根是什么东西,不能很好的运用公式

解决办法:通过上网查阅资料,请教同学,弄懂了应该如何求复数根,才将程序写入

问题2:第一次编写这个程序时,没有考虑到定义的字母需要有含义,而是随便拿了一个英文字母就用

原因:没有这方面的意识

解决办法:又重新定义了一些变量使用的字母,使它代表了数字的意义

问题3:写程序时没考虑到a=0这种情况

原因:数学学得不行,还需要努力啊!

解决办法:考虑a=0的情况并将这种情况写进程序里

(5)本题PTA提交列表

1242864-20171102153100935-709339220.png

四、博客互评

我的评论同学的博客链接
程晓磊

http://www.cnblogs.com/8426224ll/p/7769227.html

评论内容:

①老铁,PTA提交列表是每个题单独的提交PTA提交的截图,不是最后总的提交;

②raptor的流程图太模糊,不清楚,建议下次放大并且只截图流程部分,不要把软件框也截上,这样流程图会好很多;

③分析错误要把错误和原因解决方法讲详细,单写个结果不对,运行xxx出错,部分正确之类的除了你没人能看明白;

④不客气!

郭玉霖

http://www.cnblogs.com/HBQ521/p/7765641.html

评论内容:

①改错改完以后样例全部正确后,建议再输入两组与样例不一样的数据来检测程序的正确与否;

②实验分析方面说的太潦草,“实验部分正确”,“没按题目要求做”,部分正确是哪的错?没按题目要求做是没按哪个要求做,应该说清楚,让读你博客的人一目了然;

③不客气!

怪人、

http://www.cnblogs.com/LLIU/p/7765845.html

①改错改完以后样例全部正确后,建议写出改成后的源程序并且再输入两组与样例不一样的数据来检测程序的正确与否;

②实验分析“没问题”,其实我也没问题,但是老师说了,没问题也得写,没办法,老铁,写点吧,没有困难咱们得创造困难;

③PTA提交列表是每个题单独的提交PTA提交的截图,不是最后总的提交;

④不客气!


这是我此次的博客作业

祝评论我博客的人一辈子不脱发、不长痘、不失眠、不犯口腔溃疡、不犯鼻炎、不抑郁、一夜暴富!

转载于:https://www.cnblogs.com/yjy751522356/p/7773477.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值