一、改錯題
題目:輸出三角形的面積和周長,輸入三角形的三條邊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:
錯誤原因:area = sqrt( s * ( s - a ) * ( s - b ) * ( s - c );的;前面少了一個半括號)
改正方法:在( s - c )的后面加上一個)
錯誤信息2:
錯誤原因:if后面沒有加上大括號{},else找不到可以與它匹配的if語句
改正方法:在if和else之間的語句用大括號括起來
錯誤信息3:
錯誤原因:if后的條件中不應用||的符號,寫程序者混淆了||與&&的含義
改正方法:將if條件后中的||換成&&
單獨改正:為了規范,將else后面的語句加上大括號
改正完畢輸入樣例,結果如下:
與樣例一致。再次輸入其它數據:
符合期望,認為改正完畢。
附上改正后的源代碼:
#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)流程圖
(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提交列表
2.三角形判斷
(1)題目
給定平面上任意三個點的坐標(x1 ,y1)、(x2,y2)、(x3,y3),檢驗它們能否構成三角形。
(2)流程圖
(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:
原因:用了開根的數學符號sqrt,但頭文件卻沒有包含數學函數的頭文件
解決辦法:在第二行加上#include <math.h>
(5)本題PTA提交列表
3.兩個數的簡單計算器
(1)題目
本題要求編寫一個簡單計算器程序,可根據輸入的運算符,對2個整數進行加、減、乘、除或求余運算。題目保證輸入和輸出均不超過整型范圍。
(2)流程圖
(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提交列表
4.求一元二次方程的根
(1)題目
本題目要求一元二次方程的根,結果保留2位小數。
(2)流程圖
(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提交列表
四、博客互評
我的評論同學的博客鏈接
程曉磊
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提交的截圖,不是最后總的提交;
④不客氣!
這是我此次的博客作業
祝評論我博客的人一輩子不脫發、不長痘、不失眠、不犯口腔潰瘍、不犯鼻炎、不抑郁、一夜暴富!