1

私が作成したものではないコードがあります。この複雑なコードでは、量 d(x) を計算するために多くのルールが適用されています。コードでは、それを計算するためにポインターが使用されています。

次のような積分を計算したい: W= Int_0 ^L d(x) dx ?

私はこれをやっています:

#define DX 0.003
void WORK(double *d, double *W)
{
    double INTE5=0.0;
    int N_X_POINTS=333;
    double h=((d[N_X_POINTS]-d[0])/N_X_POINTS); 
    W[0]=W[0]+((h/2)*(d[1]+2.0*d[0]+d[N_X_POINTS-1])); /*BC*/
    for (i=1;i<N_X_POINTS-1;i++) 
    {
        W[i]=W[i]+((h/2)*(d[0]+2*d[i]+d[N_X_POINTS]))*DX;
        INTE5+=W[i];
    }
    W[N_X_POINTS-1]=W[N_X_POINTS-1]+((h/2)*(d[0]+2.0*d[N_X_POINTS-1]+d[N_X_POINTS-2])); /*BC*/
}

そして、「セグメンテーション違反」が発生しています。私はWをポインタとして計算するのが正しいのか、それとも単純なdoubleとして宣言すべきなのか知りたいと思っていましたか?これにはセグメンテーション違反が発生していると思います。

他の点、台形則を正しく使用していますか?

どんな助け/ヒントも、とても感謝します。

ルイス

4

3 に答える 3

1

そのコードがどこから来たのかはわかりませんが、かなり醜く、いくつかの制限がハードエンコードされています (333 ポイントで 0.003 ずつ増加)。それを使用するには、関数を適切に「サンプリング」し、ペア (x, f(x)) を生成する必要があります...

あなたの問題に対するより明確な解決策はここにあります。

あなたが関数であると考えて、それが機能すると仮定しましょう (私はそうではないと思います、それは本当にあいまいなコードです...; たとえば、関数を統合すると、結果として数値が期待されます; この数値はどこですか? 多分 INTE5? それはは返されません... もしそうなら、なぜ W 配列の最終更新なのですか? 役に立たないか、W に何か意味のあるものがあるのでしょうか?)。どのように使用しますか?

プロトタイプ

  void WORK(double *d, double *W);

WORK が 2 つのポインターを必要とすることを意味します。これらのポインターが何である必要があるかは、コードによって異なります。これを見ると、それぞれ N_X_POINTS 要素を持つ 2 つの配列が実際に必要であることがわかります。このコードは、配列 W に対して読み取りと書き込みを行い、d からのみ読み取りを行います。N_X_POINTS int は 333 なので、少なくとも 333 個の double の関数配列を渡す必要があります。

   double d[333];
   double W[333];

次に、それらを適切に埋める必要があります。関数を適切なステップでサンプリングして、それらを (x, f(x)) で埋める必要があると思いました。しかしもちろん、これはあまり意味がありません。コードはあいまいであるとすでに言っています(今は、コーダーの意図をリバースエンジニアリングしようとはしません...)。

とにかく、で呼び出すとWORK(d, W)、配列が十分に大きいため、セグフォルトは発生しません。結果は間違ったものになりますが、これは追跡が難しくなります (繰り返しますが、「リバース エンジニアリング」はありません)。

最終的な注意 (コメントからも): を持っている場合はdouble a[N]atypeを持っていますdouble *

于 2011-06-26T19:07:31.020 に答える
0

C では、アクセスしてはならないメモリの一部にアクセスしようとすると、セグメンテーション違反エラーがよく発生します。式が原因であると思われd[N_X_POINTS] ます (C の配列はゼロ インデックスであるため) が、 の定義をd確認しないと確信が持てません。

printf関数内のコードの各行の前後に有益なデバッグ ステートメントを挿入してみてください。これにより、問題の考えられる原因を絞り込むことができます。

于 2011-06-26T19:01:17.220 に答える
0

$f(x) = x^2$ を [0..10] の範囲で積分する簡単なプログラムを次に示します。それはあなたを正しい方向に送るはずです。

#include <stdio.h>
#include <stdlib.h>

double int_trapezium(double f[], double dX, int n)
{
   int i;
   double sum;

   sum = (f[0] + f[n-1])/2.0;
   for (i = 1; i < n-1; i++)
       sum += f[i];
   return dX*sum;
}

#define N 1000
int main()
{
    int i;
    double x;
    double from = 0.0;
    double to = 10.0;
    double dX = (to-from)/(N-1);
    double *f = malloc(N*sizeof(*f));

    for (i=0; i<N; i++)
    {
        x = from + i*dX*(to-from);
        f[i] = x*x;
    }
    printf("%f\n", int_trapezium(f, dX, N));
    free(f);
    return 0;
}
于 2011-06-26T19:46:09.393 に答える