1. 程式人生 > 實用技巧 >【實驗3】~C語言分支語句和迴圈語句程式設計應用~

【實驗3】~C語言分支語句和迴圈語句程式設計應用~

  • 實驗任務一

 1 // 一元二次方程求解
 2 // 重複執行, 直到按Ctrl+Z結束
 3 //
 4 #include <math.h>
 5 #include <stdio.h>
 6 int main() {
 7     float a, b, c, x1, x2;
 8     float delta, real, imag;
 9     printf("Enter a, b, c: ");
10     while(scanf("%f%f%f", &a, &b, &c) != EOF) {
11         if(a == 0
) 12 printf("not quadratic equation.\n\n"); 13 else { 14 delta = b*b - 4*a*c; 15 if(delta >= 0) { 16 x1 = (-b + sqrt(delta)) / (2*a); 17 x2 = (-b - sqrt(delta)) / (2*a); 18 printf("x1 = %.2f, x2 = %.2f\n\n", x1, x2); 19 }
20 else { 21 real = -b/(2*a); 22 imag = sqrt(-delta) / (2*a); 23 printf("x1 = %.2f + %.2fi, x2 = %.2f - %.2fi\n\n", real, 24 imag, real, imag); 25 } 26 } 27 printf("Enter a, b, c: "); 28 } 29 return 0; 30 }

執行結果:

分析程式:運用必要條件a!=0 , delta分虛實情況討論。作為判斷條件使用,是程式的骨架。

      運用寬度格式字元輸入方法,限制保留小數位。

      運用!=EOF迴圈,實現多組輸入。


  • 實驗任務二

 1 // 生成N個0~9之間的隨機整數,並列印輸出
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <time.h>
 5 #define N 5
 6 int main() {
 7     int x, n;
 8     srand(time(0)); // 以當前系統時間作為隨機種子
 9     n = 0;
10     do {
11         n++;
12         x = rand()%10; // 生成一個0~9之間的隨機整數
13         printf("%3d", x);
14     }while(n<N);
15     printf("\n");
16 return 0;
17 }

執行結果:

程式分析:這串17行程式碼中用到了“函式”,及使用函式的必要條件“預處理與標頭檔案”

     因為還沒學習,在這裡我自己實踐了一下函式的普通用法

 1 #include <stdio.h>
 2 
 3 int max(int a, int b){
 4     if(a > b){
 5         return a;
 6     }else{
 7         return b;
 8     }
 9 }
10 int main(){
11     int a,b,c;
12     scanf("%d%d",&a,&b);
13     c = max(a,b);
14     printf("%d",c);    
15     return 0;
16 }

     函式是一個很方便的東西。

     do-while語句和while語句是差不多的用法,但while就感覺多了個if的感覺,這個程式我也可以改成while:

 1 // 生成N個0~9之間的隨機整數,並列印輸出
 2 //do-while 改 while
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 #include <time.h>
 6 #define N 5
 7 int main() {
 8     int x, n;
 9     srand(time(0)); // 以當前系統時間作為隨機種子
10     n = 0;
11     while(n<N){
12         n++;
13         x = rand()%10; // 生成一個0~9之間的隨機整數
14         printf("%3d", x);
15     }
16     printf("\n");
17 return 0;
18 }

執行結果:

      所以dowhile就是“先do再while”。


  • 實驗任務三

第一回,我得到了錯誤答案。

 1 #include<stdio.h>
 2 #include<math.h>
 3 
 4 int main(){
 5     int a=101,i,sum=0;
 6     int max=sqrt(a);
 7     for(int a=101;a<=200;a++){
 8         for(int i=2;i<=max;i++){
 9             if(a%i!=0){
10                 if(i==max){
11                     printf("%5d",a);
12                     sum++;                    
13                 }
14                 else 
15                     continue;
16             }
17             else{
18                 break;
19             }
20         }
21     }
22     printf("101-200間共有%d個素數",sum);
23     return 0;
24 }

執行結果:

      沒錯,多出來了幾個數,那就是可以開平方的數(121、169),但我很好奇為什麼144沒算在裡面。

修正之後:

 1 #include<stdio.h>
 2 #include<math.h>
 3 
 4 int main(){
 5     int a=101,i,sum=0,r;
 6     for(int a=101;a<=200;a++){
 7         int max=sqrt(a);
 8         for(int i=2;i<=max;i++){
 9             r=a%i;
10             if(r==0){
11                 break;
12             }
13             else{
14                 continue;
15             }
16         }
17         if(r!=0){
18             printf("%5d",a);
19             sum++;
20         }
21         
22     }
23     printf("\n101-200間共有%d個素數",sum);
24     return 0;
25 }

執行結果:

      沒錯,我把列印函式從最初的那個程式碼的最後一步if判斷是不是質數中拿了出來,放在了最外面篩選質數的for迴圈中。

總結:我的演算法寫得還比較稚嫩,跟著感覺走是我的程式碼風格 。我還不熟練,視野略窄,做了上步就想立刻達成下步,沒有跳躍思維。

   It is always true that Practice makes perfect .


  • 實驗任務四

實驗任務四看著就是一道簡單的、像OJ上的題,但是我在自主編寫時有些夠嗆。

弄了很久,最後受到同學們的熱心幫助,合力做出來了。

最終答案:

 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 int main(){
 5     char s[16];
 6     printf("Enter a number: ");    
 7     
 8     while(scanf("%s",s)!=EOF){
 9         printf("new number is: ");
10         int i=0;        
11         int len;
12         len = strlen(s);
13         
14         while(i<=len-1){
15             int a=s[i];
16             if(a%2!=0){
17                 printf("%c",s[i]);
18                 i++;
19             }
20             else {
21                 i++;
22                 continue;
23             }
24         }
25         printf("\n\nEnter a number: ");    
26     }
27 
28 return 0;
29 }

執行結果:

程式思路:因為我用的是字串的方法去做這道題,所以呼叫字串中的奇數字符與最終按順序列印輸出幾乎不用考慮。也有同學是用long方法去做的,可能我這個方法就方便在這裡。

     即:輸入字元→掃描字元→呼叫字元→列印字元。

下面是我的struggle process:

初始版本:

可見,這個程式真是千瘡百孔、漏洞百出、不堪入目,但錯誤是最好的老師不是嗎?我把他記錄下來的意義……

  • i=1沒有初始化
  • scanf了%d賦給字串s
  • printf了%d的字元s[i]

這是目前可見的錯誤,我開始聯合同學們一起討論更正。

1、“scanf後面沒有&”

  結果是字串可以不用&賦值的。之後同學的告知並且我上網查找了一下

  “scanf物件是陣列名不需要&,陣列名本身是陣列首個單位的地址。

2、“把scanf的%d換成%s”

  雖然沒有解決輸出結果完全錯誤的問題,但是好歹數值變了,這就說明了我原本是有問題的!

3、“大家討論了while語句中的輸入問題”

  1)同學共享了方案“gets()!=NULL”

    但結果我發現不能把這個方案放到while迴圈的括號裡。

   即while(s=getchar()!=EOF) 是行不通的。大概是賦值語句之後不能加上關係運算符的問題。

  2)在末尾加一句getchar()

    這是符合邏輯的,因為迴圈末尾有getchar,迴圈條件有輸入scanf。可以實現多組輸入。但是我第二次輸入再輸出結果是空白這個問題的來源不是這個…

4、“i=0放在迴圈裡面”

  這是一個關鍵的問題!我把i=0放在了開頭。雖然說第一遍迴圈時沒有哪個方法動了i的值。但是從第二遍迴圈開始時,i的初始值就變成了max-1。這是致命的錯誤。

 


  • 實驗任務五

 1 #include<stdio.h>
 2 
 3 double stage(double t){        //stage函式的意義是階乘 
 4         double b=1.0;        //b作為起始值1與最後階乘函式的值的輸出 
 5     for(int i=1;i<=t;i++){    
 6         b=b*i;
 7     }
 8     return b;
 9 }
10 
11 int main(){
12     printf("Enter n(1~10): ");
13     int n;
14         
15     while(scanf("%d",&n)!=EOF){
16         double a,s=0.0;
17         printf("n = %d, ",n);
18         for(double t=1;t<=n;t+=1){    //t指的是每一個分母,即t的最大值是n 
19             a=1.0/stage(t);            //a指的是每一個項(每一個分式) 
20             if((int)t%2==0){
21                 a*=(-1.0);
22             }
23             s+=a;
24         }
25         printf("s = %lf",s);
26         printf("\n\nEnter n(1~10): ");
27     }
28     return 0;
29 }

執行結果:

程式分析:我用的是函式方法,可能又和同學們的做法不一樣。我的思路是:先把階乘“!”編制為函式方法,然後再直接倒數求和。其中通過規律我不難發現若分式分母為偶數,則該分式的值為負。


  • 實驗任務六

 1 #include<stdio.h>
 2 #include <stdlib.h>
 3 #include <time.h>
 4 
 5 int main(){
 6     int day,guess;
 7     int chance = 3;
 8     
 9     srand(time(0));
10     day = rand() % 31;
11     
12     printf("猜猜12月的哪一天會是你的lucky day★");
13     getchar();
14     printf("\n開始嘍★你有三次機會,請猜吧(1~31)→ ");
15     
16 judge:while(chance--){
17         scanf("%d",&guess); 
18         if(guess==day) return 0;
19         if(guess>day){
20             printf("\n\n你猜的日期晚了,lucky day悄悄溜到前面啦:(\n");
21             if(chance==0){
22                 printf("\n\n殘念だ,次數已經用完了,偷偷告訴你☆,12月你的lucky day是%d號~\n",day);
23                 return 0; 
24             }
25             printf("\n再猜★→ ");
26             goto judge; 
27         }
28         if(guess<day){
29             printf("\n\n你猜的日期早了,lucky day還沒到呢2333\n");
30             if(chance==0){
31                 printf("\n\n殘念だ,次數已經用完了,偷偷告訴你☆,12月你的lucky day是%d號~\n",day);
32                 return 0; 
33             }
34             printf("\n再猜★→ ");
35             goto judge;
36         }
37     }
38     return 0; 
39 }

執行結果:


~實驗結論~

  1. 通過這次實驗,我漸漸地習慣使用字串和函數了,畢竟在這兩個方法上消磨了很多時間w。
  2. 再一個,很開心能和同學們一起討論解決問題,思維的碰撞是最高效率學習的方法之一。
  3. 基礎語法錯誤已經完全可以避免了,現在出現的主要問題是邏輯錯誤。例如有的時候該放在迴圈裡的語句我卻放在了外面,該放在外面的我又放在了裡面。這個是硬傷,得自己治。
  4. 羅馬不是一天建成的。

Thanks for reading