- ベストアンサー
JAVAでCの関数ポインタのようなことをするには?
CのプログラムをJAVAに移植しています。関数ポインタのプログラムを移植したいのですがやり方がよく判りません。interfaceを実装するとできるようですが・・・ 以下のCプログラムをJAVAに移植する方法を教えてください。 #include <stdio.h> int func(int , int); int main() { int (*po)(int , int) , i; po = func; i = (*po)(10 , 3); printf("%d" , i); return 0; } int func(int i , int j) { return i + j; }
- kahata
- お礼率39% (66/168)
- Java
- 回答数14
- ありがとう数13
- みんなの回答 (14)
- 専門家の回答
質問者が選んだベストアンサー
こんな感じでしょうか。 static interface Func { int func(int i, int j); } static class FuncImpl implements Func { public int func(int i, int j) { return i + j; } } public static void main(String[] args) { Func po = new FuncImpl(); int i = po.func(10, 3); System.out.println(i); } ややこしいですね。 Javaにも関数ポインタがあればいいのに。 po に別の関数を代入したい場合は、 po = new AnotherFuncImpl(); のような形になります。
その他の回答 (13)
- choconamacream
- ベストアンサー率44% (152/338)
/** 取り敢えずは、動くのを作ってみた。(但し、入力チェックは省略。) ご参考までに・・・。 http://itpro.nikkeibp.co.jp/article/lecture/20070131/260145/ http://lib.stwing.jp/archives/2006/02/call_user_funcc.html */ import java.util.*; import static java.lang.System.*; abstract class Func{ void call_user_func_array(String method, int[] array){ Func po; int result = 0; if(method.equals("SubFunc")){ po = new SubFunc(); result = po.func(array[0], array[1]); }else if(method.equals("KoFunc")){ po = new KoFunc(); result = po.func(array[0], array[1]); }else if(method.equals("fnctn")){ KoFunc popo = new KoFunc(); result = popo.fnctn(array[0], array[1]); } System.out.println("\n結果は、" + result + "です。"); } abstract int func(int i, int j); } class SubFunc extends Func{ public int func(int i, int j){ return i + j; // 和 } } class KoFunc extends Func{ public int func(int i, int j){ return i - j; // 差 } public int fnctn(int i, int j){ // 自作メソッド。 return i * j; // 積 } } class Polymorphism{ // 多態性。 static public void main(String... $_){ // JDK5。 int[] test = {10, 3}; KoFunc c_u_f_a = new KoFunc(); Scanner scan = new Scanner(in); while(true){ System.out.println("\n 以下の何れかの文字を入力して、動的結合の開始。"); System.out.println("SubFunc"); System.out.println("KoFunc"); System.out.println("fnctn"); String line = scan.next(); c_u_f_a.call_user_func_array(line,test); System.out.println("\n\n// 終了は、「Ctrl + Z」か、「Ctrl + C」で。"); } } }
お礼
call_user_func_array()の件は余談のつもりでしたのに丁寧にフォローして頂きありがとうございます、面白いです。大変有用で参考になります。
- 神崎 渉瑠(@taloo)
- ベストアンサー率44% (1016/2281)
連続失礼。 > dummy.GetTimes()のところでシンボルを解決出来ないというコンパイルエラーでした。 エラーの原因はtypoでした○| ̄|_
- 神崎 渉瑠(@taloo)
- ベストアンサー率44% (1016/2281)
質問に対する回答じゃなくてすみませんが。 > ANo.2 参考サイト 読み直すと、インスタンスを生成して変数に入れるということをせずに、 関数呼び出しの引数のところで直接 new してるだけなのかなぁ。。 だとすると、オブジェクトを作ってそのメソッドを呼ぶのは関数ポインタとは関係なくて、 OOPそのものじゃないかなと思いますが。。。 (Raise2()の例が微妙ですが、、、) class Hand{ private int t; public void Hand(){ t=0; } public void Raise(){ t++; } public int GetTimes(){ return t; } } class Test{ public static void main(String[] arg){ Hand rHand=new Hand(); Hand lHand=new Hand(); rHand.Raise(); rHand.Raise(); lHand.Raise(); Raise2(lHand); System.out.println("Right hand has raised "+rHand.GetTimes()+" times); System.out.println("Left hand has raised "+lHand.GetTimes()+" times); //Hand dummy=rHand; //System.out.println("dummy "+dummy.GetTimes()+ "times); //エラー } public static void Raise2(Hand h){ h.Raise(); h.Raise(); } } dummy.GetTimes()のところでシンボルを解決出来ないというコンパイルエラーでした。 こういうのもダメなんですかねぇ > 逆に言うと、Cで書けていることをあえて、なぜJavaで書き換えるのですか、 質問者さんが何のために移植しようとされているのかは知りませんが、 たとえばWrite Once, Run Anywhereは移植の理由にはなりませんか?
補足
> 逆に言うと、Cで書けていることをあえて、なぜJavaで書き換えるのですか、 一つの理由はCで動いているある便利なプログラムをWebに載せるためですが、そこまで問い質さなくても単純な技術的質問と考えて頂いて結構です。 私の場合スタンドアロンのプログラミングはC/C++、ウエブはPHPで殆ど事足りており、JaVAを使うのはよほど特殊なケースでJAVAにあまり慣れていません。
- _ranco_
- ベストアンサー率58% (126/214)
要するに、アプリケーションのレベルでの要求が、質問からはよーわからんから、Java的な良いお答えを書きようがない。 いちばんまともなのは、オブジェクトを作るか入手して、そのオブジェクトのpublicメソッドを呼ぶことです。staticメソッドなら、オブジェクトではなくpublicなクラス。
- bgbg
- ベストアンサー率53% (94/175)
Class#getMethod で当該のメソッドを取得し、Method#invoke で実行します。 以下サンプル。printlnを使った例。 import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class QA3787147 { public static void main( String[] args ) { PrintStream out = System.out; try { // printlnメソッドのオブジェクト取得 Method aMethod = System.out.getClass().getMethod( "println", String.class ); // 引数の用意 Object[] arg = {"Hello world!"}; // 実行する。 aMethod.invoke( out, arg ); } catch ( SecurityException e ) { e.printStackTrace(); } catch ( NoSuchMethodException e ) { e.printStackTrace(); } catch ( IllegalArgumentException e ) { e.printStackTrace(); } catch ( IllegalAccessException e ) { e.printStackTrace(); } catch ( InvocationTargetException e ) { e.printStackTrace(); } } } Javaでの動的メソッドの取得実行(クラスも変数も同じような方法でできますが)は重いし面倒だしJavaの持つ強力な型チェック機能も台無しなので、平素な代替手段があるならそちらを使ったほうが良いです。
お礼
専門家らしいご回答をどうもありがとうございます。色々勉強させて頂きます。
詳しく調べていないのですが、 ClassクラスのgetMethodメソッドを使うと良さそうです。
- koko_u_
- ベストアンサー率18% (459/2509)
なんだか C 言語エライ貶されてますが、使われなくなった古代言語でもないし、その手法はまだまだ健在です。 まあ、古くからある言語なので、当時は「処理をブロックとして渡す」ための実装方法が関数ポインタだったわけですわ。 Java は Java の流儀に従ってコーディングすればいいんだけど、質問者さんの「C ではこう書いていたけど、Java ではどうするんだろう」っていう疑問が悪いとは思いませんよ。
補足
エライ所に議論が行っていますが・・・Cを古代言語、死語として卑下するのは多少引っかかります。アセンブラやCOBOLと比較している訳じゃないしJAVAと同じALGOL系で英語とフランス語のような関係です。またC→C++→C#と発展していますのでオブジェクト指向やポインタの議論は当らないと思います。何より重要なのはUNIX,Windows等多くのOSのベース言語であり色々な各種言語(compiler)がC/C++で書かれている事です。ただ、ウエブアプリケーションの開発に向かないのは確かですが。。。
- dyna_1550
- ベストアンサー率34% (122/353)
質問者様に申し訳ないのですが、_ranco_さんに賛同します。 Javaは比較的オブジェクト指向を強く意識した言語と思いますので、 処理を外部に委託しようとする関数ポインタはなじまないと 考えるのが筋と思います。(個人的な意見としてです) デザインパターンの臭いがプンプンするJavaなので、Javaでの解決方法として 「○○パターンに書き換える」、という議論の方が本質と思います。 逆に言うと、Cで書けていることをあえて、なぜJavaで書き換えるのですか、 ということになると思います。
- _ranco_
- ベストアンサー率58% (126/214)
> 言語を比較しながら学ぶことは 多くの場合、古代言語との比較は、「現行の刑法で切腹と同等の刑を与える方法を教えてください」などの議論と同じで、最初からナンセンスです。 Methodクラス、CallableとFutureクラス、などを実際に小さなプログラムを書きながら勉強してみてください。
- _ranco_
- ベストアンサー率58% (126/214)
そんなことより、アプリケーションのレベルの要求をJavaと照らしてよく見据えるべきです。関数ポインタなどより、もっと安全で堅牢な方法があるはず。私はC(などの古代言語)のナニナニをJavaで書くには?という話題が大嫌いです。真剣な開発にとって、無意味かつ無メリットだから。
補足
専門家らしい人からこんなことを言われると身も蓋もなくなります。初心者にとって言語を比較しながら学ぶことは、その言語の理解を深める上で当然あってよい手法です。
- 1
- 2
関連するQ&A
- Javaでポインタ的なことはできるか?
JavaでC言語のようにポインタを使おうとしたらJavaには ポインタが表面上はサポートされていないことを知りました。 関数を呼び出した際に、呼び出し元の変数に影響を与えるようなプログラムは Javaで作れるのでしょうか? 例えば、以下のプログラムはCで関数を呼び出した際に呼び出し元の 変数の中身を関数内で書き換えてしまうプログラムです。 こういうことをJavaでするにはどう書けばよいのでしょうか? もしこういうことができないのであれば、Javaにはポインタに代わるやりかたがあるのでしょうか? 実行結果: 1 10 #include <stdio.h> void func( int *n ){ *n = 10; } int main(){ int n = 1; printf("%d ", n ); func( &n ); printf("%d ", n ); }
- ベストアンサー
- Java
- 関数ポインタについて
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
- 締切済み
- C・C++・C#
- CでいうポインタみたいなことをJAVAでも・・・
Cでいうポインタを使ったプログラム #include <stdio.h> void nibai (int *a , int *b) { *a *= 2; *b *= 2; } int main(void) { int a=3 , b=5; nibai(&a,&b); printf("a=%d b=%d\n",a,b); return 0; } nibai関数はint型のアドレスを貰ってそのアドレスが指す値を書き換えているためmain関数に戻った際に値が変化している。 このようなことをJAVAでやりたいんですけど方法が見当たりません。 グローバルで共有するしか方法はないのでしょうか? CかつJAVAを知っている方限定の質問になってしまいますが よろしくお願いします。
- ベストアンサー
- Java
- 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++・C#
- c言語で大きな値の階数を求めたいのですが
c言語で関数を用いてn!を求めるプログラムを作ったのですが、 nの値が大きくなると0という値になってしまって正しい値が出てきません。 プログラムをどの様に修正したらきちんとnの値が大きくなっても 正しく値が表示されるでしょうか? ソースはこちらです。 #include <stdio.h> int func(int i); int func(int i){ if(i == 0) return 1; else return (i*func(i-1)); } void main(){ printf("%d",func(90)); /*90!を求める*/ } よろしくお願いします。
- ベストアンサー
- 数学・算数
- C言語の基本的な質問ですが、関数へのポインタの宣言
関数へのポインタの質問です。 下のように、関数へのポインタを使ったプログラムを書きました。 (関数へのポインタを理解するためのものなので、実用的な意味はありません。(*^_^*) また、このプログラムはコンパイルもリンクも実行も問題なく出来ます。) #include <stdio.h> int add_func(int,int); (*func_p0) (int,int); int main(void) { int (*func_p1) (int,int); int (*func_p2) ( ); int hoge0,hoge1,hoge2; func_p0=add_func; hoge0=func_p0(3,5); printf("0 : 3+5は%d\n",hoge0); func_p1=add_func; hoge1=func_p1(3,5); printf("1 : 3+5は%d\n",hoge1); func_p2=add_func; hoge2=func_p2(3,5); printf("2 : 3+5は%d\n",hoge2); return(0); } int add_func(int x, int y) { return(x+y); } func_p0のように戻り値の型を書かない場合と、func_p1やfunc_p2のように戻り値の型を書くのとでは何が違うのでしょうか。 func_p0は外部変数ですが、自動変数にする(main関数の中で同様に宣言。)とコンパイルエラーになります。 それはなぜですか。 func_p1のように引数の型が書いてあるのと、func_p2のように引数の型が書いていないのでは何が違うのでしょうか。 int (*func_p2) ( );というのは、int (*func_p2) (void);とは違うんですよね?
- 締切済み
- C・C++・C#
- 【C++】関数ポインタの使い方
関数ポインタの使い方で悩んでいます。 下記の (1)のようにグローバルメソッドとして定義したメソッドを関数ポインタに代入することは出来るのですが、 (2)のようにクラスのメンバメソッドとして定義したメソッドは関数ポインタに代入することは出来ませんでした。 Error:バインドされた関数へのポインターは関数の呼び出しにのみ使用できます。 というエラーが発生します。 関数ポインタに外部参照でメソッドを代入することは出来ないのでしょうか? -----(1)------------------------------------------------------------------ #include "stdafx.h" #include <iostream> using namespace std; int f(int a, int b){ return a * b; } int _tmain(int argc, _TCHAR* argv[]) { typedef int (* FUNC_POINTER)(int, int); FUNC_POINTER fp; fp = f; cout << fp(1,2) <<endl; getchar(); return 0; } ------------------------------------------------------------------------- -----(2)------------------------------------------------------------------ #include "stdafx.h" #include <iostream> using namespace std; class MPointerList{ public: int f(int a, int b){ return a * b; } }; int _tmain(int argc, _TCHAR* argv[]) { typedef int (* FUNC_POINTER)(int, int); FUNC_POINTER fp; //fp = f; MPointerList mP; fp = mP.f; cout << fp(1,2) <<endl; getchar(); return 0; } -------------------------------------------------------------------------
- ベストアンサー
- C・C++・C#
- ポインタ定義は必要なんですか?
#include <stdio.h> int main( void ) { int x; int *p; p = &x; printf("Address = %p\t\n", p ); return 0; } を #include <stdio.h> int main( void ) { int x; int p;←ここを上とはかえた p = &x; printf("Address = %p\t\n", p ); return 0; } にしたところコンパイル時に p = &x に関して 移植性のないポインタ変換と表記されますが 結果は同じだったのでポインタ定義というのは結局必要なんですか? 移植性のないポインタ変換とはなんなんですか? よければ詳しく教えてください
- ベストアンサー
- C・C++・C#
- 【C言語】別関数でポインタの値を変えたのに変わらない。
【C言語】別関数でポインタの値を変えたのに変わらない。 メイン関数のポインタの値を、別関数で書き換えるプログラムを作りました。 以下がそのプログラムになります。 そのままだと、ダブルポインタを操作する必要があるので分かり辛いです。なので、ダブルポインタをシングルポインタにしてからポインタの書き換えを行うようにしました。その結果、きちんとポインタの書き換えが出来なくなってしまいました。 なぜ出来なくなってしまったのでしょうか。 2つのプログラムの違いは、 > *pp = &dummy; が > p = *pp; // ダブルポインタをシングルポインタにした > p = &dummy; に変わっただけです。 【参考】http://www.kouno.jp/home/c_faq/c4.html#8 -----------------正しいプログラム---------------- // 以下プログラムは、正しく動作する // 実行結果は、 // p = 5 // と表示される void func( int **pp ); int main (void){ int *p; int a = 0; p = &a; func( &p ); printf("p = %d\n", *p); return 0; } void func( int **pp ){ static int dummy = 5; *pp = &dummy; } ---------------------------------------------- -----------------間違いプログラム---------------- // 以下プログラムは、正しく動作しない // 実行結果は、 // p = 0 // と表示される void func( int **pp ); int main (void){ int *p; int a = 0; p = &a; func( &p ); printf("p = %d\n", *p); return 0; } void func( int **pp ){ static int dummy = 5; int *p; p = *pp; // ダブルポインタをシングルポインタにした p = &dummy; } ----------------------------------------
- 締切済み
- C・C++・C#
お礼
完璧な回答をありがとうございました。test proofです。 もうひとつ、別の質問になるかも知れないのですが、javaでphpの call_user_func_array()のようなことができればよいのですが・・・ つまり、関数名をstringで与えて動的に関数を呼び出す方法です。