1. 程式人生 > >C語言程序設計第六次作業

C語言程序設計第六次作業

-1016 你在 快速實現 無限 沒有 部分 輸入 需要 優先

(一)改錯題
序列求和:輸入一個正實數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:
技術分享圖片

錯誤原因1:do...while語句中while需要在後面加分號
改正方法1:在while後面加上分號

錯誤信息2:
技術分享圖片

錯誤原因2:n為整型變量,所以輸出為0或1
改正方法2:將1改為1.0,強制轉換

錯誤信息3:
技術分享圖片

錯誤原因3:while中應為循環開始的語句,而題中給出的為循環結束的語句
改正方法3:將item < eps改為item >= eps

錯誤信息4:
技術分享圖片

錯誤原因4:題中定義的eps為double格式
改正方法4:將%f改為%lf
改正後與輸出樣例相符
給出改正後的代碼

#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)表示無限循環,當括號裏的數字為1時,表示為真,執行循環語句,當括號裏的數字為0時,表示為假,跳出循環。
for(;;)表示已知循環次數時用for語句,表達式1是賦初值,表達式2是判斷循環條件,表達式3是步長。先執行表達式1,再進行表達式2,接著執行循環體,然後執行表達式3,再進行表達式2,再執行循環體,然後再回到表達式3,直到表達式2不成立,跳出循環。所以for(;;)也為無限循環。若程序中沒有停止標誌,則一直執行下去,在程序中加入break,則停止循環。

2.一般情況下,設計循環結構時,使用for、while、do while三種語句都可以,並且三種語句可以相互轉換,但是,在某些特定情況下,我們應該優先選擇某種語句來快速實現循環設計。如果有如下情況:
(1)循環次數已知
(2)循環次數未知,但循環條件在進入循環時明確
(3)循環次數未知,且循環條件在進入循環時未知,需要在循環體中明確
針對上面三種情況,分別采用什麽循環語句實現比較好?對每種情況,用我們完成的兩次循環結構作業中的題目加以說明。
當循環次數已知時,用for語句循環,先判斷後執行;當循環次數未知,但給出了循環條件結束時的條件時,用while語句循環,也是先判斷後執行;當循環體至少執行一次時,用do...while語句循環,先執行後判斷。
for語句:以PTA循環結構(一)第一題為例,題目為:計算序列 1 + 1/3 + 1/5 + ... 的前N項之和。
這道題用for比較方便,題中明確給出了循環次數,給次數賦初值,明確了循環條件和步長,就可以得出答案。
while語句:以PTA循環結構(二)第七題為例,題目為:對方不想和你說話,並向你扔了一串數…… 而你必須從這一串數字中找到“250”這個高大上的感人數字。
這道題就是典型的用while語句,不知道循環多少次,但知道循環結束的條件,當輸入的數字第一次遇到250時,循環結束。
do...while語句:以PTA循環結構(二)第六題為例,題目為:掉入陷阱的數字。
這道題的要求就是當這一次的輸出的結果和上一次的輸出結果相同時輸出,所以需要先循環一次,再進行判斷,直到輸出。所以用do...while是合適的。

3.有如下問題:輸入一批學生成績,以-1作為結束,計算學生的平均成績。
要求分別用for語句、while語句、do while語句三種循環語句實現,並說明你認為哪種形式更合適?
(1)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
        {
            break;
        }
    }
            average = sum/i;
    printf("%f",average);

    return 0;
}

(2)while語句程序:

#include <stdio.h>
int main(void)
{
    int grade = 0,sum = 0,i;
    double average = 0.0;
    i = 1;
    while(grade != -1)
    {
        scanf("%d",&grade);
        sum = sum + grade;
        i++;
    }
    average = (sum+1)/(double)(i-1);
    printf("%f",average);
    return 0;
 } 

(3)do...while語句程序:

#include <stdio.h>
int main(void)
{
    int grade = 0,i = 0,sum = 0;
    double average = 0.0;
    do
    {
        scanf("%d",&grade);
        sum = sum + grade;
        i++;
    }
    while(grade != -1);
    average = (sum+1)/(double)(i-1);
    printf("%f",average);

    return 0;
}

我覺得for語句循環比較簡單易懂,並且方便,while語句和do...while語句很相似,不同的地方是判斷循環進行的條件位置不同。但while語句比較簡潔,不需要循環重復很多遍。while語句在題目輸入-1時,會將-1也算進去,需要特別說明。綜上,我覺得for語句更加合適。

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;
}  

結果如下:
技術分享圖片

兩個程序唯一的不同就是第一個用break控制循環語句,第二個用continue控制循環語句。break控制就是跳出循環體,執行循環外的語句,而第一個程序在輸入2時就已經跳出循環了,所以答案為s=1;continue控制是結束本次循環,跳出本次未執行的循環語句,再執行下一次循環語句,直到結束。這個語句求的是1-10的奇數和,所以答案為s=25。

(三)實驗總結
本次實驗總結,完成循環結構(2)中的1、2、3題。
第一題:求給定精度的簡單交錯序列部分和
(1)題目:計算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... 直到最後一項的絕對值不大於給定精度eps

(2)流程圖:
技術分享圖片
技術分享圖片
技術分享圖片

(3)源代碼:

#include <stdio.h>
#include <math.h>
int main()
{
    double eps,item,S = 0;
    int denominator = 1,flag = 1;
    item = 1.0;
    scanf("%lf",&eps);
    if(eps >= item)
    {
        S = 1.0;
    }
    while(fabs(item) > eps)
    {
        item = flag *1.0 / denominator;
        S = S + item;
        flag = -flag;
        denominator = denominator + 3;
    }
    printf("sum = %.6f",S);
    return 0;
}

(4)實驗分析:
問題1:結果最後輸出為0.000000
原因1:item定義為double類型,flag*1為0
解決方法1:將1改為1.0

問題2:這個程序用while語句是錯誤的
原因2:這個程序必須執行一次才能循環
解決方法2:將while語句改為do...while語句

(5)本題PTA提交列表
技術分享圖片

第二題:猜數字遊戲
(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,a;
    i = 1;
    scanf("%d %d",&num,&N);
    do
    {
        scanf("%d",&a);
        if(a < 0)
        {
            printf("Game Over");
            break;
        }
        else if(a == 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(a > num)
        {
            printf("Too big\n");
        }
        else if(a < num)
        {
            printf("Too small\n");  
        }
        i++;
    }
    while(num != a);
    return 0;
}

(4)實驗分析:
問題1:當輸入的數字大於次數時,結束程序,輸出結果
原因1:沒有在輸入的數字和次數相等時結束
解決方法1:將i>N改為i>=N

問題2:當輸入負數時仍可輸出
原因2:沒有在if語句後面加break
解決方法2:在第13行加上break
(5)本題PTA提交列表
技術分享圖片

第三題:求奇數和
(1)題目:本題要求計算給定的一系列正整數中奇數的和。

(2)流程圖:
技術分享圖片

(3)源代碼:

#include<stdio.h>
int main(void)
{
    int n = 0,sum = 0;
    do
    {
        scanf("%d",&n);
        if(n % 2 == 1)
        {
            sum = sum+n;
        }
        else
        {
        
        }
    }
    while(n > 0);
    printf("%d",sum);
    return 0;
 } 

(4)實驗分析:
問題1:一開始用的while語句,但是不能很好理解
原因1:本題更應該用do...while語句
解決方法1:把循環改為do...while無限循環

(5)本題PTA提交列表
技術分享圖片

(四)博客互評
幕曦:改錯題步驟清楚,並且實驗分析簡潔清楚,非常細致,還附上了改錯完成後的源代碼,這一點值得我學習
(http://www.cnblogs.com/yjy751522356/p/7838296.html)

侯冠達:改錯題我感覺有一個你沒有改出來,就是保留六位小數那裏,但是實驗總結和學習總結你完成的很好,思路很清晰,需要向你學習。
(http://www.cnblogs.com/HGD980425/p/7837319.html)

lucky you:改錯題條理清楚,過程簡潔明了,但是在實驗分析中的源代碼部分,最後是用markdown格式,具體如何操作,老師已經在群裏說過了,群文件裏有,希望改正。
(http://www.cnblogs.com/LYFRRS/p/7854183.html)

風離你在:本次博客園作業完成迅速,思路也很清晰,格式很規範。
(http://www.cnblogs.com/GX201701-/p/7828562.html)

C語言程序設計第六次作業