---恢復內容開始---
#C語言程序設計第六次作業——循環結構(2) ##(一)改錯題 ###序列求和:輸入一個正實數eps,計算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精確到最后一項的絕對值小於eps(保留6位小數)。 輸入輸出樣例: Input eps:1E-4 s = 0.835699 ### #include 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;
}
對源程序進行編譯,發現錯誤:
在使用“do .. while”時,“while”后面應該加上“;”,源程序中缺少“;”,經改正,繼續進行編譯:
程序無錯誤,運行程序,輸入樣例值1:
發現與應有的結果不相符,仔細檢查程序發現:flag應該為double類型的,while后面的條件應為“fabs(item) > eps”,如圖:
#include<stdio.h>
#include<math.h>
int main()
{
int flag;
double eps,item,s,n;
printf("Input eps: ");
scanf("%lf",&eps);
flag = 1;
s = 0;
n = 1;
do{
item = 1/ n;
s =s + flag * item;
flag = -flag;
n = n + 3;
}while( fabs(item) > eps );
printf( "s = %.6f\n",s);
return 0;
}
輸入樣例,結果和答案一致。
(二)學習總結
1.語句while(1)和for(;;)是什么意思?,如何保證這種循環能正常執行?
①語句while(1)表示的是無限循環,-該循環想要停止時只要在判斷條件后面加上“break;”,即可在達到此條件后結束循環;
②for(;;)語句表示的有限的循環,往往會有一個固定的N值作為它的最大限制條件,for語句中的判斷語句不可以省略,其他兩個語句可在擴號內省略。
2.一般情況下,設計循環結構時,使用for、while、do while三種語句都可以,並且三種語句可以相互轉換,但是,在某些特定情況下,我們應該優先選擇某種語句來快速實現循環設計。如果有如下情況:
(1)循環次數已知
(2)循環次數未知,但循環條件在進入循環時明確
(3)循環次數未知,且循環條件在進入循環時未知,需要在循環體中明確
針對上面三種情況,分別采用什么循環語句實現比較好?對每種情況,用我們完成的兩次循環結構作業中的題目加以說明。
①循環條件已知:
例題:循環結構(1)求奇數分之一序列前N項和(計算序列 1 + 1/3 + 1/5 + ... 的前N項之和。)
對於該循環的編寫應該使用“for”循環,“for”循環用於循環次數已知的循環程序編寫,而且改程序比較簡單使用“for”更加合適。
②循環次數未知,但循環條件在進入循環時明確:
例題:循環結構(2) 猜數字游戲,該循環體可能一次都不執行,所以應該使用while語句,符合whlie語句可能一次也不執行的特點。
循環結構(2)求給定精度的簡單交錯序列部分和,該循環體至少執行一次,所以選用“do ..whlie”更合適。
③循環次數未知,且循環條件在進入循環時未知,需要在循環體中明確
例題:循環結構(2)韓信點兵,由於條件無法再循環體外給出所以應該使用無限循環whlie(1)編寫合適。
3.有如下問題:輸入一批學生成績,以-1作為結束,計算學生的平均成績。
要求分別用for語句、while語句、do while語句和無限循環四種循環語句實現,並說明你認為哪種形式更合適?
#include<stdio.h>
int main()
{
int n,i,s,x;
scanf("%d",&n);
s = 0;
for(i=1;n<0;i++)
{
s +=n;
x = x/(double)i;
}
return 0;
}
#include<stdio.h>
int main()
{
int n,i,x,s;
s = 0;
i = 1;
scanf("%d",&n);
while(n>0)
{
s +=n;
x = x/(double)i;
i +=1;
}
return 0;
}
#include<stdio.h>
int main()
{
int n,i,x,s;
s = 0;
i = 1;
scanf("%d",&n);
do
{
s +=1;
x =x/(double)n;
i +=1;
}while(n>0) ;
return 0;
}
我認為用“do..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;
}
執行程序一得到:
執行程序二得到:
造成結果不相同的原因:程序一中為(if(n % 2 == 0)break; ),break為終止程序,所以當讀到2時已經可以被2整除,此時程序已經結束,則s=1;程序二中為(if(n % 2 == 0) continue; ),continue表示的是當讀到被2整除的數時不再執行下面的語句,回到循環開頭繼續循環,則s=25。
(三)實驗總結
1.求給定精度的簡單交錯序列部分和
(1)題目:本題要求編寫程序,計算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... 直到最后一項的絕對值不大於給定精度eps。
(2)流程圖:
(3)源代碼:
#include<stdio.h>
int main()
{
double n,m,x,eps,sum;
scanf("%lf",&eps);
m =1;
n =1;
while(1)
{
x = m/n;
sum +=x;
if(x>=-eps&&x<=eps)break;
m = -m;
n +=3;
}
printf("sum = %.6f",sum);
}
(4)實驗分析
該題用無限循環編寫需注意break該放置的位置。
(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 i,n,a,N;
scanf("%d",&i);
scanf("%d",&N);
while(n<=N)
{
scanf("%d",&a);
n=n+1;
if(a<0)
{
printf("Game Over\n");
break;
}
if(i>a)
{
printf("Too small\n");
}
else if(i<a)
{
printf("Too big\n");
}
else
{
if(n==1)
{
printf("Bingo!\n");
break;
}
else if(n>1&&n<=3)
{
printf("Lucky You!\n");
break;
}
else if(n>3&&n<=N)
{
printf("Good Guess!\n");
break;
}
else
{
printf("Game Over\n");
break;
}
}
}
}
(4)實驗分析:
這個題的信息量可以說是見過最大的一次,讀題時只要遺漏一點就可能導致多出編寫錯誤,對於這種情況比較復雜的題目,一定要好好順一下思路,否則會出現多次編寫依然錯誤的情況。
(5)本題PTA提交列表
3. 求奇數和
(1)題目:本題要求計算給定的一系列正整數中奇數的和。
(2)流程圖:
(3)源程序:
#include<stdio.h>
int main()
{
int x,sum;
sum = 0;
while(1)
{
scanf("%d",&x);
if(x<=0)break;
if(x>0)
{
if(x%2!=0)
{
sum +=x;
}
else
{
sum = sum;
}
}
}
printf("%d",sum);
}
(4)實驗分析:
都一次編寫時忽略了可以為0的條件,屬於讀題不細致。
(5)本題PTA提交列表:
(四)博客園互評:
對王映丹同學博客園作業的評價(http://www.cnblogs.com/windsky-1999/p/7838107.html):
這位同學將改錯題中錯誤所在處的截圖顯示出來,使錯誤更加的詳細,而且在實驗總結的時候描述的很清晰。
對蕊薏同學博客園作業的評價(http://www.cnblogs.com/123ruike/p/7851176.html):
這位同學在描寫三種循環的不同之處時運用了具體實例,還附有程序圖,使人更加容易明白三者的區別。
對DiRt同學博客園作業的評價(http://www.cnblogs.com/dsy7777777/p/7856453.html):
該同學的插圖給人看上去並不是很整齊,建議程序圖方面可以用Markdown本身的格式。