【龍神録】以下のプログラムの意味を教えてください!

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
amehirune
記事: 181
登録日時: 11年前
住所: どっか
連絡を取る:

【龍神録】以下のプログラムの意味を教えてください!

#1

投稿記事 by amehirune » 11年前

ゲーム制作中、(忙しくてずっと後回しにしてましたが)意味の分からない文章があったので、
その部分についての解説をお願いしたく、投稿させていただいております。
こんなんなのかなー、というイメージは大雑把についているのですが、
やっぱり作るからには意味や構文を理解したいと思っています。

龍神録:第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のアドレスを記憶させる」…的な。
間違ってます…よね?
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 【龍神録】以下のプログラムの意味を教えてください!

#2

投稿記事 by softya(ソフト屋) » 11年前

配列ように見えるというのは、その通り間違いないです。これは関数ポインタの配列です。
なので「配列の初期化と同じようなイメージなのかな」の質問には、「配列の初期化そのものです」とお応えしておきます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
amehirune
記事: 181
登録日時: 11年前
住所: どっか
連絡を取る:

Re: 【龍神録】以下のプログラムの意味を教えてください!

#3

投稿記事 by amehirune » 11年前

回答ありがとうございます。
イメージはあっていたのですね。

では、

コード:

void (*shot_bullet[SHOT_KND_MAX])(int)
の、(int)はどういった意味を表しているのでしょうか?
intがdouble等になったら、どういった処理になるのでしょうか?
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 【龍神録】以下のプログラムの意味を教えてください!

#4

投稿記事 by softya(ソフト屋) » 11年前

そうですね。
勉強法として、まずdoubleに書き換えてやってみてください。コンパイルするとどうなりますか?
あと配列以前に関数ポインタを調べてみてください。
その上で関数ポインタやら関数ポインタの配列を色々と自分でZEROから書いて試してみてください。

あれこれやった上で分からないことを質問して頂くのが一番理解できて効率の良い方法だと思います。
「ふーん」で理解したつもりで終わらないためにも私はそうすべきだと思いますよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
amehirune
記事: 181
登録日時: 11年前
住所: どっか
連絡を取る:

Re: 【龍神録】以下のプログラムの意味を教えてください!

#5

投稿記事 by amehirune » 11年前

回答ありがとうございます。一回、自分で「関数ポインタ」でサイト検索してみて、勉強してみました。
そして、勉強用に簡単なプログラムを作ってみました。

コード:

#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に変えてみたところ、同じようなエラーが表示されました。
このことから、関数ポインタの配列は引数および戻り値が同じものにしか適用できない、ということがわかりました。
オフトピック
自分で公式みたいにしてみました。
戻り値の型(*関数ポインタ配列名[最大要素数])(引数の型)
これであってますか?
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 【龍神録】以下のプログラムの意味を教えてください!

#6

投稿記事 by softya(ソフト屋) » 11年前

ここのところの仕組は関数ポインタも変数ですから型を持ちます。
関数ポインタ変数の場合は、戻り値の型も引数の型も合わせて関数ポインタ変数の型の一部となります。
なので、型が一致しない変数には代入できないのです。

> 戻り値の型(*関数ポインタ配列名[最大要素数])(引数の型)

そうですね関数ポインタ配列だとそれで合っています。
ただの関数ポインタ変数の場合は[最大要素数]がなくなります。
関数ポインタはコールバックするために引数にしたりする事もありますので結構使います。

最後に関数ポインタをtypedefしたりも出来ますので時間が有るときに研究してみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
amehirune
記事: 181
登録日時: 11年前
住所: どっか
連絡を取る:

Re: 【龍神録】以下のプログラムの意味を教えてください!

#7

投稿記事 by amehirune » 11年前

返信ありがとうございます。
おかげで、勉強法も含めて大変よくわかりました。
他にもわからない部分がありますが、そこは勉強したうえでどうしても…という部分だけお尋ねしようと思います。
ありがとうございました!
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

閉鎖

“C言語何でも質問掲示板” へ戻る