データ隠蔽のために不完全型構造体を使っていますが
例えば上記のソースコードの場合、敵をたくさん出現させたいときに配列を使いたいですが構造体のサイズが分からないので配列は使えません
がんばってポインタ一つ一つに命名していってもいいのですが
それだと配列の添字とfor文を使った場合のように敵の処理を一度に済ませることができません
なにか良い方法はないのでしょうか?それとも複数のオブジェクトが欲しい場合に不完全型構造体を使うのが間違いなのでしょうか?
投げやりなのですが自分ではどんなに考えても調べても解決できませんでした
ご教授よろしくお願いします
不完全型構造体のポインタが複数ほしい
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 不完全型構造体のポインタが複数ほしい
そういう場合に使われるのが、ポインタを使ったリスト構造です。
struct tagEnemyの実体はmallocして、リスト構造体自体もmallocします。リスト構造体には、次のリスト構造体ポインタとstruct tagEnemy *Enemy;を持てば良いでしょう。
http://www9.plala.or.jp/sgwr-t/c/sec15-5.html
C++ならstd::listなど便利なライブラリがあるんですが、C言語は自分で実装してください。
struct tagEnemyの実体はmallocして、リスト構造体自体もmallocします。リスト構造体には、次のリスト構造体ポインタとstruct tagEnemy *Enemy;を持てば良いでしょう。
http://www9.plala.or.jp/sgwr-t/c/sec15-5.html
C++ならstd::listなど便利なライブラリがあるんですが、C言語は自分で実装してください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 不完全型構造体のポインタが複数ほしい
素直にポインタの配列ではダメなのでしょうか?
#include <stdio.h>
#include <stdlib.h>
struct tagEnemy *generateEnemy(int data);
void freeEnemy(struct tagEnemy *e);
void printEnemy(const struct tagEnemy *e);
int main(void) {
struct tagEnemy *Enemy[3];
int i;
Enemy[0] = generateEnemy(3);
Enemy[1] = generateEnemy(4);
Enemy[2] = generateEnemy(6);
for (i = 0; i < 3; i++) {
printEnemy(Enemy[i]);
}
for (i = 0; i < 3; i++) {
freeEnemy(Enemy[i]);
}
return 0;
}
struct tagEnemy {
int data;
};
struct tagEnemy *generateEnemy(int data) {
struct tagEnemy *e = (struct tagEnemy*)malloc(sizeof(struct tagEnemy));
if (e == NULL) exit(1);
e->data = data;
return e;
}
void freeEnemy( struct tagEnemy *e) {
free(e);
}
void printEnemy(const struct tagEnemy *e) {
if (e == NULL) {
puts("null");
} else {
printf("%d\n", e->data);
}
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 不完全型構造体のポインタが複数ほしい
敵の数の上限が決まっているなら、みけCATさんの方法をおすすめします。その方法の方がバグが少ないですから。[誤字修正]
【ご指摘ありがとうございます。敬称がもれておりました。みけCATさんすいません。】
【ご指摘ありがとうございます。敬称がもれておりました。みけCATさんすいません。】
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
-
- 記事: 19
- 登録日時: 8年前
Re: 不完全型構造体のポインタが複数ほしい
質問する前にみけCATさんのやりかたで試していたのですがコンパイルが通りませんでした
ですが、どうやらポインタ配列とは関係ないところの記述ミスが原因でコンパイルが通らなかったようです
お手数おかけしました 本当にすみません
(配列はサイズが分からないと宣言できないから、たとえ不完全構造体のポインタでも配列は作れないのかという
思い込みが自分の中にあったので記述ミスを探すのを怠っていました)
ただ、疑問なのですがお二人ともmallocを使用していますが、mallocを使用しない方法でもいいのでしょうか?
例えばtagEnemy構造体が定義されているファイルにstaticなtagEnemy構造体の実体を
置いておいて、その実体のアドレスをみけCATさんのコードでいうgenerateEnemy()で返してあげるという方法はアリでしょうか?
(みけCATさんのコードでいうとtagEnemyが定義されているファイルにstatic struct tagEnemy Enemy[3];と書いてあるということです)
キャラクターの表示数は決まっています 動的に要素数を変更する必要はないです
ですが、どうやらポインタ配列とは関係ないところの記述ミスが原因でコンパイルが通らなかったようです
お手数おかけしました 本当にすみません
(配列はサイズが分からないと宣言できないから、たとえ不完全構造体のポインタでも配列は作れないのかという
思い込みが自分の中にあったので記述ミスを探すのを怠っていました)
ただ、疑問なのですがお二人ともmallocを使用していますが、mallocを使用しない方法でもいいのでしょうか?
例えばtagEnemy構造体が定義されているファイルにstaticなtagEnemy構造体の実体を
置いておいて、その実体のアドレスをみけCATさんのコードでいうgenerateEnemy()で返してあげるという方法はアリでしょうか?
(みけCATさんのコードでいうとtagEnemyが定義されているファイルにstatic struct tagEnemy Enemy[3];と書いてあるということです)
キャラクターの表示数は決まっています 動的に要素数を変更する必要はないです
Re: 不完全型構造体のポインタが複数ほしい
エラーメッセージは読みましたか?ウーパールーパー山田 さんが書きました:質問する前にみけCATさんのやりかたで試していたのですがコンパイルが通りませんでした
ですが、どうやらポインタ配列とは関係ないところの記述ミスが原因でコンパイルが通らなかったようです
お手数おかけしました 本当にすみません
指す先の型にかかわらず、ポインタはサイズが(環境によって)決まっています。ウーパールーパー山田 さんが書きました:(配列はサイズが分からないと宣言できないから、たとえ不完全構造体のポインタでも配列は作れないのかという
思い込みが自分の中にあったので記述ミスを探すのを怠っていました)
だから配列も作れます。
もしサイズが決まっていなかったら、単体の も定義できないのではないでしょうか?
大丈夫だと思います。ウーパールーパー山田 さんが書きました:ただ、疑問なのですがお二人ともmallocを使用していますが、mallocを使用しない方法でもいいのでしょうか?
例えばtagEnemy構造体が定義されているファイルにstaticなtagEnemy構造体の実体を
置いておいて、その実体のアドレスをみけCATさんのコードでいうgenerateEnemy()で返してあげるという方法はアリでしょうか?
#include <stdio.h>
struct tagEnemy *generateEnemy(int data);
void printEnemy(const struct tagEnemy *e);
int main(void) {
struct tagEnemy *Enemy[3];
int i;
Enemy[0] = generateEnemy(3);
Enemy[1] = generateEnemy(4);
Enemy[2] = generateEnemy(6);
for (i = 0; i < 3; i++) {
printEnemy(Enemy[i]);
}
return 0;
}
struct tagEnemy {
int data;
};
static struct tagEnemy EnemyPool[3];
static int EnemyPoolIndex = 0;
/*
バッファオーバーランに注意。(ここではエラーチェックは省略)
やりたいことによっては、一度の呼び出しで配列全体に値(ポインタ)を設定するなど、もっといい設計があるかも。
*/
struct tagEnemy *generateEnemy(int data) {
struct tagEnemy *e = &EnemyPool[EnemyPoolIndex++];
e->data = data;
return e;
}
void printEnemy(const struct tagEnemy *e) {
if (e == NULL) {
puts("null");
} else {
printf("%d\n", e->data);
}
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 不完全型構造体のポインタが複数ほしい
実体がstaticでも構いません。
こんな案もあるという参考ですが、
struct tagEnemy *Enemy[3];自体もmain側でなくenemy側に有っても構わないです。
そうすれば、こういう関数でポインタ配列の先頭ポインタを返却できます。
struct tagEnemy **getEnemysArray();
こんな案もあるという参考ですが、
struct tagEnemy *Enemy[3];自体もmain側でなくenemy側に有っても構わないです。
そうすれば、こういう関数でポインタ配列の先頭ポインタを返却できます。
struct tagEnemy **getEnemysArray();
#include <stdio.h>
#include <stdlib.h>
#define ENEMY_ARRAY_NUMS 3
struct tagEnemy **getEnemysArray();
void printEnemy(const struct tagEnemy *e);
int main(void) {
struct tagEnemy **Enemy = getEnemysArray();
int i;
for (i = 0; i < ENEMY_ARRAY_NUMS; i++) {
printEnemy(Enemy[i]);
}
return 0;
}
struct tagEnemy {
int data;
};
static struct tagEnemy enemysArray[ENEMY_ARRAY_NUMS] = { {1},{2},{3} };
static struct tagEnemy *enemysPtrArray[ENEMY_ARRAY_NUMS];
struct tagEnemy **getEnemysArray() {
int i;
for( i=0 ; i<ENEMY_ARRAY_NUMS ; i++ ) {
enemysPtrArray[i] = &enemysArray[i];
}
return enemysPtrArray;
}
void printEnemy(const struct tagEnemy *e) {
if (e == NULL) {
puts("null");
} else {
printf("%d\n", e->data);
}
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 不完全型構造体のポインタが複数ほしい
あるいは敵構造体ポインタ自体を隠してしまって、外部には敵番号だけでやりとりするのも方法です。
その方が色々とシンプルかもしれません。
その方が色々とシンプルかもしれません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
-
- 記事: 19
- 登録日時: 8年前
Re: 不完全型構造体のポインタが複数ほしい
そうでした 迂闊でした、、、
それと毎度毎度コードを書いてくださりありがとうございます すごく分かりやすいです!
先に挙げてくれた先頭ポインタを返却する方法もそうですがどの方法を使えば一番スマートにsoftya(ソフト屋) さんが書きました:あるいは敵構造体ポインタ自体を隠してしまって、外部には敵番号だけでやりとりするのも方法です。
その方が色々とシンプルかもしれません。
書けるのか今、考えあぐねているところでしてまだ疑問に思うところがあって調べている最中ですので
「解決!」ボタンはまだ押しません ごめんなさい