• ベストアンサー

関数へのポインタで

関数を場合によって使い分けたくて, 次のようにしています. 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)を一つの関数として扱えることができればいいと思うのですが,方法がわかりません. 教えて下さい. よろしくお願いします.

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

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

>いま,f1*g2のような関数に対してsubを使いたいのですが,この場合はどのようにすればいいのでしょうか? >(f1*g2)を一つの関数として扱えることができればいいと思うのですが,方法がわかりません. sub自体が2つの関数のポインターを一気に受け取るようにするしかないと思います。subは2つの関数の戻り値の積を求めるようにしておきます。 例えば、以下のようにします。 typedef struct _tFADDR{ double (*func_f1)(double); double (*func_f2)(double); } FADDR; void sub(FADDR *F, double a,double b) { double a1,b1; (F->func_f1)(a) * (F->func_f2)(a);/* F(a)に相当*/ (F->func_f1)(b) * (F->func_f2)(b);/* F(b)に相当*/ } 関数の定義は、 double (*func_f[])(double)={f1, f2, f3}; の代わりに FADDR func_f [] = { {f1,c1},{f2,c1},{f3,c1} }; ようにします。c1は常に1を返す関数で、 double c1(double x) { return 1; } としておきます。 f1*g2のような関数は、 FADDR func_x [] = { {f1,g1},{f2,g2},{f3,c1} }; とします。 呼び出しは、 sub(&func_f[i], 1.0,2.0); のようにします。 但し、f1+g1とかf1/g1のようなものもやりたいのでしたら、この方法は、このままでは使えませんが・・・・

その他の回答 (3)

  • SoHeart
  • ベストアンサー率50% (13/26)
回答No.4

取り敢えず、subをそのまま使う形で考えてみました。 double xdat; double sub(double (*F)(double)) { return F(xdat); } double (*fnc_f)(double); /* f(x) */ double (*fnc_g)(double); /* g(x) */ double h(double x ) {  return fnc_f(x)*fnc_g(x); /* h(x)=f(x)*g(x) */ } int main() {  double (*func_f[])(double)={f1, f2, f3};  double (*func_g[])(double)={g1, g2, g3};  xdat=10;  /* 普通のsub */  printf("F(%f)=%f\n",xdat,sub(f1)); /* h(x)用のsub */  /* h(x) の f(x) と g(x) を代入 */  fnc_f = &f1; /* subの引数のとり方と異なるため */  fnc_g = &g1; /* f(x) g(x) は外にもってきました。 */  printf("F(%f)=%f\n",xdat,sub(h)); }

yassan_yassan
質問者

お礼

皆様回答ありがとうございます. どの回答も参考になります. ただ,私の質問の仕方が悪くて,少し意図と違っております. 一度締め切って,もう一度質問させていただこうかと思います. すいませんが,よろしくお願いします.

  • gimmick
  • ベストアンサー率49% (134/270)
回答No.2

ちょっと考えてみたのですが、次のような方法はどうでしょうか? テストしてないので誤りがあるかもしれませんが、考え方だけ 参考にしてください。 typedef double (*FUNC_DBL_DBL)(double); FUNC_DBL_DBL function_f; /*関数f_gが使う関数*/ FUNC_DBL_DBL function_g; /*関数f_gが使う関数*/ /*function_fとfunction_gにセットされた関数を使って計算する*/ double f_g(double x) {  return function_f(x) * function_g(x); } /*function_fとfunction_gに関数をセットし、関数f_gのポインタを返す*/ FUNC_DBL_DBL h(FUNC_DBL_DBL f, FUNC_DBL_DBL g) {  function_f = f;  function_g = g;  return f_g; } int main() {  double (*func_f[])(double)={f1, f2, f3};  double (*func_g[])(double)={g1, g2, g3};  /*略*/  sub(h(func_f[i], func_g[j]), ...); }

  • SoHeart
  • ベストアンサー率50% (13/26)
回答No.1

void sub_sample(double (*F)(double),double (*G)(double)) { printf("F=%f G=%f F*G=%f\n",F(10),G(20),F(10)*G(20)); } int main() { double (*func_f[])(double)={f1, f2, f3}; double (*func_g[])(double)={g1, g2, g3}; sub_sample(func_f[1],func_g[1]); } 参考にしてください。素粒子のスピン計算を作ってるんですか?

yassan_yassan
質問者

補足

回答ありがとうございます。 少し質問内容に補足させて頂きます。 sub(func, ...)は変更したくなくて、funcの指すものをf1とかg2に変えて処理を変えたいのです。 したがって、h(x)=(f1*g2)(x)というようにh(x)を作って、func=&h(x)としたいのですが。f1(x)*g2(x)のxはともに同じ値を取ります。 イメージとしては次のようなサブルーチンが作れればいいなぁって感じなのですが… void sample(double (*f)(double), double (g)(double)) { double (*func)(double) func=f*g } ちなみに、やってることは光の回折計算です。

関連するQ&A

  • C言語 ポインタ 関数

    キーボードから文字列”abcdefg”を入力し、main関数で配列aryに格納する。 main関数から配列aryの先頭アドレスを副関数に引き渡す。 副関数で配列aryの最後尾の要素の内容を';'に変更する。 main関数で配列aryの内容を表示する。 この問題が解けません... #include <stdio.h> int main (void) { char ary[]="abcdef"; int *p; int i,x; p=&ary[0]; func(&i); for (x=0;x<=7;x++){ printf("%s",ary[x]); void func (int i) if(i==\0) i=';' else i++ } return 0 } とりあえずこんな感じなんですけど、出来ませんでした...

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

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

  • 関数ポインタについて

    C言語の関数ポインタの問題で以下のような問題で、実際に解いて、プログラムを動かしてみてみました。 正常に動作したのですが、この回答では満点はもらえませんでした。 このほかに良い解答例などありましたら、教えていただけないでしょうか。 どうかよろしくお願い致します。 [問題]次の※1・※2を埋めなさい(「func1」,「func2」は解答に含まれないように書くこと)。 #include <stdio.h> void func1() { printf("func1\n"); } void func2() { printf("func2\n"); } void func(int no) { void (*func[2])(void) = {func1, func2}; /* ※1 (*func[no])() */; } int main() { /* ※2 func(1) */; return 0; } 実行結果:func2

  • ポインタ、関数、アドレス・・・

    はじめまして。 今微分方程式を解かせるプログラムを作る上で、関数に配列を渡したいと考えています。(多変数微分方程式なので) そのため、ポインタを学び、何となくそれについて分かってきたつもりなんですが、いざ試しのプログラムで、コンピュータがちゃんと値を返してくれるかを試しているのですが、どーもうまく値を返してくれません。。。 下に僕が作ったプログラムを載せますので、問題点を指摘してもらえたらうれしいです。 このプログラムで、僕として返してもらいたい値は1.1111です。 よろしくお願いします /******ソースプログラム******/ #include<stdio.h> #include<math.h> double f(int *x); void main() { double x[5]; x[0] = 0.0; x[1] = 1.0; x[2] = 2.0; x[3] = 3.0; x[4] = 4.0; printf("%f \n", f(x)); (←ここらへんがおかしいと言われます。。。) } double f(int *x) { int i; double z=0.0; for(i=0 ; i<=4 ; i++) { z += pow(0.1,*(x+i)); } return(z); }

  • 関数のポインタのポインタ・・・

    main内部を変更してはならない。 関数setとsetsetで、3.140000と表示させよ gcc -Wallでいろいろと探したのですが /bin/などと表示されていて、何を直せばいいのか、わからない状態です。 簡易c言語だと 3.139999 = 3.140000 となります どこかで0.000001を足すのでしょうか? でもxで3.14で出てますしね。むしろなぜ3.13999が出てきたのか。 ただ学校のコンパイラだとセグメントエラが出ます #include <stdio.h> void out(double **); void set(double *,double **); void setset(double **,double ***); int main() { double x; double *p; double **pp; x = 3.14; set(&x, &p); setset(&p, &pp); out(pp); return 0; } void set(double *x,double **p) { *p = x; } void setset(double **p,double ***pp) { **pp = *p; } void out(double **pp) { printf("%f = 3.140000\n", **pp); }

  • C 関数とポインタ

    ポインタと関数がよく分かりません。 (日本語がおかしくてすみません(^_^;)) たとえば↓のようなプログラムで、 #include <stdio.h> void increase(int *i); int main(void) { int x = 3; increase(&x); printf("%d\n", x); return 0; } void increase(int *i) { (*i)++; } 結果は4になりますが、increase(&x)が&xとなっていて、 関数はvoid increase(int *i)でint *iになっているのですが、 これはvoid increase(int *i)はint型の「ポインタ」なので、 increase(&x)も&xと「アドレス」を渡さなければいけないということですか?? そして、void increase(int *i)内では、アドレス&xの指す値をインクリメント、という考えで良いのでしょうか?

  • 【C++】関数ポインタの代入

    C++の関数ポインタについて質問です。 下記のように関数ポインタを宣言し、3通りの代入を行ってみました。 (3)のように関数名の頭に&を付けた場合と(2)のように&を付けなかった場合で 全く動きが同じになってしまうのですが、何故なのでしょうか? ------------------------------------------ #include "stdafx.h" #include <iostream> using namespace std; void Func1(){ cout<<"Func1が呼ばれました。"<<endl; return; } int main() { //(1) void (*fp1_1)(); fp1_1 = Func1; fp1_1(); //(2) void (*fp1_2)()=Func1; fp1_2(); //(3) void (*fp1_3)()=&Func1; fp1_3(); getchar(); return 0; }

  • bccでエラー:メンバー関数は呼び出すかそのアドレスを~

    クラスのメンバ関数を、ある関数(実は qsort)の引数として渡したい と思っています。環境は OS:Windows XP コンパイラ:C++Builder6 に付属の bcc32.exe です。 下記のコード(t.cpp)をコマンドプロンプトで bcc32 t としてコンパイルすると「※1」の行で下のエラーになります。 「エラー E2235 t.cpp 29: メンバー関数は呼び出すか  そのアドレスをとらなければならない(関数 main() )」 どのように直せば良いでしょうか? -------------------------------------------------------- #include <stdio.h> #include <stdlib.h> class Aclass { public: void f(int); }; void Aclass::f(int x) { printf("classfunc %d\n", x); } void sub1(int x) { printf("sub-1 %d\n", x); } void call_func(void(*func)(int), int x) { func(2*x + 1); } void main(void) { call_func((void(*)(int))sub1, 11); Aclass *a = new Aclass; call_func((void(*)(int))a->f, -7); //※1 delete a; } -------------------------------------------------------- この掲示板、行頭の空白が削除されてしまいますねー。

  • 関数とポインタについて

    #include <stdio.h> void test(int *p); int main() { int i; test(&i); printf("%d",i); return 0; } void test( int *p) { static int k; k = 10; p = &k; } このようなプログラムを作って、void test()のkの値をmain関数で受け取りたいのですが、どのようにすればよいのかわかりません。 どなたか教えていただけませんか?

  • 教えてポインタ

    例えば、以下のようなソース。 関数の中で、引数のポインタに値を入れてmainに戻す。 とても簡単なものです。 void func(int *N) {  *N=0; } main {  int  *N=1;  func(N);  printf("%d",*N) } 疑問は、ここからです。 (1)void func(int  *N) (2)void func(int*  N) (3)void func(int*  &N) 上記は、何が違いますか? なお、当方のVS2010で同じソースを作ると、 (1)の場合、エラーになります。(func関数の*N=0のところでダウン) (2)だと、OKになります。 (3)は、なに?

専門家に質問してみよう