一、梯形法簡介
在數學中,梯形法是一種計算曲線下面積的方法。它的原理是將曲線圖形分成許多小的梯形,並計算每個梯形的面積,最後將這些面積總和起來。這個方法在近似計算不可積分的曲線下面積時非常有用。二、函式指標介紹
函式指標是C語言中的一個重要概念。它允許我們在函式中使用指標來操作和存取變數的地址。函式指標可以傳遞指標作為參數,並且可以在函數內部改變指標所指向的值。三、梯形法計算面積的實現
1、積分運算函式
double calculatef(double (*f)(double, double), double a, double p, double q, int n)
{
    double area = f(a, p) + f(a, q);
    double h = (q - p) / n;
    for (double xi = p + h; xi < q; xi += h)
    {
        area += 2 * f(a, xi);
    }
    area *= (q - p);
    area /= (2 * n);
    return area;
}
2、指定計算f1(x) or f2(x)的函式
double (*getOption(int option))(double, double)
{
    if (option == 1)
    {
        return f1;
    }
    else if (option == 2)
    {
        return f2;
    }
    return NULL;
}
4、計算f1(x) or f2(x)
double f1(double a, double x)
{
    return sqrt(a - x * x);
}
double f2(double a, double x)
{
    double f2 = (a * x * x * x + 7 * x) / sqrt(a + x);
    if (f2 < 0)
        f2 *= -1.0;
    return f2;
}
f2 函式:計算函數 f2 的值。它根據給定的參數 a 和 x,計算 (a * x * x * x + 7 * x) / sqrt(a + x)。如果計算結果小於 0,則將其乘以 -1.0。
可根據自己需求,自行修改程式碼改成自己想要計算的函數。
5、計算絕對值
double myabs(double a)
{
    if (a < 0)
        return -a;
    else
        return a;
}
6、main函式
int main()
{
    int option;
    double a, p, q, err;
    while (scanf("%d", &option))
    {
        if (option == 0)
        {
            break;
        }
        scanf("%lf %lf %lf %lf", &a, &p, &q, &err);
        double (*Option)(double, double) = getOption(option);
        int n = 1;
        double prevarea = calculatef(Option, a, p, q, n);
        double currarea = calculatef(Option, a, p, q, 2 * n);
        n *= 2;
        double derr = pow(10, -err);
        while (myabs(prevarea - currarea) >= derr)
        {
            n *= 2;
            prevarea = currarea;
            currarea = calculatef(Option, a, p, q, n);
        }
        printf("%.12lf\n", currarea);
    }
    return 0;
}
a 表示函式中的常數,p 表示區間的起始位置,q 表示區間的終點位置,err 表示精確小數位數。
然後它使用 getOption 函式獲取對應的函式指標。
輸入整數1 代表計算 f1(x) 面積,2 代表計算 f2(x)面積。
接下來,使用數值積分的方法計算積分值,並根據給定的誤差要求調整積分的精度。
前一個計算結果跟目前的計算結果的差要小於10的-err次方,否則繼續計算,且切割度增加。
最後,輸出計算得到的積分值。
程式會持續讀取輸入,直到選項值為 0 時結束執行。輸入1或2,繼續新一輪計算。
四、結語
這是我的c語言作業的某一題,要求使用梯形法來計算面積。通過這一題,展示了如何使用函式指標和梯形法來計算面積。
函式指標提供了一種更靈活和高效的方法來寫你的程式。
原本f1的計算要一個函數,f2的計算也要一個函數。
用了函式指標之後,結合起來只需要一個'calculatef'。
還增加了可讀性且方便維護。
五、完整程式碼
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double calculatef(double (*f)(double, double), double a, double p, double q, int n);
double (*getOption(int option))(double, double);
double f1(double a, double x);
double f2(double a, double x);
double myabs(double a);
int main()
{
    int option;
    double a, p, q, err;
    while (scanf("%d", &option))
    {
        if (option == 0)
        {
            break;
        }
        scanf("%lf %lf %lf %lf", &a, &p, &q, &err);
        double (*Option)(double, double) = getOption(option);
        int n = 1;
        double prevarea = calculatef(Option, a, p, q, n);
        double currarea = calculatef(Option, a, p, q, 2 * n);
        n *= 2;
        double derr = pow(10, -err);
        while (myabs(prevarea - currarea) >= derr)
        {
            n *= 2;
            prevarea = currarea;
            currarea = calculatef(Option, a, p, q, n);
        }
        printf("%.12lf\n", currarea);
    }
    return 0;
}
double calculatef(double (*f)(double, double), double a, double p, double q, int n)
{
    double area = f(a, p) + f(a, q);
    double h = (q - p) / n;
    for (double xi = p + h; xi < q; xi += h)
    {
        area += 2 * f(a, xi);
    }
    area *= (q - p);
    area /= (2 * n);
    return area;
}
double (*getOption(int option))(double, double)
{
    if (option == 1)
    {
        return f1;
    }
    else if (option == 2)
    {
        return f2;
    }
    return NULL;
}
double f1(double a, double x)
{
    return sqrt(a - x * x);
}
double f2(double a, double x)
{
    double f2 = (a * x * x * x + 7 * x) / sqrt(a + x);
    if (f2 < 0)
        f2 *= -1.0;
    return f2;
}
double myabs(double a)
{
    if (a < 0)
        return -a;
    else
        return a;
}
沒有留言:
張貼留言