關於第三次實踐課作業
實驗結論
task1.c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 char score_to_grade(int score); 4 int main() { 5 int score; 6 char grade; 7 8 while (scanf("%d", &score) != EOF) 9 { 10 grade = score_to_grade(score); 11 printf("分數 : %d , 等級 : %c\n\n", score, grade); 12 } 13 return 0; 14 } 15 char score_to_grade(int score) { 16 char ans; 17 switch (score / 10) { 18 case 10: 19 case 9:ans = 'A'; break; 20 case 8:ans = 'B'; break; 21 case 7:ans = 'C'; break; 22 case 6:ans = 'D'; break; 23 default:ans = 'E'; 24 } 25 return ans; 26 }
question1:函式 score_to_grade 的功能是什麼?形參型別、返回值型別是什麼?
answer1:函式的功能是將得到的分數透過計算轉化為對應的等級;
形參型別是int型資料,返回型別是字元型資料;
question2:如果line21-28以下形式,有問題嗎?如果有,指出有哪些問題?
1 switch(score/10) { 2 case 10: 3 case 9: ans = "A"; 4 case 8: ans = "B"; 5 case 7: ans = "C"; 6 case 6: ans = "D"; 7 default: ans = 'E'; 8 }
answer2:有問題;
沒有使用break語句會導致ans得到對應grade時
無法離開switch語句,返回ans時其值始終是E
task2.c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 int sum_digits(int n); 4 5 int main() 6 { 7 int n; 8 int ans; 9 while (printf("Enter n:"), scanf("%d", &n) != EOF) { 10 ans = sum_digits(n); 11 printf("n = %d,ans = %d\n\n", n, ans); 12 } 13 return 0; 14 } 15 int sum_digits(int n) { 16 int ans = 0; 17 while (n != 0) { 18 ans += n % 10; 19 n /= 10; 20 } 21 return ans; 22 }
question1:函式 sum_digits 的功能是什麼?
answer1:取出n的各個數位,並將它們相加
question2:如果保持 main 程式碼和函式 sum_digits 宣告不變,
把函式 sum_digits 定義成如下 實現方式,能實現同等的效果嗎?
如果不能實現同等效果,分析原因。
如果能實現同等效果,說明兩種實現方式背後的演算法思維區別。
1 int sum_digits(int n) { 2 if(n < 10) 3 return n; 4 return sum_digits(n/10) + n%10; 5 }
answer2:能實現同等效果
第一種演算法思維是迭代,
透過取餘取出n的個位後透過整除去掉n的個位
如此往復不斷得到n的個位並累加
第二種演算法思維是遞迴,
最簡單情形即是n本身就是一個個位數,
即可以直接返回n值;
其他情況下:既透過取餘得到n的個位數,
又透過取整去掉n的個位進入函式作進一步計算
task3.c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 int power(int x, int y); 4 int main() { 5 int x, n, ans; 6 while (printf("Enter x and n:"), scanf("%d %d", &x, &n) != EOF) { 7 ans = power(x, n); 8 printf("n = %d,ans = %d\n\n", n, ans); 9 } 10 return 0; 11 } 12 int power(int x, int n) { 13 int t; 14 if (n == 0) { 15 return 1; 16 } 17 else if (n % 2) { 18 return x * power(x, n - 1); 19 } 20 else { 21 t = power(x, n / 2); 22 return t * t; 23 } 24 }
question1:函式 power 的功能是什麼?
answer1:計算x的n次冪
question2:函式 power 是遞迴函式嗎?如果是,找出遞迴模式。寫出這個遞迴模式對應的數學公 式模型
answer2:是,其遞迴模式是:
task4.c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 #include<math.h> 4 int is_prime(int x); 5 int main() 6 { 7 printf("100以內的孿生素數:\n"); 8 int cnt = 0; 9 int i ; 10 for (i = 2; i <= 100; i++) { 11 if (is_prime(i) == 1 && is_prime(i + 2) == 1) { 12 printf("%d %d\n", i, i + 2); 13 cnt++; 14 } 15 } 16 printf("100以內的孿生素數共有%d個\n", cnt); 17 return 0; 18 } 19 int is_prime(int x) { 20 int i; 21 for (i = 2; i <= sqrt(1.0*x); i++) { 22 if (x % i == 0) { 23 return 0; 24 } 25 } 26 return 1; 27 }
task5.c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 void hanoi(int n, char from, char temp, char to); 4 void move(int n, char from, char to); 5 int cnt = 0; 6 int main() { 7 int n; 8 while (scanf("%d", &n) != EOF) { 9 cnt = 0; 10 hanoi(n, 'A', 'B', 'C'); 11 printf("一共移動了%d次\n", cnt); 12 } 13 return 0; 14 } 15 void hanoi(int n, char from, char temp, char to) { 16 if (n == 1) { 17 move(n, from, to); 18 } 19 else { 20 hanoi(n - 1, from, to, temp); 21 move(n, from, to); 22 hanoi(n - 1, temp, from, to); 23 } 24 } 25 void move(int n, char from, char to) { 26 printf("%d : %c --> %c\n", n, from, to); 27 cnt++; 28 }
task6_1.c
用迭代方式實現計算組合數 func()
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 int func(int n, int m); 4 int fac(int n); 5 int main() 6 { 7 int n, m; 8 int ans; 9 while (scanf("%d %d", &n, &m) != EOF) { 10 ans = func(n, m); 11 printf("n = %d,m = %d,ans = %d\n\n", n, m, ans); 12 } 13 return 0; 14 } 15 int func(int n, int m) { 16 return fac(n) / (fac(m) * fac(n - m)); 17 } 18 int fac(int n) { 19 int i,ans=1; 20 for (i = 1; i <= n; i++) { 21 ans *= i; 22 } 23 return ans; 24 }
task6_2.c
用遞迴函式實現計算組合數 func()
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 int func(int n, int m); 4 5 int main() 6 { 7 int n, m; 8 int ans; 9 while (scanf("%d %d", &n, &m) != EOF) { 10 ans = func(n, m); 11 printf("n = %d,m = %d,ans = %d\n\n", n, m, ans); 12 } 13 return 0; 14 } 15 16 int func(int n, int m) { 17 if (n == 0 && m!=0) { 18 return 0; 19 } 20 else if (m == 0) { 21 return 1; 22 } 23 else { 24 return func(n - 1, m) + func(n - 1, m - 1); 25 } 26 }
task7.c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 void print_charman(int n); 4 void one(int x); 5 void two(int x); 6 void three(int x); 7 int main() 8 { 9 int n; 10 printf("Enter n:"); 11 scanf("%d", &n); 12 print_charman(n); 13 return 0; 14 } 15 int j, cnt = 0; 16 void print_charman(int n) { 17 int i; 18 for (i = n; i >= 1; i--) { 19 int x = (2 * i)- 1; 20 one(x); 21 two(x); 22 three(x); 23 cnt++; 24 } 25 26 } 27 28 void one(int x) { 29 for (j = 1; j <= cnt; j++) { 30 printf("\t"); 31 } 32 int i; 33 for (i = 1; i <= x; i++) { 34 printf(" 0\t"); 35 } 36 printf("\n"); 37 } 38 void two(int x) { 39 for (j = 1; j <= cnt; j++) { 40 printf("\t"); 41 } 42 int i; 43 for (i = 1; i <= x; i++) { 44 printf("<H>\t"); 45 } 46 printf("\n"); 47 48 } 49 void three(int x) { 50 for (j = 1; j <= cnt; j++) { 51 printf("\t"); 52 } 53 int i; 54 for (i = 1; i <= x; i++) { 55 printf("I I\t"); 56 } 57 printf("\n"); 58 }
實驗總結
1.尚存的問題 :對於Hanoi塔的理解問題,無法正確理解兩個函式
對於全域性變數,區域性變數等的理解
編寫遞迴函式
2.函式作為一種模組化程式的設計手段,
在編寫一個“大”程式時可以逐個編寫每個“小”程式(即函式)
逐一進行除錯糾錯,保證每個函式都是正確的,
這樣在運用函式時可以保證不因區域性函式的問題
而影響整體程式,使調適時更加便捷清晰