第六章函數與宏定義實驗報告二

C程序設計實驗報告

實驗項目:

一、利用復化梯形公式計算定積分
二、計算Ackerman函數
三、編寫計算x的y次冪的遞歸函數getpower(int x,int y),並在主程序中實現輸入輸出
四、編寫計算學生年齡的遞歸函數
五、編寫遞歸函數實現Ackman函數算法

姓名:戴求  實驗地點:教學樓514  實驗時間:2019.5.16

1、實驗目的與要求

一、利用復化梯形公式計算定積分

  • 掌握C語言中定義函數的方法
  • 掌握經過「值傳遞」調用函數的方法

二、計算Ackerman函數

  • 掌握遞歸函數的設計方法
  • 進一步練習閱讀檢查與調試修改C程序的方法

三、編寫計算x的y次冪的遞歸函數getpower(int x,int y),並在主程序中實現輸入輸出

  • 寫出解決該問題的遞歸算法:
  • 在遞歸函數中,使用數字1 做爲迴歸條件;
  • 在遞歸函數中,使用 if_else 語句根據條件的真假來決定是遞推仍是迴歸。

四、編寫計算學生年齡的遞歸函數

  • 寫出解決該問題的遞歸算法:
    遞歸公式以下,根據公式容易寫出遞歸程序。
  • 在遞歸函數中,使用數字1 做爲迴歸條件;
  • 在遞歸函數中,使用if_else語句根據條件的真假來決定是遞推仍是迴歸。

五、編寫遞歸函數實現Ackman函數

  • 根據遞歸公式編寫遞歸函數;
  • 在遞歸函數中,使用if_else語句根據條件的真假來決定是遞推仍是迴歸。

2、實驗內容

一、利用復化梯形公式計算定積分

  • 問題的簡單描述:
    (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()的流程圖。
    方法說明:
    設定積分爲

    則復化梯形求積公式爲

    其中h=(b-a)/n,Xk=a+kh。程圖如圖下圖所示:

  • 實驗代碼:
    (1)sab.h
#include<stdio.h>
double f(double x);
double sab(double a,double b,int n)
{
    double h,result,x1,x2,x3=0,t;
    int k;
    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);
    }
    return h*(x1+x2)/2+h*x3;
}

(2)6.4.2.2.1.cpp函數

#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)=%f",a,b,n,result);
    return 0;
}

(3)6.4.2.2.2.cpp設計

#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(%f,%f,%d)=%f",a,b,n,result);
    return 0;
}

運行結果以下:3d

  • 問題分析:在編寫程序時,我編寫出來的運行結果與我預期的不同,當主程序的輸入中輸入數據的類型爲%f時,獲得的結果全是0.000000,在該變輸入數據的類型爲%lf時,獲得了正確的結果。還有就是在調用函數的時候不是寫形參,而是實參,否則系統會提示變量未定義。

二、計算Ackerman函數

  • 問題的簡單描述:
    具體要求以下:

(1)根據方法說明,編制計算Ackerman函數的遞歸函數ack(n,x,y)。調試

(2)編制一個主函數,由鍵盤輸入n,x,y,調用(1)中的函數ack(n,x,y),計算Ackerman函數code

(3)在主函數中,輸入以前要有提示,並檢查輸入數據的合理性,若輸入的數據不合理,則輸出出錯信息。輸出要有文字說明。blog

(4)輸入(n,x,y) = (2,3,1)運行該程序。而後自定義幾組數據再運行該程序。遞歸

方法說明:
Ackerman函數的定義以下:
1n,x,y爲非負整數,且字符串

流程圖以下圖所示:get

  • 實驗代碼:
#include<stdio.h>
int Ack(int n,int x,int y)
{
    int a;
    if(n==0)
    a=x+1;
    if(n==1&&y==0)
    a=x;
    if(n==2&&y==0)
    a=0;
    if(n==3&&y==0)
    a=1;
        if(n>=4&&y==0)
    a=2;
    if(n!=0&&y!=0)
        return Ack(n-1,Ack(n,x,y-1),x);
    return a;
} 
main()
{
    int a,b,c,d;
    printf("please input a,b,c:");
    scanf("%d%d%d",&a,&b,&c);
    while (a<=0||b<=0||c<=0)
    {
        printf("error,please input again!\n");
        scanf("%d%d%d",&a,&b,&c);
    }
    d=Ack(a,b,c);   
    printf("Ack(%d,%d,%d)=%d\n",a,b,c,d);
}

運行結果以下:

  • 問題分析:這個程序就是在照着流程圖填入語句,但在我在編寫進一步遞推語句的時候,我仍是按照以前的if語句那樣將條件寫上去,可是這樣的話,運行以後結果並無讓人如願。因而,我上網查了一下,進一步遞推的語句就是return這個函數索要地推的內容。還有就是在輸入數據不合理,從新輸入的語句時,應該用一個循環來實現。

三、編寫計算x的y次冪的遞歸函數getpower(int x,int y),並在主程序只能怪實現輸入輸出

  • 問題的簡單描述:編寫程序,分別從鍵盤輸入數據x和y,計算x的y次冪並輸出。程序流程圖以下圖所示:

  • 實驗代碼:
#include<stdio.h>
long getpower(int x,int y)
{
    if(y==1)
        return x;
    else
        return x*getpower(x,y-1);
}
main()
{
    float num,power;
    long answer;
    printf("輸入一個數:");
    while((!scanf("%f",&num))||((int)num)!=num)
    {
        fflush(stdin); 
        printf("輸入錯誤,請從新輸入!\n輸入一個數:");
        //scanf("%f",&num);
    }
    printf("輸入冪次方:");
    while((!scanf("%f",&power))||((int)power)!=power)
    {
        fflush(stdin); 
        printf("輸入錯誤,請從新輸入!\n輸入一個數:");
    //  scanf("%f",&power);
    }
    answer=getpower(num,power);
    printf("結果是:%ld",answer);
    return 0;
}

運行結果以下:

  • 問題分析:這個程序的最重要的問題就在於怎樣判斷輸入的數是一個整數和遞推語句。我先想到的是用一個if的判斷語句a%2==0||a%2==1來實現這個要求,可是我發現輸入1.2等數據時,這個判斷就出現了錯誤。在網上查到一種方法,就是將其定義爲浮點型數據,而後用int(num)==num這個判斷條件來判斷這個數據是否爲整數,若是這個數轉換爲整型的數據類型爲這個數的話,那他就是整數,不然不是。可是,在老師叫我輸入字符或字母的時候,程序崩了,因此我在網上查了一下,查到了fflush(stdin)這個語句:fflush(stdin)是一個計算機專業術語,功能是清空輸入緩衝區,一般是爲了確保不影響後面的數據讀取(例如在讀完一個字符串後緊接着又要讀取一個字符,此時應該先執行fflush(stdin);),而且在while表達式&&中只要第一個表達式爲假就不會執行第二個表達式,直接結束循環,當第一個表達式爲真就執行第二個。,因此還要將while中的條件調換順序,不然會喲啊輸入兩次,這樣的話就能夠執行正確了。

四、編寫計算學生年齡的遞歸函數

  • 問題的簡單描述:用遞歸方法計算學生的年齡。已知第一位學生年齡最小爲10歲,其他學生一個比一個大2歲,求第5位學生的年齡。流程圖以下圖所示:

  • 實驗代碼:
#include<stdio.h>
int age(int n)
{
    int c;
    if(n==1)
        c=10;
    else
        return age(n-1)+2;
    return c;
}
main()
{
    int n=5;
    printf("%d",age(n));
}

運行結果以下:

  • 問題分析:這個程序要注意怎樣輸出第n個學生的年齡和下一步遞推,就是將調用函數的結果放進去。

五、編寫遞歸函數實現Ackman函數

  • 問題的簡單描述:定義遞歸函數實現下列Ackman函數:

其中m、n爲正整數。設計程序求Acm(2,1),Acm(3,2)。程序流程圖以下圖所示:

  • 實驗代碼:
#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 m,n,x,y;
    printf("please input two integers m,n:");
    scanf("%d%d",&m,&n);
    printf("please input two integers x,y:");
    scanf("%d%d",&x,&y);
    printf("Acm(%d,%d)=%d\n",m,n,Acm(m,n));
    printf("Acm(%d,%d)=%d",x,y,Acm(x,y));
}

運行結果以下:

  • 問題分析:這個程序其實也不難,只要看懂了要怎樣下一步遞推就能夠了,他不像前面的程序那樣,他每一個都是要用return語句。

3、實驗小結(在本次實驗中收穫與不足)

一、要正確掌握如何實現進一步遞推的功能,使用if-else語句根據條件的真假;來決定是遞推仍是迴歸。 二、學會如何調用另外一個獨立文件程序中的函數,且要注意,在獨立文件頭文件中還要對函數進行聲明。 三、掌握如何判斷一個數是否爲整數,和輸入輸出的循環,冪函數的輸出結果的格式要定義爲%ld型,由於他要輸出長整型數據。

相關文章
相關標籤/搜索