利用函數指針編寫一個通用的求定積分函數
程序代码:
/* 功能:利用函數指針編寫一個通用的求定積分函數 最後編輯:2015.10.13 */ // 在VC中,要使用標準C庫的數學常數,應定義如下宏 #define _USE_MATH_DEFINES #include <stdio.h> #include <math.h> #include <conio.h> //-------------------------------------- // 功能:通用的求定積分函數 // 參數:fun - 所求函數的指針,帶1個double形參 // x1 - 積分下限 // x2 - 積分上限 // 返回:定積分結果 // 備註:調用者應自己保證函數在區間[x1,x2]內可積 //-------------------------------------- double Get_Integral(double fun(double), double x1, double x2) { // 微元長度:假設輸出精度為小數點後4位,則此處取5位 static const double interval = 0.00001; double integral = 0; // 結果 // 下面for()聲明double x屬於C99標準,VC的C編譯模式不支持,但其C++模式支持,若一定要在VC中用C編譯 // 模式,把double x聲明放到函數開始處。強制VC使用C編譯的方法,是把源代碼文件擴展名取.c,默認取.cpp // 為C++編譯。 for (double x = x1; x <= x2; x += interval) { //------------------------------ // 定積分的幾何意義: // 定積分意味著函數曲線在上下區間內與x軸所圍成的圖形面積,算法是分割微元矩形求和,即x軸上 // 任意取一極小橫段(由interval表示),與此處曲線的高度(由函數的値fun(x)表示),構成一個微元 // 矩形,在整個區間內計算所有這樣的微元矩形面積(寬*高),其總和即為所求曲線圖形的近似面積。 // 祗要interval足夠小,這樣求得的近似面積可以滿足精度要求。 // interval數値越小越精確,然而耗時也越多;數値越大誤差越大,然而計算較快。平衡關鍵點是在實 // 際使用過程中按精度需求和運行情況調整interval的値。如何在自己的程序中方便地調整interval的値 // 又不至於改動太多的源代碼,是下一步改進的思考點,不是現在達到目的就行了。 // // 注意: // 定積分的結果與函數的正負値有關,它們會互相抵消,若要求真正的幾何面積,需按照正負區間分 // 別計算然後用絕對値相加,應先做數學分析。 //------------------------------ integral += fun(x) * interval; } return integral; } //-------------------------------------- // 函數:f(x)=x // 幾何圖形:斜45°直線 //-------------------------------------- double Fun1(double x) { return x; } //-------------------------------------- // 函數:f(x)=x^2 // 幾何圖形:向上開口的拋物線 //-------------------------------------- double Fun2(double x) { return x * x; } //-------------------------------------- // 函數:f(x)=Sin(x) // 幾何圖形:正弦曲線 //-------------------------------------- double Fun3(double x) { return sin(x); } //-------------------------------------- // 函數:f(x)=Cos(x) // 幾何圖形:余弦曲線 //-------------------------------------- double Fun4(double x) { return cos(x); } //-------------------------------------- // 驗證通用定積分函數,用同一個求定積分函數求出4個不同函數的定積分 //-------------------------------------- int main(void) { double x1, x2, integral; // 驗證[0,1]的直線面積為1/2 x1 = 0; x2 = 1; integral = Get_Integral(Fun1, x1, x2); printf_s("Integral f(x)=x [%.4f, %.4f] = %.4f\n", x1, x2, integral); // 驗證拋物線面積 x1 = 0; x2 = 1; integral = Get_Integral(Fun2, x1, x2); printf_s("Integral f(x)=x^2 [%.4f, %.4f] = %.4f\n", x1, x2, integral); // 驗證[0,π]的正弦曲線面積 x1 = 0; x2 = M_PI; integral = Get_Integral(Fun3, x1, x2); printf_s("Integral f(x)=Sin(x) [%.4f, %.4f] = %.4f\n", x1, x2, integral); // 驗證[0,2π]的余弦曲線面積為零,因正負抵消 x1 = 0; x2 = 2 * M_PI; integral = Get_Integral(Fun4, x1, x2); printf_s("Integral f(x)=Cos(x) [%.4f, %.4f] = %.4f\n", x1, x2, integral); _getch(); // VC專用的控制臺鍵盤按鍵讀取函數,在conio頭中,不要用getchar() return 0; }