重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

いま関数の積分を行おうとしています.
この積分を行う関数が
double integral(double (*func)(double), double a, double b )
{
   double ans;
   .....
   return ans;
}
となっていて,aからbまでfuncが指す関数を積分して結果を返します.

積分をさせる関数は
double f1(double x)
{
return 3.0*x;
}

double f2(double x)
{
return x*x;
}
となっていて,同じようにg1, g2も用意します.(本当は関数が3つ4つあります.)

例えばf1を積分したいとき,
int main()
{
   double ans = integral(f1, a, b);
   printf("%f\n", ans);
}
ですよね.

自分で積分する関数を選ぶときは,ここに配列で場合分けをして
double (*func_f[])(double)={f1, f2};
scanf("%d", &flag); /* flagに0~1を代入 */
ans = integral(func_f[flag], a, b);
でいいと思います.

さて,そこで本題なのですが,
double (*func_f[])(double)={f1, f2};
double (*func_g[])(double)={g1, g2};
としておいて,
scanf("%d", flag1); scanf("%d", flag2);
func_f[flag1], func_g[flag2];
として関数を入力側から決定して,
(例えばflag1=1, flag2=1,であったとして
*func_f[1]=x*x *func_g[1]=5.0*x ならば)
h(x)=(x*x)*(5.0*x)=5.0*x*x*x
という関数を作って,
h(x)を指すポインタを double (*h_ptr)(double) とすれば
ans = integral(h_ptr, a, b);
としたいのです.

(f1*g2)を一つの関数としてh(x)=(f1*g2)(x)というように扱うことができればいいと思うのですが.
integralの引数で,関数のポインタを2個にすると,汎用性が失われてしまうと思うので,できればそこは変えたくないです.

どのようにすればよいのでしょうか?
また,「考え方を変えればよい」などの意見も頂きたいです.
皆様,どうぞよろしくお願いします.

A 回答 (5件)

動的に関数を作り出すことは出来ませんから、有り得る組み合わせの関数、f1g1(),f1g2(),f2g1(),f2g2() を


doube f1g1(double x) { return f1(x)*g1(x); }
等とすべて事前に定義しておく必要があります。
その上で、
double (*func[])(doube)={f1g1,f1g2,f2g1,f2g2};
として、
ans=integral(func[flag1*2+flag2],a,b);

この回答への補足

すいません.勘違いしていました.
引数とか関係ないですね.失礼しました.
この方法でいこうと思います.
ありがとうございました.

補足日時:2004/06/16 01:13
    • good
    • 0
この回答へのお礼

回答ありがとうございます.
f1g1を用意するときはどのようにするべきですか?
以下の方法では引数の数が異なってきてしまいますよね.
double f1g1(double x, double (*f1)(double), double (*g1)(double))
{
return f1(x)*g1(x);
}

お礼日時:2004/06/16 01:06

#4ですが、今読み直して、誤解があってはまずいと思いかいてます。

以下は自分自身が積分が不勉強なため作っては見たけど、自信ないです。間違ってるかもしれない。という意味で決してあなたのことをいってるのではないです。自分の場合コメントは次の行の説明として入れるのが習慣になってますので、もし誤解がありましたら、ご容赦願います。
----------
  /*
積分計算のつもりですが内容は微妙に
   間違ってると思いますので、直してください。
  */
ans = ans *
( ( F[i](b)*b ) - ( F[i](a)*a ) );
-----------
    • good
    • 0

関数を配列にしてはどうでしょう。



double sub(double (*F[])(double), double a, double b)
{
doubleans;
int i;

i = 0;
ans = 1;
while( F[i] != (void *)0 ){
  /*
積分計算のつもりですが内容は微妙に
   間違ってると思いますので、直してください。
  */
ans = ans *
( ( F[i](b)*b ) - ( F[i](a)*a ) );
i++;
}
return( ans );
}

int main()
{
/*
定義の部分で計算させたい関数を宣言しちゃいます。
 */
double (*func_list[])(double)={f1, g1, 0};

printf("∫( %f, %f ) = %f\n",
5.0, 10.0, sub( func_list, 5, 10 )
);
}
    • good
    • 0

いちおうこんな方法もありますが....



外部変数として
double (*f_selected)(double);
double (*g_selected)(double);
を, 被積分関数として
double mul_f_g(double x)
{
return f_selected(x) * g_selected(x);
}
を定義する. integral を呼出すときには
f_selected = func_f[flag1];
g_selected = func_g[flag2];
ans = integral(mul_f_g, a, b);
とする.

f_selected, g_selected を外部変数とするあたりが反則っぽいんですけど,
とりあえず目的は達成できるような.

C の範囲できれいにしようとするなら
double integral(double (*f)(double x, void *args), double a, double b, void *args);
とするんでしょうか.
    • good
    • 0
この回答へのお礼

回答ありがとうございます.
確かに外部変数を使えばできそうですね.
externを使ったりして,考慮してみます.
ちなみに,
>double integral(double (*f)(double x, void >*args), double a, double b, void *args);
この部分は全く同じようにしています.

お礼日時:2004/06/16 01:08

自分では使っていないのですが, C++ で boost を使うという手はあります.



#include <functional>
#include <boost/compose.hpp>

template <typename T>
double integral(T &func, double a, double b);

とでもしておいて (実装は現在と全く同じ), 実際に使うときには

ans = integral(
boost::compose_fx_gx(
std::multiplies<double>(),
std::ptr_fun(func_f[flag1]), std::ptr_fun(func_g[flag2])),
a, b);

でよかったかと思います. integral の第1引数がとても長いですが, これで
x を与えたときに func_f[flag1](x) * func_g[flag2](x) の値を返す関数オ
ブジェクトが作成されます.
    • good
    • 0
この回答へのお礼

回答ありがとうございます.
boostは初めて聞きました.初心者ですいません…
少しboostについて見てみたのですが,なかなか難しそうですね.
頑張って勉強していきます.

お礼日時:2004/06/16 00:58

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!