• ベストアンサー

関数へのポインタ

C言語で科学計算をやらなければならない状況になりました。 そこで質問です。 ものすごく基本的なことだと思うのですが・・・ aからbまで積分をするルーチンが以下のように与えられています。 float qromb(float (*func)(float), float a, float b) { ・・・・・ } これを使うときの呼び出し方がわからないのです。 a,bは積分の下限・上限なので例えば 0,1 として、 s= qromb(float (*func)(float), 0, 1 ); のようにすればいいと思うのですが、 (*func)(float) の部分がよくわかりません。 例えば、f(x)=x を0~1で積分するようなときは、 どのような宣言をして、どのようにルーチンを呼び出せばいいのでしょうか。 またこの(*func)(float) は何を意味しているのでしょうか? とても基本的なことだとは思うのですが、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
noname#5537
noname#5537
回答No.1

float (*func)(float) とあれば,func は float 型の引数を1つとって, float 型の戻り値を返す関数へのポインタです。 というわけで,float 型の引数を1つとって, float 型の戻り値を返す関数を定義して, そのポインタを qromb に渡せばいいです。 float f(float x) {   return x; } // s = qromb(f, 0, 1);

yassan_yassan
質問者

お礼

早速の回答ありがとうございます。 分かりました。 引数宣言の中にさらに()が入っているのを見るのが初めてだったもので。 やっぱりC言語はポインタがキーですよね? 使えるように勉強します・・・

その他の回答 (1)

  • ret
  • ベストアンサー率40% (8/20)
回答No.2

#1の方が説明されていますね。 関数名を引数としてそのまま渡せばいいです。 qsort関数もこのうちの一つですね。 void qsort ( void * base, size_t num, size_t width, int (*fncompare)(const void *, const void *) ); float qromb(float (*func)(float), float a, float b); とあれば 引数にfloatを1つ取り、float型を戻り値とする関数を 別に用意しなければいけません。

yassan_yassan
質問者

お礼

ありがとうございました。 できました。

関連するQ&A

  • 関数へのポインタで

    関数を場合によって使い分けたくて, 次のようにしています. double f1(double x) { return 3*x; } double f2(double x) { return 5*x; } double f3(double x) { return 10*x } /* 同じようにg1, g2, g3があります. */ 次のようなルーチンを使って, void sub(double (*F)(double), ...) { F(a); F(b); } int main() { double (*func_f[])(double)={f1, f2, f3}; double (*func_g[])(double)={g1, g2, g3}; sub(func_f[i], ...) } といった感じにしています. いま,f1*g2のような関数に対してsubを使いたいのですが,この場合はどのようにすればいいのでしょうか? (f1*g2)を一つの関数として扱えることができればいいと思うのですが,方法がわかりません. 教えて下さい. よろしくお願いします.

  • 関数の掛け算を返す関数

    いま関数の積分を行おうとしています. この積分を行う関数が 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個にすると,汎用性が失われてしまうと思うので,できればそこは変えたくないです. どのようにすればよいのでしょうか? また,「考え方を変えればよい」などの意見も頂きたいです. 皆様,どうぞよろしくお願いします.

  • 引数の個数を変えないで変数(定数)を扱う

    別に積分に限らないと思うのですが、積分を例にして質問させていただきます。 次のようなルーチンがあります。 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; } という方法も考えたのですが、どうもイマイチ良くないような… こういう場合に、良い方法はありますか? ここには簡単な関数を書きましたが、少し複雑な関数を積分するので。 質問の意図がうまく伝わらなかったらすいません。 書きにくかったです。

  • 関数を引数とする方法?

    いつもお世話になっています。 MFCでプログラムをしています。 今、任意の関数(Func1)を 積分する関数(Func2)を作っています。 現在は、被積分関数の数だけ、 積分関数(Func2)を書いているのですが、 非効率的なので、なるべく汎用性を持たせたいと 考えています。 参考書(新C言語入門シニア編)の該当個所で、 クラスでない通常の関数を引数とする場合は、 うまくいったのですが、 クラスのメンバ関数を引数とした場合、 どうしてもコンパイルエラーが 発生してしまいます。 関数Func、I及びエラーメッセージは大凡次のとおりです。今のところ、引数とする関数(Func1)の引数は、 同一個数としています。 <被積分関数の例> double ClassA::Func1 (double a){ return a * 10; } <積分関数> double ClassA::Func2 (double (*f)(double), double a, double b){ return b * f(a); } void classA::Integration() { ... Func2(Func1,a,b); ... } <エラーメッセージ> classA::Integrationの呼び出し箇所で、 「1番目の引数を double(double)からdouble(__cdecl)(double)に 変換できません」 と出ます。 double(double)の部分は合っているようなのですが、 (__cdecl)の部分が違うということまでは 分かりました。 メンバ関数であることが原因のようなので、 Func2での引数宣言を double ClassA::Func2 (double (ClassA::*f)(double), double a, double b){ return b * f(a); } に変えてみたところ、 引数受け渡しのところはクリアするのですが、 Func2(Func1,a,b); の呼び出し時に、Func2が関数ではないという エラーがでます。 アドバイス又は参考URL等を 教えていただければ助かります。 よろしくお願いします。

  • main関数の中でパラメータを宣言

    c言語で積分をしています。 a~bまで積分する関数を dobule integral(double (*f)(double), double a, double b) { ・・・・・・ return s; /*sが計算結果*/ } としています。 fx=x*x を積分するときは double fx(double x) { return x*x; } を用意して、 main() { double ans = integral(fx, 0.0, 1.0); } という具合で現在やっています。 本題なのですが、 main関数の中でxを宣言して、そのxで同じように積分をしたいのです。 どうすればよいのでしょうか? 良い方法があれば教えて頂きたいです。

  • VBで、関数を関数の引数にするは?

    VBで関数の引数に、関数を呼ぶにはどのようにすればいいでしょうか?  例えば以下のようなイメージです   DEF FUNC1(X)=X^2   DEF FUNC2(F,a,b)=F(a)+F(b)     関数FUNC2では、関数Fを引数にする     つまりFUNC2(FUNC1,1,2)は     FUNC1(1)+FUNC1(2)=1^2+2^2=5 こんな感じです。 お教えください。

  • c言語 関数宣言

    c言語で書かれたプログラムを見ていると、ちょっとわからない関数宣言がでてきました。 関数宣言をしているのだと思うのですが、これはいったいどういうことなのでしょうか。 grad_pf(x, a, yfit, dyda, ma) float x; float a[]; float *yfit; float dyda[]; int ma; {            処理・・・・・・・・ } 中括弧の前で宣言された変数はどういったものなのでしょうか。 よろしくお願いいたします。

  • 関数の書き方と使い方

    Nを引数として受け取り、 y=1+x+x^2+x^3+...+x^N ただし |x|<1 を計算する関数 float func1(float x, int N) を定義してその動作を確認するプログラムkadai3-1.cを書きなさい。 ただしNとxはキーボードから次で入力するものとする。 scanf("%f %d", &x, &N); 答えは以下で出力されるものとする。 printf("answer = %f\n", answer); 実行例 $ gcc kadai3-1.c $ ./a.out 0.1 5 answer = 1.111110 よろしくお願いいたします。

  • ポインタなどからの比較。

    この2つのプログラムとその実行した場合の結果を、変数の型、値、アドレス、変数へのポインタなどの関係から比較して説明していただけますか? #include <studio.h> int main () {float a; float b; a = 0.0; b = 0.0; a = 10.0; printf("a = %f, b= %f, &a = %x, &b = %x\n",a,b,&a,&b); b = 20.0; printf("a = %f, b= %f, &a = %x, &b = %x\n",a,b,&a,&b); b = a; printf("a = %f, b= %f, &a = %x, &b = %x\n",a,b,&a,&b); 結果 a=10.000000, b=0.000000, &a=bffffaf4, &b=bffffaf0 a=10.000000, b=20.000000, &a=bffffaf4, &b=bffffaf0 a=10.000000, b=10.000000, &a=bffffaf4, &b=bffffaf0 ━━━━━━━━━━━━━━━━━━ #include <stdio.h> int main () {float a; float *b; a = 0.0; b = &a; a = 10.0; printf("a = %f, b= %f, &a = %x, &b = %x\n",a,*b,&a,b); *b = 20.0; printf("a = %f, b= %f, &a = %x, &b = %x\n",a,*b,&a,b); } 結果 a=10.000000, b=10.000000, &a=bffffaf4, &b=bfffaf4 a=20.000000, b=20.000000, &a=bffffaf4, &b=bfffaf4 お願いします!

  • 合成関数の積分

    こんにちは。積分法に関する質問です。 gが(a,b)において連続[a,b]において微分可能とし、g´(x)>0で、fもgの値域においては連続とするとき ∫f(g(x))g´(x)dx(積分範囲はaからb)=∫f(y)dy(積分範囲はg(a)からg(b))が成り立つことを示し、(Fоg)´(x)を計算せよという問題です。((Fоg)は合成関数) 今ヒントが与えられていて g(a)≦y≦g(b)において F(y)= ∫f(t)dt(積分範囲はg(a)からy)と置く。とあるのですが、このヒントをどう使うのかが分かりません。 それと(Fоg)´(x)の計算もお手上げです。 どなたかヒントよろしくお願いします。