- ベストアンサー
引数の個数を変えないで変数(定数)を扱う
別に積分に限らないと思うのですが、積分を例にして質問させていただきます。 次のようなルーチンがあります。 integral( double (*func)(double), double a, double b ); /* a~bまで関数funcを積分する。 */ そこで、簡単に被積分関数を fx=3*x とすれば、 double fx(double x) { return 3*x; } というようにすれば良いですよね。 でも、例えば fx = exp(x-X) とか fx = x*X のような関数を積分したいときはどうすればよいのでしょうか? Xは変数ですが、xにはよらないので積分の中では定数とみなせます。 ループで X=0 のときにfxを積分 X=1 のときにfxを積分 X=2 のときにfxを積分… というようにしたいのですが、 fxの引数をfx(double x, double X) とすると、プロトタイプ宣言もルーチンの中も書き換えなければならなくなりますよね。 さらに fx = x-X + x' などとなったりすると、さらに書き換えなければならなくなり、せっかくの積分のルーチンをうまく使えません。 Xをグローバルで宣言する方法と、 プログラミングの前に、x-X を x' などと置きかえた式を実際に手計算で作る方法を思いついたのですが、 グローバル変数を使うのはあまりよくないし、手計算では簡単な場合しか置換を思いつかなかったりします。 fxの中で X を宣言して、 double fx(double x) { static double X; double y; y = x-X; X++; return y; } という方法も考えたのですが、どうもイマイチ良くないような… こういう場合に、良い方法はありますか? ここには簡単な関数を書きましたが、少し複雑な関数を積分するので。 質問の意図がうまく伝わらなかったらすいません。 書きにくかったです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> fxの中の *(double*)params > がどういう扱い方をしているのか教えていただけないでしょうか? たとえば f(x) = x * X で X が 3.0 のとき、integral を使うには: double f(double x, void* params) { double X = *(double*)paramsl return x * X; } ... double X = 3.0; double result = integral(f, &X, a, b);
その他の回答 (3)
- bikkuri
- ベストアンサー率33% (23/68)
現状から大きく変わるので、単なる案です。 C++もありと考えると、積分関数を定義して渡すのではなく、 関数をメソッドとして実装している関数オブジェクトを integral関数に渡すと、面白いかもしれません。 ・実行しようとする関数のオブジェクトを生成 ・定数など必要な物をオブジェクトに設定 ・integralにオブジェクトと範囲a,bを渡す ・integralでは、オブジェクト内の関数メソッドをcall(名前は固定) ・関数オブジェクトではパラメータxと内部の定数で値を返す みたいな感じです。 Cでも、構造体(or共用体)で似た実装をすることは可能でしょう。 (構造体中に関数ポインタと定数メンバを設ける感じ)
- ranx
- ベストアンサー率24% (357/1463)
integralのインターフェースを変えないという前提で考えると、 外部static変数を使うのはどうでしょう。 static double X; double fx(double x) { ・・・ } void setParameter(double p) { X = p; } というようにしておけば、Xはこのソースファイルの外からは直接アクセスできません。 integralを呼び出す前に予めsetParameterでXをセットしておきます。
お礼
回答ありがとうございます。 外部staticを使うのですか。 考慮してみます。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
僕ならこうする: integral( double (*func)(double,void*), void* params, double a, double b ); { ... (*func)(x,params); ... } double fx(double x, void* params) { double X = *(double*)params; ... } void* params を介して受け渡します。
お礼
回答ありがとうございます。 でも、すいません。 初心者なので、このプログラムがよく分からないです。 (*func)(double, void*), void* params, の宣言は何を意図しているのか。 fxの中の *(double*)params がどういう扱い方をしているのか教えていただけないでしょうか? すいません。
お礼
いろいろありがとうございました。