C程序設計實驗報告
實驗項目:
1、利用復化梯形公式計算定積分
2、計算Ackerman函數
3、編寫計算x的y次冪的遞歸函數getpower(int x,int y),並在主程序中實現輸入輸出
4、編寫計算學生年齡的遞歸函數
5、編寫遞歸函數實現Ackman函數
姓名:熊承啟 實驗地點:教學樓514 實驗時間:2019.5.16
一、實驗目的與要求
1、利用復化梯形公式計算定積分
- 掌握C語言中定義函數的方法
- 掌握通過“值傳遞”調用函數的方法
2、計算Ackerman函數
- 掌握遞歸函數的設計方法
- 進一步練習閱讀檢查與調試修改C程序的方法
3、編寫計算x的y次冪的遞歸函數getpower(int x,int y),並在主程序中實現輸入輸出
- 寫出解決該問題的遞歸算法:

- 在遞歸函數中,使用數字1 作為回歸條件;
- 在遞歸函數中,使用 if_else 語句根據條件的真假來決定是遞推還是回歸。
4、編寫計算學生年齡的遞歸函數
- 寫出解決該問題的遞歸算法:
遞歸公式如下,根據公式容易寫出遞歸程序。

- 在遞歸函數中,使用數字1 作為回歸條件;
- 在遞歸函數中,使用if_else語句根據條件的真假來決定是遞推還是回歸。
5、編寫遞歸函數實現Ackman函數
- 根據遞歸公式編寫遞歸函數;
- 在遞歸函數中,使用if_else語句根據條件的真假來決定是遞推還是回歸
二、實驗內容
1.實驗練習:6.4.2.2
1.問題描述:
(1)編制一個函數sab(a,b,n),其功能為利用復化梯形公式計算定積分

其中n為對區間[a,b]的等分數。要求該函數在一個獨立的文件中.
(2)編制一個主函數以及計算被積函數值的函數f(x),在主函數中調用(1)中的函數sab(a,b,n)計算並輸出下列積分值

要求主函數與函數f(x)在同一文件中。

3)編制另一個主函數以及計算被積函數值的函數f(x),在主函數中調用(1)中的函數sab(a,b,n)計算並輸出下列積分值。

同樣要求主函數與函數f(x)在同一文件夾中,
(4)要求畫出模塊sab()的流程圖。
方法說明:
設定積分為:

則復化梯形求積公式為:

其中
2.流程圖:




3.實驗代碼:
#include<stdio.h>
double f(double x);
double sab(double a, double b,int n)
{
int k;
double h,result,x1,x2,x3=0,t;
h=(b-a)/n;
x1=f(a);
x2=f(b);
for (k=1;k<=n-1;k++)
{
t=a+k*h;
x3=x3+f(t);
}
result=h*(x1+x2)/2+h*x3;
return result;
}
#include<stdio.h>
#include<math.h>
#include"sab.h"
double f(double x)
{
double result;
result=x*x*exp(x);
return result;
}
main()
{
double a,b,result;
int n;
printf("please input double a,b and integer n:");
scanf("%lf,%lf,%d",&a,&b,&n);
result=sab(a,b,n);
printf("sab(%lf,%lf,%d)=%lf",a,b,n,result);
return 0;
}
#include<stdio.h>
#include"sab.h"
double f(double x)
{
double result;
result=1/(25+x*x);
return result;
}
main()
{
double a,b,result;
int n;
printf("please input double a,b and integer n:");
scanf("%lf,%lf,%d",&a,&b,&n);
result=sab(a,b,n);
printf("sab(%lf,%lf,%d)=%lf",a,b,n,result);
return 0;
}
4.問題分析:
這里最要注意的是三個文件是分開的,頭文件sab.h在兩個程序中都要調用,剛開始我直接對着課本上的程序實現打,發現沒有用,然后經過老師的提醒才發現問題所在,sab.h中還要調用主程序文件中的f()函數,所以在sab.h頭文件中還需要對f()函數進行聲明,在寫代碼的過程中,對一個數的定義類型要特別注意,有時候是整型,有時候是雙精度等,都要根據情況而改變。
5.運行效果:

2.實驗練習:6.4.2.3
1.問題描述:
具體要求:
(1)根據方法說明,編制計算Ackerman函數的遞歸函數ack(n,x,y)。
(2)編制一個主函數,由鍵盤輸入n,x,y,調用(1)中的函數ack(n,x,y),計算Ackerman函數。
(3)在主函數中,輸入之前要有提示,並檢查輸入數據的合理性,若輸入的數據不合理,則輸出錯誤信息,輸出要有文字說明。
(4)輸入(n,x,y)=(2,3,1)運行該程序。然后自定義幾組數據再運行該程序。
方法說明:
Ackerman函數的定義如下:
n,x,y為非負整數,且

2.流程圖:
3.實驗代碼:
#include<stdio.h>
int Ack(int n,int x,int y)
{
int a;
if(n==0)
a=x+1;
else if(n==1&&y==0)
a=x;
else if(n==2&&y==0)
a=0;
else if(n==3&&y==0)
a=1;
else if(n>=4&&y==0)
a=2;
else if(n!=0&&y!=0)
a=Ack(n-1,Ack(n,x,y-1),x);//*我在前面用了一個return*//
return a;
}
main()
{
int n,x,y,result;
printf("Please input nx,y:");
scanf("%d,%d,%d",&n,&x,&y);
if(n<0||x<0||y<0)
printf("Error!");
result=Ack(n,x,y);
printf("Ack(%d,%d,%d)=%d\n",n,x,y,result);
}
4.問題分析:
首先,用到了條件分支結構,之前都在考慮要不要用if else的結構,改了很久發現其實用不用都可以,后面的編程中我沒有用renturn進行進一步的遞推,這個失誤要記住。
5.運行效果:

3.實驗練習:6.4.3.1
1.問題描述:
編寫程序,分別從鍵盤輸入數據x和y,計算x的y次冪並輸出。
2.流程圖:
3.實驗代碼:
#include<stdio.h>
long getpower(int x,int y)
{
if(y==1)
return x;
else
return x*getpower(x,y-1);
}
main()
{
int num,power;
long answer;
printf("輸入一個數:");
scanf("%d",&num);
printf("輸入冪次方:");
scanf("%d",&power);
answer=getpower(num,power);
printf("結果是:%ld\n",answer);
}
4.問題分析:
if()條件中的“==”號的問題很難發現,一旦犯錯可能就會陷入困難,這個是我很久都沒有找到的問題所在。
5.運行效果:

4.實驗練習:6.4.3.2
1.問題描述:
用遞歸方法計算學生的年齡。已知第一位學生年齡最小為10歲,其余學生一個比一個大2歲,求第5位學生的年齡。
2.流程圖:
3.實驗代碼:
#include<stdio.h>
int age(int n)
{
int c;
if(n==1)
c=10;
else
c=age(n-1)+2;
return c;
}
main()
{
int n=5,result;
result=age(n);
printf("第五位學生的年齡是%d歲",result);
}
4.問題分析:
我自己出了一個小問題,我沒讀懂題,當時一直在想怎么不是20,后面通過自己繪制流程圖明白了為什么是18.
5.運行效果:
5.實驗練習:6.4.3.3
1.問題描述:
定義遞歸函數實現下列Ackman函數:

其中m,n為正整數,設計程序求Acm(2,1),Acm(3,2)。
2.流程圖:
3.實驗代碼:
#include<stdio.h>
Acm(int m,int n)
{
if(m==0)
return n+1;
if(n==0)
return Acm(m-1,1);
if(n>0&&m>0)
return Acm(m-1,Acm(m,n-1));
}
int main()
{
int f=2,g=1,k=3;
printf("Acm(2,1)=%d\nAcm(3,2)=%d",Acm(f,g),Acm(k,f));
return 0;
}
4.問題分析:
題目已經給出了Acm函數的定義,不同條件返回不同的值,按照流程圖解決問題。
5.運行效果:

三、實驗小結
1.知道遞歸函數的定義,才能根據函數寫出代碼,
2.學會了將通用的重要文件獨立開來並引用,
3.根據流程圖進行編寫的過程中更多的是將它運行出來,不知所以然。在今后的學習過程中,要更加將自己看懂流程圖,理解流程圖並動手設計流程圖融匯起來。
4.當代碼沒有錯誤時,但是卻運行不出來的時候,就要看看是不是某個數的定義類型有誤,或者是標點符號漏錯的問題。
5.寫遞歸函數的時候,有時候幾個程序都要調用一個函數,那么就可以把它獨立的放到一個文件中,會更方便。


