ポインタが苦手で、解決法が分かりません。 どなたか、力を貸して下さい。 以下、サンプルです。 #include "stdio.h" #include "string.h" typedef struct { int a; int b; char c[32]; } DATA_T; void Code001(); void Code002(); int Code003(DATA_T *tData1, DATA_T *tData2); DATA_T tData[10]; void Code001() { int i; memset(&tData, 0, sizeof(tData)); for(i=0;i<5;i++){ tData[0].a = 1; } return; } void Code002() { DATA_T *tData1 = NULL; if( 0 == Code003(tData1, &tData[0]) ){ printf("1-%08x\n", tData1); printf("2-%08x\n", &tData); // ---(1) } return; } int Code003(DATA_T *tData1, DATA_T *tData2) { int i; for(i=0;i<10;i++){ // ---(2) if( tData2->a == 0 ){ tData1 = tData2; // ---(3) return (0); } tData2++; } return (1); } int main(int argc, char* argv[/url]) { char aaa[64]; Code001(); Code002(); printf("おしまい: "); scanf("%s", aaa); return 0; } 分からないこと 1. (1)で、(3)のときの tData1 のアドレスが返らない(NULLのまま) 2. (2)で、10ではなく配列数を動的に取りたい 以上、よろしくお願いします。
ポインタが分かりません
ポインタが分かりません
Re:ポインタが分かりません
(2)malloc関数を使ってください。使い方は…
型 *p;
p=malloc(確保したい要素数*sizeof(型));
使い終わったら…
free(p);
とします。
(1)まず、(tData2->a == 0)の結果が偽ですから、その中の文は実行されませんし、関数にアドレスを渡しているわけですが、[color=White" size="6">アドレスは値[/color]なので、[color=White" size="6]書き換えても、それはコピーを書き換えた事になる[/color]のです。
つまり、元の変数のアドレスが変わることはありません。そもそも、変数のアドレスはコロコロ変わったりしません。
型 *p;
p=malloc(確保したい要素数*sizeof(型));
使い終わったら…
free(p);
とします。
(1)まず、(tData2->a == 0)の結果が偽ですから、その中の文は実行されませんし、関数にアドレスを渡しているわけですが、[color=White" size="6">アドレスは値[/color]なので、[color=White" size="6]書き換えても、それはコピーを書き換えた事になる[/color]のです。
つまり、元の変数のアドレスが変わることはありません。そもそも、変数のアドレスはコロコロ変わったりしません。
Re:ポインタが分かりません
流れを追うと
---------------------------
DATA_Tという構造体を定義した。
DATA_T型の配列 tData[10];を定義した。
void Code001()
では値の代入を行っている。戻り値はなし。
( tData[0].a = 1;なのでforでループさせたところで、[0]にしか代入していないが・・・)
void Code002()
{
DATA_T *tData1 = NULL;
(ポインタを宣言しているにも関わらず、代入する値(アドレス)がNULLって・・・メモリを破壊したいのでしょうか?)
if( 0 == Code003(tData1, &tData[0]) ){
printf("1-%08x\n", tData1);
printf("2-%08x\n", &tData); // ---(1)
}
Code003の戻り値が0の時に実施させると言うif文自体は問題なさそうですね。
ただ、Code003の第一引数がtData1なのでNULLが渡されることになりますね・・・。
int Code003の関数では・・・
tData2->a == 0は必ず偽を返します。
なぜなら、Code001で
tData[0].a = 1;
としているからです。
なので戻り値は
return (1);
を返し、結果、Code002のif文は必ず偽になり、printf文は実行されません。
また、main関数のコマンドライン引数とか、scanfとか全く意味を成さないように見えますが???
---------------------------
DATA_Tという構造体を定義した。
DATA_T型の配列 tData[10];を定義した。
void Code001()
では値の代入を行っている。戻り値はなし。
( tData[0].a = 1;なのでforでループさせたところで、[0]にしか代入していないが・・・)
void Code002()
{
DATA_T *tData1 = NULL;
(ポインタを宣言しているにも関わらず、代入する値(アドレス)がNULLって・・・メモリを破壊したいのでしょうか?)
if( 0 == Code003(tData1, &tData[0]) ){
printf("1-%08x\n", tData1);
printf("2-%08x\n", &tData); // ---(1)
}
Code003の戻り値が0の時に実施させると言うif文自体は問題なさそうですね。
ただ、Code003の第一引数がtData1なのでNULLが渡されることになりますね・・・。
int Code003の関数では・・・
tData2->a == 0は必ず偽を返します。
なぜなら、Code001で
tData[0].a = 1;
としているからです。
なので戻り値は
return (1);
を返し、結果、Code002のif文は必ず偽になり、printf文は実行されません。
また、main関数のコマンドライン引数とか、scanfとか全く意味を成さないように見えますが???
Re:ポインタが分かりません
回答有難う御座います。 > アドレスは値なので、書き換えても、それはコピーを書き換えた事になるのです DATA_T *Code003(int index, DATA_T *tData2); とかでしか、ポインタは返せないのかな・・・ > ( tData[0].a = 1;なのでforでループさせたところで、[0]にしか代入していないが・・・) 気付かなかった。 tData.a = 1; の間違い > (ポインタを宣言しているにも関わらず、代入する値(アドレス)がNULLって・・・メモリを破壊したいのでしょうか?) 理解不足ですね。 とりあえず何でも空にしようとするので・・・ > tData2->a == 0は必ず偽を返します。 そんなことはないと思うけど・・・。 tData2++; で、実質 tData.a を参照できてるはず。 > main関数のコマンドライン引数とか、scanfとか全く意味を成さないように見えますが??? 実行確認用。 Code003を汎用化して DATA_T tDataA[10]; DATA_T tDataB[20]; DATA_T tDataC[30]; とかから検索させたかったけども無理そうだ。 int Code003(int *index, DATA_T *tData2); if( 0 == Code003(&index, &tData[0]) ){ tData1 = &tData[index]; 的な逃げ方しかないのかな・・・。 1手間増えるけど。
Re:ポインタが分かりません
アドレスを代入させたい変数にポインタのポインタを利用すればいけるはずですよ。
ちょっとややこしくなるかもしれませんけど…
ちょっとややこしくなるかもしれませんけど…
void Code002() { DATA_T* pData1 = NULL; if (Code003(&pData1, &tData[0]) == 0) { if (pData1 != NULL) { printf("1-%08x\n", pData1); printf("2-%08x\n", tData); } } } int Code003(DATA_T** ppData1, DATA_T* pData2) { int i; for (i = 0; i < 10; i++) { if (pData2->a == 0) { *ppData1 = pData2; // ---(3) return 0; } pData2++; } return 1; }
Re:ポインタが分かりません
おっと、書き忘れていましたが、個人的な趣味の話になりますが、Code003関数に関しては、下記のような書き方の方が個人的には好きですね。まぁ、参考程度に…という事で(^_^;)
int Code003(DATA_T** ppData1, DATA_T* pData2) { int i; for (i = 0; i < 10; i++) { if ((pData2 + i)->a == 0) { *ppData1 = (pData2 + i); // ---(3) return 0; } } return 1; }
Re:ポインタが分かりません
> バグさん 欲しかったアドレスが返って来ました。 有難う御座いました。 (2)については、 int Code003(DATA_T** ppData1, DATA_T* pData2, int num); if (Code003(&pData1, &tData[0], sizeof(tData)/sizeof(DATA_T)) == 0) で、要素数も引数に混ぜます。 さすがにポインタから要素数を求めるのは無理か・・・
Re:ポインタが分かりません
要素数に関しては、静的に確保するにしろ、動的に確保するにしろ、プログラマ側が管理してやらなければいけない領域だと思います。ですから、毎回要素数を求めるよりは、定数なり変数なりで保持しておいた方が使い勝手のよい関数になると思いますよ。
Re:追記:敵の描画について
>敵の描画をアニメーションでやっている
というのはどういうことでしょうか?
また、何節の話ですか?
プロジェクトのダウンロードで全てダウンロードしても、不具合が起きますか?
というのはどういうことでしょうか?
また、何節の話ですか?
プロジェクトのダウンロードで全てダウンロードしても、不具合が起きますか?
Re:追記:敵の描画について
シューティングゲームの館http://dixq.net/s/に
ソースとプロジェクトのダウンロード(その1)
と
ソースとプロジェクトのダウンロード(その2)
がありますよね。プロジェクトが丸ごとダウンロード出来ますので、
ここから使用していただけるとコピーミスやコードのミスなどがありません。
ソースとプロジェクトのダウンロード(その1)
と
ソースとプロジェクトのダウンロード(その2)
がありますよね。プロジェクトが丸ごとダウンロード出来ますので、
ここから使用していただけるとコピーミスやコードのミスなどがありません。
Re:追記:敵の描画について
ありがとうございました。問題は解決しました。しかし、また新たな問題が発生しました。それは、シューティングゲームの館13節の敵を5枚の画像を時間差で表示して表現するというところです。
具体的にはプログラムを実行すると時が点滅します。
プログラム自体はサンプルをまねています。
開発環境はBCC Developerを使っています。
アドバイスよろしくお願いします。
具体的にはプログラムを実行すると時が点滅します。
プログラム自体はサンプルをまねています。
開発環境はBCC Developerを使っています。
アドバイスよろしくお願いします。
Re:追記:敵の描画について
計算の値を変更したらちゃんと動作しました。どうやら処理が間に合わなくて点滅していたようです。今まで私の質問に答えてくれた皆様、本当にありがとうございました。