實驗四 張珂瑜
實驗四
(一)task 1
思考:在這個實驗中,一元二次方程的根是否能設計成通過函式返回值的方式傳遞迴主函式?
不可以;函式的返回值只有一個,而一元二次方程的解可能會出現兩個,這樣無法同時傳遞。但是可以通過指標的方式傳遞。
(二)task 2
(ex1的原始碼)
#include <stdio.h> long long fac(int n); int main() { int i,n; printf("Enter n: "); scanf("%d", &n); for(i=1; i<=n; ++i) printf("%d! = %lld\n", i, fac(i)); return 0; } long long fac(int n) { static long long p = 1; printf("p=%lld\n",p); p = p*n; return p; }
(增加一行程式碼之後的測試結果截圖)
(ex2的原始碼)
#include<stdio.h> int func(int, int); int main() { int k=4,m=1,p1,p2; p1 = func(k,m) ; p2= func(k,m) ; printf("%d,%d\n",p1,p2) ; return 0; } int func(int a,int b) { static int m=0,i=2; i += m+1; m = i+a+b; return (m); }
(理論分析結果)
呼叫第一次func時,k=4,m=1.這兩個數在函式內部對應的是a、b ,即a=4,b=1。在函式內部,m=0,i=2被定義成了靜態變數。經過計算,i=i+m+1=3,m=i+a+b=8,返回m的值給p1,即原函式中p1=8.然而由於m和i僅僅是func域內部的靜態變數,所以保留上一次執行的結果,m=8,i=3.第二次呼叫func,a=4,b=1,經過計算,i=i+m+1=12,m=i+a+b=17。函式返回m的值給p2,p2=17.螢幕上會打印出p1,p2的值,所以最終結果為“8 17”。
(實驗執行結果)
(總結其一致性)
結果與分析一致。
(三)task 3
(補全後完整程式原始碼)
//輸出(n,m)之間的所有素數 #include <stdio.h> #define N 1000 int fun(int n,int m,int bb[N]); int main(){ int n=0,m=0,i,k,bb[N-1]; scanf("%d",&n); scanf("%d",&m); for(i=0;i<m-n;i++) bb[i]=0; k=fun(n,m,bb); for(i=0;i<k;i++) printf("%4d",bb[i]); printf("\n"); return 0; } int fun(int n,int m,int bb[N]) { int i,j,k=0,flag; for(j=n;j<=m;j++) { flag=1; for(i=2;i<j;i++) if(j%i==0) { flag=0; break; } if(flag==1) bb[k++]=j; } return k; }
(程式執行測試結果截圖)
(四)task 4
*必做
(程式原始碼)
//f(n)=2^n-1 #include <stdio.h> long long fun(int n); int main() { int n; long long f; while(scanf("%d", &n) != EOF) { f = fun(n)-1;//其實我通過在這裡-1來實現了,也就是說我的函式事實上是求2^n的結果 printf("n = %d, f = %lld\n", n, f); } return 0; } long long fun(int n){// 函式定義 long long ret=1; if (n==1) { ret=2; }else{ ret=2*fun(n-1); } return ret; }// 補足
(程式測試結果截圖)
*選做(暫時還不會,留著以後來補)
(演算法思路的文字表述)
(程式原始碼)
(程式執行結果截圖)
(五)task 5
(程式原始碼)
#include <stdio.h> void draw(char symbol ,int line); int main(int argc, const char * argv[]) { char symbol; int line; printf("input symbol and line:"); while(scanf(" %c %d",&symbol,&line)!=EOF) { draw(symbol, line); printf("\n"); printf("input symbol and line:"); } return 0; } void draw(char symbol,int line){ int i,t; for (i=1; i<=line; i++) { for(t=line-i;t>0;t--){ printf("\t"); } for (t=0; t<2*i-1; t++) { printf("%c\t",symbol); } printf("\n"); } } //好巧我之前自己寫過這個程式,所以就沒有用老師的原始碼
(程式執行測試結果截圖)
(六)實驗總結
1.本次實驗中踩過的坑:在task3中,我在引用函式時在函式內部寫了bb[N],然後給2個warning下標問題和資料型別問題,我改成bb[N-2]後只剩下1個數據型別問題warning,我強制編譯,由於mac下的xcode檢查嚴格,編譯成功無法執行。提問了一個專業人員之後立馬查錯,問題在bb[N-2]是一個特定的數字,而bb是一個數組。此處應該引入陣列。
2.尚存的問題:在task4中,我利用迭代思想只能在新函式func中實現2^n的迭代,最後的-1只能在main函式中實現。但是老師給的原始碼中main函式中不可修改,所以事實上我並沒有實現要求。而是強制用我自己的思路編寫了程式。