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;
}
No.4ベストアンサー
- 回答日時:
こんな感じでしょうか。
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();
のような形になります。
完璧な回答をありがとうございました。test proofです。
もうひとつ、別の質問になるかも知れないのですが、javaでphpの
call_user_func_array()のようなことができればよいのですが・・・
つまり、関数名をstringで与えて動的に関数を呼び出す方法です。
No.14
- 回答日時:
/**
取り敢えずは、動くのを作ってみた。(但し、入力チェックは省略。)
ご参考までに・・・。
http://itpro.nikkeibp.co.jp/article/lecture/2007 …
http://lib.stwing.jp/archives/2006/02/call_user_ …
*/
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()の件は余談のつもりでしたのに丁寧にフォローして頂きありがとうございます、面白いです。大変有用で参考になります。
No.12
- 回答日時:
質問に対する回答じゃなくてすみませんが。
> 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にあまり慣れていません。
No.11
- 回答日時:
要するに、アプリケーションのレベルでの要求が、質問からはよーわからんから、Java的な良いお答えを書きようがない。
いちばんまともなのは、オブジェクトを作るか入手して、そのオブジェクトのpublicメソッドを呼ぶことです。staticメソッドなら、オブジェクトではなくpublicなクラス。
No.10
- 回答日時:
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の持つ強力な型チェック機能も台無しなので、平素な代替手段があるならそちらを使ったほうが良いです。
No.8
- 回答日時:
なんだか C 言語エライ貶されてますが、使われなくなった古代言語でもないし、その手法はまだまだ健在です。
まあ、古くからある言語なので、当時は「処理をブロックとして渡す」ための実装方法が関数ポインタだったわけですわ。
Java は Java の流儀に従ってコーディングすればいいんだけど、質問者さんの「C ではこう書いていたけど、Java ではどうするんだろう」っていう疑問が悪いとは思いませんよ。
この回答への補足
エライ所に議論が行っていますが・・・Cを古代言語、死語として卑下するのは多少引っかかります。アセンブラやCOBOLと比較している訳じゃないしJAVAと同じALGOL系で英語とフランス語のような関係です。またC→C++→C#と発展していますのでオブジェクト指向やポインタの議論は当らないと思います。何より重要なのはUNIX,Windows等多くのOSのベース言語であり色々な各種言語(compiler)がC/C++で書かれている事です。ただ、ウエブアプリケーションの開発に向かないのは確かですが。。。
補足日時:2008/02/19 08:45No.7
- 回答日時:
質問者様に申し訳ないのですが、_ranco_さんに賛同します。
Javaは比較的オブジェクト指向を強く意識した言語と思いますので、
処理を外部に委託しようとする関数ポインタはなじまないと
考えるのが筋と思います。(個人的な意見としてです)
デザインパターンの臭いがプンプンするJavaなので、Javaでの解決方法として
「○○パターンに書き換える」、という議論の方が本質と思います。
逆に言うと、Cで書けていることをあえて、なぜJavaで書き換えるのですか、
ということになると思います。
No.6
- 回答日時:
> 言語を比較しながら学ぶことは
多くの場合、古代言語との比較は、「現行の刑法で切腹と同等の刑を与える方法を教えてください」などの議論と同じで、最初からナンセンスです。
Methodクラス、CallableとFutureクラス、などを実際に小さなプログラムを書きながら勉強してみてください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「配列定数は、イニシャライザ...
-
Javaプログラムについての質問...
-
JAVA エラー 式の開始が不正で...
-
javaでcsvファイル読込時の改行...
-
Javaのファイル名チェックについて
-
Javaについて
-
Swing の実装でどうしてもエラ...
-
JFrameをフェードイン・フェー...
-
数学的な処理
-
【C#】フォームをなめらかに移動
-
JSPやサーブレットでSystem.out...
-
パソコンキーボードで時分秒を...
-
javaで質問です。 文字列2023/2...
-
Path型をString型へ変換する(Java)
-
変数を動的に利用するには?
-
VBAで配列の計算
-
C言語32bitから64bitの移行につ...
-
System.err. printlnとSystem.o...
-
動的配列が存在(要素が有る)か...
-
IF関数でEmpty値を設定する方法。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「配列定数は、イニシャライザ...
-
java spring でエラーが出て困...
-
Java 初心者 int型の取り扱い方
-
式の型は配列型で int に解決済...
-
DataSet(DataTable)の使い方
-
C#で、デリゲートからその関数...
-
6桁の数字を重複なしでランダム...
-
C#で実行時にメソッドの返り値...
-
JUnit4のアノテーションについて
-
行の途中から読み込む方法
-
Javaで電卓を作りたい
-
SwingでJtableのヘッダ行が表示...
-
javaでcsvファイル読込時の改行...
-
javaでカレンダー作成
-
ビープ音をなめらかに鳴らしたい
-
c# デリゲート関連の命名について
-
intが負の時に投げる例外はあり...
-
java 長さの異なる配列の代入
-
デスクトップのアイコンの位置...
-
【C#】フォームをなめらかに移動
おすすめ情報