関数ポインタで二重配列らしきものを作る

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

関数ポインタで二重配列らしきものを作る

#1

投稿記事 by namari » 10年前

http://dixq.net/rp/24.html
のように、

コード:

 
void (*boss_shot_bullet[DANMAKU_MAX])() =
{
     boss_shot_bulletH000,
     boss_shot_bulletH001,
};

boss_shot_bullet[boss.knd]

というものを、stageごとに作るために、

コード:

 
void (*boss_shot_bullet0[DANMAKU_MAX])() =
{
     boss_shot_bulletH000,
     boss_shot_bulletH001,
};

void (*boss_shot_bullet1[DANMAKU_MAX])() =
{
     boss_shot_bulletH004,
     boss_shot_bulletH006,
};

void (*boss_shot_bullet2[DANMAKU_MAX])() =
{
     boss_shot_bulletH007,
     boss_shot_bulletH011,
};

void (*boss_shot_bullet[STAGE_MAX][DANMAKU_MAX])() =
{
     ...//(ここが分からない)
};

boss_shot_bullet[stage][boss.knd]//このように使いたい


このように一度作った関数ポインタたちをさらにまとめた関数ポインタを扱いたいんですが、
いまいち方法が分かりません。
これも関数ポインタが理解できていないで使っているからなんでしょうが・・・。
ご教授していただけると嬉しいです。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 関数ポインタで二重配列らしきものを作る

#2

投稿記事 by みけCAT » 10年前

「らしきもの」ではなく、本物の二重配列ではいけないのですか?

コード:

#include <cstdio>

const int STAGE_MAX = 3;
const int DANMAKU_MAX = 2;

void boss_shot_bulletH000() {puts("000");}
void boss_shot_bulletH001() {puts("001");}
void boss_shot_bulletH004() {puts("004");}
void boss_shot_bulletH006() {puts("006");}
void boss_shot_bulletH007() {puts("007");}
void boss_shot_bulletH011() {puts("011");}

void (*boss_shot_bullet[STAGE_MAX][DANMAKU_MAX])() =
{
	{
		boss_shot_bulletH000,
		boss_shot_bulletH001,
	},{
		boss_shot_bulletH004,
		boss_shot_bulletH006,
	},{
		boss_shot_bulletH007,
		boss_shot_bulletH011,
	}
};
 

int main(void) {
	struct boss_t {
		int knd;
	} boss;
	int stage;
	for (stage = 0; stage < STAGE_MAX; stage++) {
		for(boss.knd = 0; boss.knd < DANMAKU_MAX; boss.knd++) {
			boss_shot_bullet[stage][boss.knd]();
		}
	}
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
namari
記事: 111
登録日時: 12年前

Re: 関数ポインタで二重配列らしきものを作る

#3

投稿記事 by namari » 10年前

みけCAT さんが書きました:「らしきもの」ではなく、本物の二重配列ではいけないのですか?

コード:

//略
すみません。条件が足りてなかったみたいです。

コード:

#define DANMAKU_MAX 50
void (*boss_shot_bullet0[DANMAKU_MAX])() =
{
     boss_shot_bulletH000,
     boss_shot_bulletH001,
     boss_shot_bulletH003,
};
 
void (*boss_shot_bullet1[DANMAKU_MAX])() =
{
     boss_shot_bulletH004,
     boss_shot_bulletH006,
};
 
void (*boss_shot_bullet2[DANMAKU_MAX])() =
{
     boss_shot_bulletH007,
     boss_shot_bulletH011,
     boss_shot_bulletH011,
     boss_shot_bulletH011,
     boss_shot_bulletH011,
};
 
void (*boss_shot_bullet[STAGE_MAX][DANMAKU_MAX])() =
{
     ...//(ここが分からない)
};
 
boss_shot_bullet[stage][boss.knd]//このように使いたい
このようにboss_shot_bullet0,1,2の中身の要素数がバラバラの状況なんですよね。
この場合、その方法だと要素数が一定じゃないとできないですよね?(おそらく・・・)
意味のないboss_shot_bulletH000で埋めて要素数を合わせることはできなくはないですが・・・。
すみません、後出しなことばかり言って・・・

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 関数ポインタで二重配列らしきものを作る

#4

投稿記事 by みけCAT » 10年前

namari さんが書きました:すみません。条件が足りてなかったみたいです。

コード:

#define DANMAKU_MAX 50
void (*boss_shot_bullet0[DANMAKU_MAX])() =
{
     boss_shot_bulletH000,
     boss_shot_bulletH001,
     boss_shot_bulletH003,
};
 
void (*boss_shot_bullet1[DANMAKU_MAX])() =
{
     boss_shot_bulletH004,
     boss_shot_bulletH006,
};
 
void (*boss_shot_bullet2[DANMAKU_MAX])() =
{
     boss_shot_bulletH007,
     boss_shot_bulletH011,
     boss_shot_bulletH011,
     boss_shot_bulletH011,
     boss_shot_bulletH011,
};
 
void (*boss_shot_bullet[STAGE_MAX][DANMAKU_MAX])() =
{
     ...//(ここが分からない)
};
 
boss_shot_bullet[stage][boss.knd]//このように使いたい
このようにboss_shot_bullet0,1,2の中身の要素数がバラバラの状況なんですよね。
この場合、その方法だと要素数が一定じゃないとできないですよね?(おそらく・・・)
この段階で既に配列の要素数はDANMAKU_MAXで一定なので、そのまま2次元配列にできるはずです。

コード:

#include <cstdio>

const int STAGE_MAX = 3;
#define DANMAKU_MAX 50

void boss_shot_bulletH000() {puts("000");}
void boss_shot_bulletH001() {puts("001");}
void boss_shot_bulletH003() {puts("003");}
void boss_shot_bulletH004() {puts("004");}
void boss_shot_bulletH006() {puts("006");}
void boss_shot_bulletH007() {puts("007");}
void boss_shot_bulletH011() {puts("011");}

void (*boss_shot_bullet[STAGE_MAX][DANMAKU_MAX])() =
{
    {
		boss_shot_bulletH000,
		boss_shot_bulletH001,
		boss_shot_bulletH003,
    },{
		boss_shot_bulletH004,
		boss_shot_bulletH006,
    },{
		boss_shot_bulletH007,
		boss_shot_bulletH011,
		boss_shot_bulletH011,
		boss_shot_bulletH011,
		boss_shot_bulletH011,
    }
};

const int boss_shot_bullet_num[STAGE_MAX] = {3, 2, 5};

int main(void) {
    struct boss_t {
        int knd;
    } boss;
    int stage;
    for (stage = 0; stage < STAGE_MAX; stage++) {
    	printf("----- stage %d\n", stage);
        for(boss.knd = 0; boss.knd < boss_shot_bullet_num[stage]; boss.knd++) {
            boss_shot_bullet[stage][boss.knd]();
        }
    }
    return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 関数ポインタで二重配列らしきものを作る

#5

投稿記事 by みけCAT » 10年前

本当にバラバラな要素数の配列をまとめたい
(例えば200要素程度の配列が数本あり、他の配列は5要素程度で、
要素数を統一すると無視できないレベルの無駄な領域が生じる場合など)
のであれば、配列(の先頭要素)へのポインタの配列を作ると良いでしょう。

コード:

#include <cstdio>

const int STAGE_MAX = 3;

void boss_shot_bulletH000() {puts("000");}
void boss_shot_bulletH001() {puts("001");}
void boss_shot_bulletH003() {puts("003");}
void boss_shot_bulletH004() {puts("004");}
void boss_shot_bulletH006() {puts("006");}
void boss_shot_bulletH007() {puts("007");}
void boss_shot_bulletH011() {puts("011");}

void (*boss_shot_bullet0[])() =
{
	boss_shot_bulletH000,
	boss_shot_bulletH001,
	boss_shot_bulletH003,
};

void (*boss_shot_bullet1[])() =
{
		boss_shot_bulletH004,
		boss_shot_bulletH006,
};

void (*boss_shot_bullet2[])() =
{
	boss_shot_bulletH007,
	boss_shot_bulletH011,
	boss_shot_bulletH011,
	boss_shot_bulletH011,
	boss_shot_bulletH011,
};

void (**boss_shot_bullet[STAGE_MAX])() =
{
	boss_shot_bullet0,
	boss_shot_bullet1,
	boss_shot_bullet2,
};

const int boss_shot_bullet_num[STAGE_MAX] = {
	sizeof(boss_shot_bullet0)/sizeof(boss_shot_bullet0[0]),
	sizeof(boss_shot_bullet1)/sizeof(boss_shot_bullet1[0]),
	sizeof(boss_shot_bullet2)/sizeof(boss_shot_bullet2[0]),
};

int main(void) {
    struct boss_t {
        int knd;
    } boss;
    int stage;
    for (stage = 0; stage < STAGE_MAX; stage++) {
    	printf("----- stage %d\n", stage);
        for(boss.knd = 0; boss.knd < boss_shot_bullet_num[stage]; boss.knd++) {
            boss_shot_bullet[stage][boss.knd]();
        }
    }
    return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
namari
記事: 111
登録日時: 12年前

Re: 関数ポインタで二重配列らしきものを作る

#6

投稿記事 by namari » 10年前

>>みけCATさん
なるほど!最後の対策みたいなものが必要だと思っていたのですが、
最初のように{}で囲めば次の行に進めるんですね!
てっきり初期化の際には最後まで埋める必要があるのかと思っていました・・・。

また最後の方法も勉強になりました。さらにポインタを取ればいいんですね。
今まで全く考えてなかった関数ポインタも新たに使えるようになっていけそうです。ありがとうございました。

閉鎖

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