ページ 11

関数呼び出しを簡略化したい

Posted: 2010年7月18日(日) 17:06
by オーシロ
STGの敵の射撃パターンを作っています。

射撃パターン番号で分岐させる処理を作っているのですが、
switch文で分岐するとソースが長くなる気がして嫌だなぁ、と思いました。
そこで、射撃パターンの関数の名前を

Enemy_ShotPattern_1(en_data *enemy)
Enemy_ShotPattern_2(en_data *enemy)
Enemy_ShotPattern_3(en_data *enemy)
という様に似たような名前にして、(en_dataは敵のデータの構造体です)

#define EN_SH_PT(x, y) Enemy_ShotPattern_x(y)
とマクロを宣言し、

EN_SH_PT(敵の射撃パターン番号, 敵のデータのアドレス);
と書くことで、分岐を簡略化できないかと思ったのですが、
Enemy_ShotPattern_xという関数は無い、とエラーが出てしまいました。

引数は同じにするつもりなので、関数ポインタの配列を使ってもいいかなとは考えました。
しかし結局それではソースが長くなるのではないかな、と考えました。

何かいい方法はないでしょうか?

そこまで凝った処理をする必要は無いとはわかっているのですが、どうにも気になったので。
わかりづらい質問かもしれませんが、よろしくお願いします。

Re:関数呼び出しを簡略化したい

Posted: 2010年7月18日(日) 17:38
by ドラ
こんな感じでしょうか?
マクロ定義の中に現れる"##"はトークン連結演算子です。

#include <stdio.h>
#define FUNC(x, y) func_##x(y)

void func_1(int n) { printf("func_1 : %d\n", n); }
void func_2(int n) { printf("func_2 : %d\n", n); }

int main(void)
{
FUNC(1, 123);
FUNC(2, 987);
return 0;
}

Re:関数呼び出しを簡略化したい

Posted: 2010年7月18日(日) 17:46
by ISLe
> #define EN_SH_PT(x, y) Enemy_ShotPattern_x(y)

#define EN_SH_PT(x, y) Enemy_ShotPattern_##x(y)


> 引数は同じにするつもりなので、関数ポインタの配列を使ってもいいかなとは考えました。
> しかし結局それではソースが長くなるのではないかな、と考えました。

ソースの再利用を考えたらこっちのほうが良いと思います。
この部分だけですべての判断はできないですけど。

Re:関数呼び出しを簡略化したい

Posted: 2010年7月18日(日) 18:01
by dic
ソースが長くなるとは
どのくらい長くなるのでしょう?
実際にソースにしてみてはどうでしょう?

案外 思ってたよりスムーズにいくかもしれません

Re:関数呼び出しを簡略化したい

Posted: 2010年7月18日(日) 20:03
by オーシロ
>ドラさん
トークン連結演算子なんてものがあったとは…勉強不足でした。
しかし、これで
EN_SH_PT(enemy.ShotPattern, &enemy)
とすると、そのままEnemyShotPattern_enemy.ShotPatternという様に置き換えられてしまう
ということが自分で調べてわかりました。(enemy.ShotPatternは弾の射撃パターン番号です)
やっぱりマクロでやるのは無理のようですね。
でも勉強になりました。ありがとうございます!

>ISLeさん
色々捻ってみようと思ったんですけど、関数ポインタにすることにします。

>dicさん
少なくともswitch文だと縦長になって見づらくなる気がしました。
でも自分がわかりやすいように書くのがやっぱり一番でしょうか。


皆さんレスありがとうございました。
また疑問ができたらここに書き込むかもしれませんので、そのときもどうぞよろしくお願いします。