標籤:語句 賦值 計算 說明 這一 一個 為什麼 www. 輸入
(一)改錯題
序列求和:輸入一個正實數eps,計算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精確到最後一項的絕對值小於eps(保留6位小數)。
輸入輸出範例:
Input eps:1E-4
s = 0.835699
來源程式(有錯誤的程式)
#include<stdio.h>int main(){ int flag,n; double eps,item,s; printf("Input eps: "); scanf("%f",&eps); flag = 1; s = 0; n = 1; do{ item = 1/ n; s = s + flag * item; flag = -flag; n = n + 3; }while( item < eps) printf( "s = %f\n",s); return 0;}
錯誤資訊1:
錯誤原因:
在執行do while迴圈時,while語句後要有分號。
改正方法:
在while語句後加上分號。
修改後編譯正確。
運行結果:
發現運行結果不正確,修改程式。
錯誤資訊2:
錯誤原因:
在定義變數時,eps是double類型的,所以輸入時不是輸入%f。
改正方法:
把%f改為%lf。
運行結果:
發現運行結果還是不對,繼續修改程式。
錯誤資訊3:
錯誤原因:
根據題目要求可知,不應該是item
1.語句while(1)和for(;;)是什麼意思?,如何保證這種迴圈能正常執行?
while()括弧裡是判斷條件該條件是否為真,while(1)意思就是條件一直為真,所以while(1)是一個無限迴圈。for迴圈裡有三個語句,第一個語句是指派陳述式,只執行一次,第二個語句是是判斷語句,判斷該語句是真還是假,第三個語句一般是給指派陳述式加1。但for(;;)中三個語句為空白,說明判斷條件一直為真,所以也是一個無限迴圈。
想要保證這種迴圈能正常進行,可以在滿足題目條件的情況下,加一個break語句,讓程式跳出,結束程式。
2.一般情況下,設計迴圈結構時,使用for、while、do while三種語句都可以,並且三種語句可以相互轉換,但是,在某些特定情況下,我們應該優先選擇某種語句來快速實現迴圈設計。如果有如下情況:
(1)迴圈次數已知
(2)迴圈次數未知,但迴圈條件在進入迴圈時明確
(3)迴圈次數未知,且迴圈條件在進入迴圈時未知,需要在迴圈體中明確
針對上面三種情況,分別採用什麼迴圈語句實現比較好?對每種情況,用我們完成的兩次迴圈結構作業中的題目加以說明。
(1)迴圈次數已知,想要快速實現迴圈設計,可以優先選擇for語句。
例如:迴圈結構(1)中的第一題求奇數分之一序列前N項和,用for語句比較方便。
# include <stdio.h>int main (void){ int N,i; double sum; scanf("%d",&N); for(i=1,sum=0;i<=N;i++) { sum=sum+1.0/(2*i-1); } printf("sum = %.6f",sum); return 0;}
(2)迴圈次數未知,但迴圈條件在進入迴圈時明確,用while語句,可以快速實現迴圈設計。
例如:迴圈結構(2)中的第一題求給定精度的簡單交錯序列部分和,用while語句合適。
# include <stdio.h># include <math.h>int main (){ int flag,d; double eps,item,sum; item=1,flag=1,sum=0,d=1; scanf("%lf",&eps); if(item<=eps) { sum=1; } while(fabs(item)>eps) { item=flag*1.0/d; sum=sum+item; d=d+3; flag=-flag; } printf("sum = %.6f",sum); return 0;}
(3)迴圈次數未知,且迴圈條件在進入迴圈時未知,需要在迴圈體中明確,用do while 語句。
例如:迴圈結構(2)中的第三題求奇數和。
# include <stdio.h>int main(){ int n,sum; sum=0; do { scanf("%d",&n); if(n<0) { break; } else if(n%2==1) { sum=sum+n; } }while(n>0); printf("%d",sum); return 0;}
3.有如下問題:輸入一批學產生績,以-1作為結束,計算學生的平均成績。
要求分別用for語句、while語句、do while語句三種迴圈語句實現,並說明你認為哪種形式更合適?
for語句:
# include <stdio.h>int main() { int i,number; double sum,average,grade; sum=0,number=0; for(;;) { scanf("%lf",&grade); if(grade==-1) { break; } else { sum = sum+grade; number++; } } average = sum/number;printf("%.2f",average); return 0;}
while語句:
# include <stdio.h>int main(){ int number; double grade,sum,average; sum=0,number=0; scanf("%lf",&grade); while(grade!=-1) { sum=sum+grade; number++; scanf("%lf",&grade); } average=sum/number; printf("%.2f",average); return 0;}
do while 語句:
# include <stdio.h>int main (){ int number; double sum,average,grade; sum=0,number=0; scanf("%lf",&grade); do { sum=sum+grade; number++; scanf("%lf",&grade); }while(grade!=-1); average=sum/number; printf("%.2f",average); return 0;}
我認為用while語句寫更合適,因為該迴圈迴圈次數未知,而且迴圈條件在進入迴圈時明確。
4.運行下面程式,輸入1到10,結果分別是什嗎?為什嗎?
(1)
#include<stdio.h>int main(){ int n,s,i; s = 0; for(i = 1; i <= 10; i++) { scanf("%d",&n); if(n % 2 == 0) break; s = s + n; } printf("s = %d\n",s); return 0;}
迴圈結果:
(2)
#include<stdio.h>int main(){ int n,s,i; s = 0; for(i = 1; i <= 10; i++) { scanf("%d",&n); if(n % 2 == 0) continue; s = s + n; } printf("s = %d\n",s); return 0;}
迴圈結果:
運行結果顯示(1)中s=1,(2)中s=25。兩者產生區別的原因是:(1)中n%2==0語句後邊跟著break語句,當輸入n=2時,程式就會直接跳出,所以s就是等於上一步的1。而(2)中n%2==0後邊跟著continue語句,continue語句是表示只跳出這一步,然後繼續執行下一步。
(三)實驗總結
本次實驗總結,完成迴圈結構(2)中的1、2、3題。
1.求給定精度的簡單交錯序列部分和
(1)題目
本題要求編寫程式,計算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... 直到最後一項的絕對值不大於給定精度eps。
(2)流程圖
(3)原始碼
# include <stdio.h># include <math.h>int main (){ int flag,d; double eps,item,sum; item=1,flag=1,sum=0,d=1; scanf("%lf",&eps); if(item<=eps) { sum=1; } while(fabs(item)>eps) { item=flag*1.0/d; sum=sum+item; d=d+3; flag=-flag; } printf("sum = %.6f",sum); return 0; }
(4)實驗分析
問題:
在PTA上提交作業時,出現了部分正確。
原因:
沒有考慮當輸入的的第一項item就小於等於給定精度eps時會出現的情況。
解決辦法:
向同學詢問,修改程式。
(5)本題PTA提交列表
2.猜數字遊戲
(1)題目
猜數字遊戲是令遊戲機隨機產生一個100以內的正整數,使用者輸入一個數對其進行猜測,需要你編寫程式自動對其與隨機產生的被猜數進行比較,並提示大了(“Too big”),還是小了(“Too small”),相等表示猜到了。如果猜到,則結束程式。程式還要求統計猜的次數,如果1次猜出該數,提示“Bingo!”;如果3次以內猜到該數,則提示“Lucky You!”;如果超過3次但是在N(>3)次以內(包括第N次)猜到該數,則提示“Good Guess!”;如果超過N次都沒有猜到,則提示“Game Over”,並結束程式。如果在到達N次之前,使用者輸入了一個負數,也輸出“Game Over”,並結束程式。
(2)流程圖
(3)原始碼
#include <stdio.h>int main(){int num,N,i,n;i = 1;scanf("%d %d",&num,&N);do{scanf("%d",&n);if(n < 0){printf("Game Over");break;}else if(n == num && i <= N){if(i == 1){printf("Bingo!");break;}else if(i <= 3){printf("Lucky You!");break;}else if(i > 3 && i <= N){printf("Good Guess!");break;}}else if(i > N){printf("Game Over");break;}else if(n > num){printf("Too big\n");}else if(n < num){printf("Too small\n"); }i++;}while(num != n);return 0;}
(4)實驗分析
問題1:
運行時只能得出一組資料,是太大了還是太小了,得不出猜的次數。
原因:
剛開始用while語句寫的,沒有搞清邏輯關係。
解決辦法:
向同學詢問,最後改成了do while語句,結果正確。
(5)本題PTA提交列表
3.求奇數和
(1)題目
本題要求計算給定的一系列正整數中奇數的和。
(2)流程圖
(3)原始碼
# include <stdio.h>int main(){ int n,sum; sum=0; do { scanf("%d",&n); if(n<0) { break; } else if(n%2==1) { sum=sum+n; } }while(n>0); printf("%d",sum); return 0;}
(4)實驗分析
問題:
在用while語句或者for語句寫是,不正確。
原因:
因為該程式在進入迴圈時次數未知,而且迴圈條件不太明確。
解決辦法:
改成了do while語句。
(5)本題PTA提交列表
(四)部落格互評
每個同學至少評論三篇其他同學的部落格作業,依次列出你所評論的部落格地址。對於同學對你的部落格作業提出的問題,應積極進行回答,存在的錯誤應及時改正。希望大家能夠在互評的過程中取長補短,共同進步。
1.王映丹:http://www.cnblogs.com/windsky-1999/p/7838107.html
王映丹同學,在改錯題中思路清晰,能讓人一眼看出錯誤在哪。
學習總結第二題中如果能把例子的原始碼給出會更好。
整個作業思路很清晰,值得學習。
2.luckyyou:http://www.cnblogs.com/LYFRRS/p/7854183.html
改錯題中,思路很清晰。
在學習總結第二題中如果能夠把舉的例子的原始碼寫出來,可能會好點。
實驗分析中的原始碼最好是用markdown的格式寫,不要截屏。
3.程曉磊:http://www.cnblogs.com/8426224ll/p/7847221.html
改錯題中,思路清晰,哪裡有錯誤,還做了標記。
在實驗分析中,還給出了錯誤的來源程式,能和正確的來源程式做對比,值得學習。
PTA提交列表中錯誤的整體比較少,值得學習。
C語言程式設計第六次作業——迴圈結構(2)