ページ 1 / 1
【龍神録】以下のプログラムの意味を教えてください!
Posted: 2014年7月16日(水) 17:12
by amehirune
ゲーム制作中、(忙しくてずっと後回しにしてましたが)意味の分からない文章があったので、
その部分についての解説をお願いしたく、投稿させていただいております。
こんなんなのかなー、というイメージは大雑把についているのですが、
やっぱり作るからには意味や構文を理解したいと思っています。
龍神録:第14章
コード:
void (*shot_bullet[SHOT_KND_MAX])(int) ={
shot_bullet_H000,
shot_bullet_H001,
shot_bullet_H002,
shot_bullet_H003,
shot_bullet_H004,
shot_bullet_H005,
shot_bullet_H006,
};
イメージとしては、配列の初期化と同じようなイメージなのかな、と思っているのですが…。
オフトピック
想像では、配列と同じように、「shot_bullet[0]にshot_bullet_H000のアドレスを記憶させる」…的な。
間違ってます…よね?
Re: 【龍神録】以下のプログラムの意味を教えてください!
Posted: 2014年7月16日(水) 20:48
by softya(ソフト屋)
配列ように見えるというのは、その通り間違いないです。これは関数ポインタの配列です。
なので「配列の初期化と同じようなイメージなのかな」の質問には、「配列の初期化そのものです」とお応えしておきます。
Re: 【龍神録】以下のプログラムの意味を教えてください!
Posted: 2014年7月17日(木) 12:31
by amehirune
回答ありがとうございます。
イメージはあっていたのですね。
では、
コード:
void (*shot_bullet[SHOT_KND_MAX])(int)
の、(int)はどういった意味を表しているのでしょうか?
intがdouble等になったら、どういった処理になるのでしょうか?
Re: 【龍神録】以下のプログラムの意味を教えてください!
Posted: 2014年7月17日(木) 13:08
by softya(ソフト屋)
そうですね。
勉強法として、まずdoubleに書き換えてやってみてください。コンパイルするとどうなりますか?
あと配列以前に関数ポインタを調べてみてください。
その上で関数ポインタやら関数ポインタの配列を色々と自分でZEROから書いて試してみてください。
あれこれやった上で分からないことを質問して頂くのが一番理解できて効率の良い方法だと思います。
「ふーん」で理解したつもりで終わらないためにも私はそうすべきだと思いますよ。
Re: 【龍神録】以下のプログラムの意味を教えてください!
Posted: 2014年7月17日(木) 18:45
by amehirune
回答ありがとうございます。一回、自分で「関数ポインタ」でサイト検索してみて、勉強してみました。
そして、勉強用に簡単なプログラムを作ってみました。
コード:
#include <stdio.h>
#define SUCCESS 0
#define FAIL -1
int wa(int a,int b){
return ( a+b );
}
int sa(int a,int b){
return ( a-b );
}
int seki(int a,int b){
return ( a*b );
}
int syou(int a,int b){
return ( a/b );
}
int amari(int a,int b){
return ( a%b );
}
int main(){
int a,b,select;
int(*func[])(int,int)={
wa,
sa,
seki,
syou,
amari,
};
printf("a>>");
scanf("%d",&a);
printf("b>>");
scanf("%d",&b);
printf("aとbの何を求めますか?\n");
printf("1:和 2:差 3:積 4:商 5:余\n>>");
scanf("%d",&select);
if( select>5 || select<1 ){
printf("ERROR!!\n");
return FAIL;
}
else printf("\n%d\n",func[select-1](a,b));
return SUCCESS;
}
(int,int)を(int)や(double,double)に変更したところ、
error C2440: '初期化中' : 'int (__cdecl *)(int,int)' から 'int (__cdecl *)(int)' に変換できません。
というエラーが発生しました。
また、上記5つの関数のうち、適当な1つの関数の戻り値をdoubleに変えてみたところ、同じようなエラーが表示されました。
このことから、関数ポインタの配列は引数および戻り値が同じものにしか適用できない、ということがわかりました。
オフトピック
自分で公式みたいにしてみました。
戻り値の型(*関数ポインタ配列名[最大要素数])(引数の型)
これであってますか?
Re: 【龍神録】以下のプログラムの意味を教えてください!
Posted: 2014年7月17日(木) 20:52
by softya(ソフト屋)
ここのところの仕組は関数ポインタも変数ですから型を持ちます。
関数ポインタ変数の場合は、戻り値の型も引数の型も合わせて関数ポインタ変数の型の一部となります。
なので、型が一致しない変数には代入できないのです。
> 戻り値の型(*関数ポインタ配列名[最大要素数])(引数の型)
そうですね関数ポインタ配列だとそれで合っています。
ただの関数ポインタ変数の場合は[最大要素数]がなくなります。
関数ポインタはコールバックするために引数にしたりする事もありますので結構使います。
最後に関数ポインタをtypedefしたりも出来ますので時間が有るときに研究してみてください。
Re: 【龍神録】以下のプログラムの意味を教えてください!
Posted: 2014年7月19日(土) 13:14
by amehirune
返信ありがとうございます。
おかげで、勉強法も含めて大変よくわかりました。
他にもわからない部分がありますが、そこは勉強したうえでどうしても…という部分だけお尋ねしようと思います。
ありがとうございました!