C語言程序設計第六次作業——循環結構(2)


C語言程序設計第六次作業——循環結構(2)

  之前的博客園圖片沒處理好,對大家說一聲抱歉。希望大家能夠多多指出我的錯誤,我來認真修改 ^ - ^ !。

(1)改錯題

序列求和:輸入一個正實數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:

錯誤原因 :while后面的括號沒有加“;”。

改正方法:在while后面加上分號“;”。

編譯正確,繼續執行

錯誤信息 2:

錯誤原因:答案不正確,輸入和輸出用了%f

改正方法:在輸入和輸出的時候把“%f”改成“%lf”和“%.6lf”。

結果發現答案還是不正確:

錯誤原因:回頭發現do while里面的語句運行不下去了就換一種格式來寫

改正方法:把第一個程序改成第二個,如下:

do{
            item = 1/ n;
            s = s + flag * item;  
            flag = -flag;
            n = n + 3;
        }while( item < eps);
do 
	{
		item=flag*1.0/(3*n-2);
		s+=item;
		flag=-flag;
		n++;
	}
	while(fabs(item)>eps);

**因為在源代碼中出現了數學函數fabs(),所以要用include<math.h>。

運行結果:運行正確!

附上正確的源代碼:
 #include<stdio.h>
#include <math.h>
    int main()
    {
        int flag,n;
        double eps,item,s;
    
        printf("Input eps: ");
        scanf("%lf",&eps);
        flag = 1;
        s = 0;
        n = 1;
        do 
	    { 
		item=flag*1.0/(3*n-2);
		s+=item;
		flag=-flag;
		n++;
	    }
	while(fabs(item)>eps);
        printf( "s = %.6lf\n",s);
        return 0;
    }

(二)學習總結

1.語句while(1)和for( ; ; )是什么意思?,如何保證這種循環能正常執行?

while(1)相當於while(ture)里面的循環條件一直為真,一直循環下去。

保證這種循環正常執行在后面加一個判斷並且為假,就直接跳出循環;或者加一個break;也可以跳出循環,保證這個循環能夠正常運行。

for( ; ; )表示為死循環。

因為for后的圓括號中,第一個分號前的內容是執行第一次循環前執行的,第二個分號前的內容是每次執行前都要判斷的(如果該處表達式的值為真,那么執行循環體,如果為假,那么就跳出循環體),第二個分號后的內容是每執行完一次循環體后執行的。

在循環體中使用break跳出循環體。

2.一般情況下,設計循環結構時,使用for、while、do while三種語句都可以,並且三種語句可以相互轉換,但是,在某些特定情況下,我們應該優先選擇某種語句來快速實現循環設計。如果有如下情況:

(1)循環次數已知

(2)循環次數未知,但循環條件在進入循環時明確

(3)循環次數未知,且循環條件在進入循環時未知,需要在循環體中明確

針對上面三種情況,分別采用什么循環語句實現比較好?對每種情況,用我們完成的兩次循環結構作業中的題目加以說明。

①用for的循環結構來寫。例如:
循環結構(1)中 7-2 統計學生平均成績與及格人數, 7-3 奇偶分家 7-8 找出最小值,給出7-3的源程序:

#include <stdio.h>
int main(void)
{
int N,i,n,a = 0,b = 0;
scanf("%d",&n);
for(i = 0;i < n;i++)
{
   scanf("%d",&N); 
   if(N % 2 == 0)
 {
    a++;
 }
   else
 {
    b++;
 }
 
}
  printf("%d %d",b,a);
  return 0; 
}

②可以用while和do while的循環結構來寫。例如:循環結構(2)中 7-5爬動的蠕蟲,循環結構(1)中 7-4 到底是不是太胖了 給出7-5的源程序:

#include <stdio.h>
int main(void)
{
	int N,U,D,head=1,time=0;
	scanf("%d %d %d",&N,&U,&D);
	while(1) 
	{
		head+=U;
		time++;
		if(head>N)break;
			head-=D;
			time++;
	}
	printf("%d",time);
	return 0;
}

③可以用do while的循環結構來寫。例如:循環結構(2)中 7-1 求給定精度的簡單交錯序列部分和 7-3 求奇數和,給出7-3的源程序:

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

3.有如下問題:輸入一批學生成績,以-1作為結束,計算學生的平均成績。
要求分別用for語句、while語句、do while語句三種循環語句實現,並說明你認為哪種形式更合適?

循環次數未知,且循環條件在進入循環時未知,需要在循環體中明確,所以我覺得用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;
}

輸出結果:

這倆個源程序看上去沒什么倆樣,但是不同的地方就是第一個用的是break,而第二個用的是continue。結果一個輸出1,一個輸出25,因為第一個就執行一次s=s+n,而s為0,n為1,當第一次輸入1的時候就直接跳出循環就進行s=s+n,所以最后輸出1;

而第二個流程圖用continue倆控制循環條件,他進行判斷后不會跳出而是直接進行下一個,並且把能整除2的數過濾掉,所以最后輸出的是25。

(三)實驗總結

(1) 題目

7-1 求給定精度的簡單交錯序列部分和

(2) 流程圖



(3) 源代碼

#include<stdio.h>
#include<math.h>
int main(void)
{
   	int dom,flog;
	double eps,sum,t;
	flog=1;
	dom=1;
	sum=0;
	scanf("%lf",&eps);
    do 
	{
		t=flog*1.0/(3*dom-2);
		sum+=t;
		flog=-flog; /*讓這個值改變*/
		dom++;
	}
	while(fabs(t)>eps);
	printf("sum = %.6lf",sum);
	
	return 0;
 } 

(4) 實驗分析:

問題1:

第一次寫的時候有while的形式是用一下格式:

 while(fabs(x) > eps)
        {
           t=flog*1.0/(3*dom-2);
		   sum+=t;
		   flog=-flog; /*讓這個值改變*/
		   dom++;
        }

但是輸出的結果答案錯誤,這個問題糾結了很長時間。該程序需要先執行一次然后再進行循環,如果用while的形式就不能保證進行一次,所以該格式不能保證。我們要用do while的格式來寫。

do 
	{
		t=flog*1.0/(3*dom-2);
		sum+=t;
		flog=-flog; /*讓這個值改變*/
		dom++;
	}
	while(fabs(t)>eps);
問題2:答案錯誤

原因:while括號里面的條件判斷錯誤

解決方法:把"<="改成">"。


答案正確:

(5)本題PTA提交列表

(1) 題目:

7-2 猜數字游戲

(2) 流程圖


(3) 源代碼

#include<stdio.h>
int main()
 {
   int key, n;
   scanf("%d %d",&key,&n);  /*輸入倆個數*/
   int i;
   int m;
   int flag = 0;  /*定義一個數*/
   for (i = 1;i <= n;i ++)
     {
       scanf("%d",&m); /*再次輸入一個數*/
       if (m < 0)
       break;
       if (m > key)
         printf("Too big\n");
        if (m < key)
          printf("Too small\n");
        if (m == key)
           {
              if (i == 1)
               {
                  flag = 1;  /*為假,跳出*/
                  printf("Bingo!\n");
                  break;
               }
              if (i == 2 || i == 3)
                {
                  flag = 1; /*為假,跳出*/
                  printf("Lucky You!\n");
                  break;
                }
              if (i > 3)
                {
                  flag = 1; /*為假,跳出*/
                  printf("Good Guess!\n");
                  break;
                }


           }
        }
        if (flag == 0) /*為真,輸出*/
        printf("Game Over\n");
     return 0;
 }

(4) 實驗分析

錯誤信息:一開始輸入產生隨機數,用了數學函數rand(),但是結果輸出錯誤。

原因:理解題意錯誤,不用函數就可以,直接輸入倆個數再進行循環就可以。

需要注意的:循環結束可以用break來實現。在本題需要定義一個量flag=0,如果后面的跟前面所定義的相等就判斷為真,如果不相等就判斷為假,並且在break的條件下進行跳出進行下一步的運算。

(5)本題PTA提交列表

(1) 題目

7-3 求奇數和

(2) 流程圖


(3) 源代碼

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

(4) 實驗分析

問題 : 用 if--for的形式輸入結果總是部分正確,例如下面的錯誤源程序

#include <stdio.h>
int main()
{
   int n,i,s,sum;
   sum=0;
   scanf("%d",&n);
   i=0;
   for(i=0;i<n;i++)
   {
      scanf("%d",&s);
      if(s<0)
     {
        break;
     }
      else
     {
        if(s%2!=0)
       {
         sum=sum+s;
       }
     }
   }
    printf("%d",sum);
}

原因:該程序不能用if for的形式來寫,它需要先循環一次,然后再進行循環。給出正確的源程序:

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

(5)本題PTA提交列表

(四)博客互評

針對移動、淫領四妓夜物 的博客園:
(1).實驗總結寫的很認真,值得我們學習!老鐵,沒毛病!繼續加油
針對郭玉霖的博客園:
(1).在學習總結的第三個題文字與圖片應該空一格,這樣看起來比較舒服。
(2).在實驗分析的時候應該把問題用截圖截下來並且圈出來,這樣別人才能知道你哪兒多了條件或者哪兒漏了條件。
針對ShizukaRi的博客園
(1).在改錯題應該把錯誤的源程序給出來並且改正給出正確的。
(2).學習總結只能用很認真來形容,向你學習,可以看出你學的很好。
(3).實驗總結的第二個流程圖看着有點別扭,希望以后盡量截圖好一點,大家能夠更好的看清楚。

^ - ^歡迎大家來評論我的博客園!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM