(一)改錯題
1.序列求和:輸入一個正實數eps,計算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精確到最后一項的絕對值小於eps(保留6位小數)。
輸入輸出樣例:
Input eps:1E-4
s = 0.835699
①錯誤信息:
錯誤原因:do.....while后面沒有加分號;
改正方法:
②錯誤信息:
錯誤原因:item 頂一頂為double類型,但是1/n 為int類型,格式不對
改正方法:
③錯誤信息:
錯誤原因:while語句里面是循環結束語句,而題中給出的是循環跳出的語句
改正方法:
④錯誤信息:
錯誤原因:題中eps定義的是double格式
改正方法:
附上改完之后正確的代碼:
#include<stdio.h>
int main()
{
int flag,n;
double eps,item,s;
printf("Input eps: ");
scanf("%lf",&eps);
flag = 1;
s = 0;
n = 1;
do{
item = 1.0/ n;
s = s + flag * item;
flag = -flag;
n = n + 3;
}while( item >= eps);
printf( "s = %f\n",s);
return 0;
}
(二)學習總結
1.語句while(1)和for(;;)是什么意思?,如何保證這種循環能正常執行?
答:while(1)是無限循環,括號里的數字當為0是便不運行,非0即可成功運行。for(;;)表達式1是初值,表達式2是判斷,表達式3是步長,先做表達式1,然后做表達式2,接着做循環體,然后再做表達式3,再回到做表達式2,然后做循環體,接着做表達式3,直到表達式2不成立退出。所以for(;;)也為無限循環。這兩種循環的意思是等價的。當與語句中沒有停止語句時這兩種循環會一直循環下去,如果語句中出現類似於break語句的話,那么這個循環就會停止跳出。
2.一般情況下,設計循環結構時,使用for、while、do while三種語句都可以,並且三種語句可以相互轉換,但是,在某些特定情況下,我們應該優先選擇某種語句來快速實現循環設計。如果有如下情況:
(1)循環次數已知
(2)循環次數未知,但循環條件在進入循環時明確
(3)循環次數未知,且循環條件在進入循環時未知,需要在循環體中明確
針對上面三種情況,分別采用什么循環語句實現比較好?對每種情況,用我們完成的兩次循環結構作業中的題目加以說明。
答: 當循環語句已知時用for語句比較好,先判斷后執行,但是當循環次數未知時 ,但是給出了條件控制時,用while語句比較好,也是先判斷后執行,當循環體至少要循環一次時便用do while語句,這個和前面的兩個不一樣,是先執行后判斷。
我們以PTA的循環結構(一)中的第一題為例,題目為:求奇數分之一序列前N項和,此題便用for語句比較方便,明確循環的次數,選定一個初值,明確了結束條件,此題便可以得出答案,而像PTA的循環結構(二)中的第三題,題目為: 求奇數和, 此地便用到了while循環語句,這道題讓你求你輸入的數中的奇數的和,我們來細想一下,你並不知道要循環多少次,所以用到了while(1)這個無限循環,類似的題目還有第七題:尋找250這個數字,做題時並不知道要循環多少次,,這就是典型的先循環在判斷,而類似於像PTA的循環結構(二)中的第六題,題目為:掉入陷阱的數字, 當你輸入一個自然數時,你要先鎖定他的各個位數,然后再求和,他的要求是當輸出的這一次的數和上一次和一樣便輸出,所以你需要先循環一次,再開始進行判斷,直到輸出為止。像這種都未知 的情況下就用do...while 語句。
3.有如下問題:輸入一批學生成績,以-1作為結束,計算學生的平均成績。
要求分別用for語句、while語句、do while語句和無限循環四種循環語句實現,並說明你認為哪種形式更合適?
答:(一)for語句的程序如下:
#include<stdio.h>
int main(void)
{
int grade=0,sum=0,i=0;
double average=0.0;
for(;;)
{
scanf("%d",&grade);
if(grade!=-1)
{
sum = sum +grade;
i++;
}
else if(grade==-1)
{
break;
}
}
average = sum / i;
printf("%f",average);
return 0;
}
(二)while語句的程序如下:
#include<stdio.h>
int main(void)
{
int grade=0,sum=0,i=0;
double average=0.0;
i=0;
while(grade!=-1)
{
scanf("%d",&grade);
sum = sum + grade;
i++;
}
average = (sum+1) / (double)(i-1);
printf("%f",average);
return 0;
}
(三)do...while語句的程序如下:
#include<stdio.h>
int main(void)
{
int grade=0,sum=0,i=0;
double average=0.0;
i=0;
do
{
scanf("%d",&grade);
sum = sum + grade;
i++;
}
while(grade!=-1) ;
average = (sum+1) / (double)(i-1);
printf("%f",average);
return 0;
}
(四)無限循環的程序如下:
#include<stdio.h>
int main(void)
{
int grade=0,sum=0,i=0;
double average=0.0;
while(1)
{
scanf("%d",&grade);
if(grade!=-1)
{
sum = sum +grade;
i++;
}
else if(grade==-1)
{
break;
}
}
average = sum / i;
printf("%f",average);
return 0;
}
關於這四種的程序形式我感覺for語句和無限循環語句的程序比較相似和易懂,而且很方便,對於while語句和do while語句的程序也比較相似,但是這兩種程序的有點是簡潔,少了for語句和無線循環語句的繁瑣的過程,但是while語句的弊端是最后以-1作為結束的時候,程序會算上-1,從而導致程序結果有誤,所以我們需要略微在輸出的時候做一下改正,如果題目改為輸入一個負數跳出循環的話,while語句和do while語句就沒有辦法運行了。綜合而言,我覺得for語句和無線循環語句更加好。
4.運行下面程序,輸入1到10,結果分別是什么?為什么?
(1)結果為如圖所示:
(2)結果為如圖所示:
這兩個程序的唯一區別就是第一個語句用的break循環控制語句,而第二個語句用的是continue循環控制語句,這兩個循環控制語句的區別就是break是結束循環並且跳出這個循環語句,然后執行循環之外的語句,這個語句當輸入2是就跳出循環了,而continue則是結束本次循環,跳出循環體中尚未執行的語句,繼續下一次的循環,直到這個正常結束為止,這個語句求得是1-10的奇數的和,所以這兩個程序的答案不一樣。
(三)實驗總結
- 求給定精度的簡單交錯序列部分和
(1)題目
本題要求編寫程序,計算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... 直到最后一項的絕對值不大於給定精度eps。
(2)流程圖
(3)源代碼
#include<stdio.h>
#include<math.h>
int main()
{
double eps,sum = 0.0,n = 1.0,a = 0.0;
int i = 1;
scanf("%lf",&eps);
do
{
a = (1.0/i) * pow(-1,n+1);
sum = sum + a;
i = i + 3;
n++;
}
while(fabs(a) > eps);
printf("sum = %.6f",sum);
return 0;
}
(4)實驗分析:
問題1:這個程序用while語句的話是錯誤的
原因:它必須要執行一次循環才能正常進行
解決辦法:把while語句換為do....while語句即可
(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 a = 0,N = 0,i = 0,b = 0;
scanf("%d%d",&a,&N);
for(i = 1;i <= N;i++)
{
scanf("%d",&b);
if(b < 0 )
{
printf("Game Over");
break;
}
else if(b > a)
{
printf("Too big\n");
}
else if(b < a)
{
printf("Too small\n");
}
else if(a == b)
{
if(i == 1)
{
printf("Bingo!");
break;
}
else if(i <= 3 && i > 1)
{
printf("Lucky You!");
break;
}
else if(i > 3)
{
printf("Good Guess!");
break;
}
break;
}
if(i >= N)
{
printf("Game Over");
break;
}
}
return 0;
}
(4)實驗分析:
問題1:輸出的形式與題中要求不符
原因:沒看清題
解決辦法:在三個語句中加入!
問題2:當你數入的數字超過次數之后才結束程序
原因:在相等得時候沒算結束了
解決辦法:把i>N改為i>=N即可
(5)本題PTA提交列表
3.求奇數和
(1)題目
本題要求計算給定的一系列正整數中奇數的和
(2)流程圖
(3)源代碼
#include<stdio.h>
int main()
{
int a,sum = 0;
while(1)
{
scanf("%d",&a);
if(a%2!=0&&a>0)
{
sum+=a;
}
else if(a<=0)
{
break;
}
}
printf("%d",sum);
return 0;
}
(4)實驗分析:
本道題個人認為沒有什么難點,熟悉無限循環即可。
(5)本題PTA提交列表
(四)博客互評
李曉曉http://www.cnblogs.com/Reloaded/p/7825734.html
侯冠達http://www.cnblogs.com/HGD980425/p/7837319.html
郭展旭http://www.cnblogs.com/1234569ss/p/7824423.html