C言語とDXライブラリを利用したゲーム作成におけるポインタと配列の扱い方

このQ&Aのポイント
  • 初心者の方がC言語とDXライブラリを利用してゲームを作成している際に、GetMousePoint関数を利用してマウスの座標情報を配列に格納したいと考えています。しかし、ポインタと配列の扱い方について困っています。
  • 最初はアドレスを格納してしまったためにフリーズしてしまいましたが、ポインタを利用して配列に値を格納する方法を調べ、修正しました。しかし、再度フリーズが発生しました。また、ポインタの指すアドレスの中にある数値の取り出し方も理解できていません。
  • 一方、別の箇所でポインタの中身を利用して処理を行っている部分は問題なく動作しています。これはなぜでしょうか?【1】【2】【3】の処理についてアドバイスをいただきたいです。
回答を見る
  • ベストアンサー

DXライブラリ:ポインタと配列?

初心者です。よろしくお願いします。 C言語とDXライブラリを利用してゲームを作成中です。 GetMousePointの関数を利用して、マウスの座標がその時、どこにあったのか。という情報を配列に格納したい、と考えています。 リファレンスページを参照すると、 int GetMousePoint( int *XBuf, int *YBuf ); このように書かれているのですが、配列に格納しようとするとフリーズしてしまいます。 【1】 GetMousePoint(&x,&y); zahyou[i] = x; 最初上のようにしてフリーズしたため、ああ、アドレスを格納してしまったのか。と思いまして、 下のように直しました。 【2】 GetMousePoint(&x,&y); int *a = &x; zahyou[i] = *a; が、またフリーズが発生しました。ポインタを説明しているページを見てはいるのですが、ポインタの指すアドレスの中にある数値の取り出し方がイマイチ掴めません。 なぜか別の場所で処理している、 【3】 (x = x-230)/=40; x = x*40+250; このような処理に関しては動くのですが・・・。これはアドレスを直接に利用している、ポインタの中身を利用しているのではない、ような気がするのですが、なぜか動いています。 (上の処理より下の箇所で利用しています) 【1】【2】【3】のそれぞれがどう言った処理を行っていて、こうすれば良い。等のアドバイスをいただけないでしょうか。 あつかましいとは思いますが、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

static int x,y なら GetMousePoint(&x,&y); zahyoux[i] = x; zahyouy[i] = y; でいいはずですが。 // static である必要はあるのか? とか // zahyou[i] の宣言は? zahyoux[i] の間違い ? とか // struct point {int x;int y} zahyou[20] とかの方がいいのでは? とか ここでフリーズしているわけでは無いと思います。 これが原因だとしても、実際にフリーズするのは別の場所では? 例えば、このzahyouを使って何かを表示している箇所とか。 > GetMousePoint(&x,&y); > int *a = &x; > zahyou[i] = *a; これは GetMousePoint(&x,&y); zahyou[i] = x; とまったく同じです。 int *a = &x; で aはxへのアドレスとなり zahyou[i] = *a; で、 *a→(xへのアドレス)の実体→ xの実体 となるからです。 > (x = x-230)/=40; > x = x*40+250; ポインタはまったく関係ありません。 ただの数値演算です ところで (x = x-230)/=40; は意図してこうしたのですか? C++では間違いでは無いのですが...

mitara42k
質問者

お礼

配列の[i]部分で問題が生じているようでした。 zahyoux[i]の[i]部分に数字を入れればきちんと動作するのですが、そこに変数を入れるとフリーズしてしまうみたいです。 iには初期値0が与えられているのですが。 とりあえず、もう少し弄くってみたいと思います。 丁寧にありがとうございました。

mitara42k
質問者

補足

ううん。【1】でよかったとは思いませんでした。別の箇所なんですかね。Staticである必要はあります。補足で書いてあるプログラムは一部で、別の関数でもそれらを使用する予定、あるいはしている状態だからです。 >これは >GetMousePoint(&x,&y); >zahyou[i] = x; >とまったく同じです。 structは構造体の宣言でしたね。そういえばそんなものもありました。頭から抜け落ちてました。 【1】と【2】が同じとは、有難い助言です。 正直、何が何やら、で頭が沸騰していましたので。 >(x = x-230)/=40; >は意図してこうしたのですか? >C++では間違いでは無いのですが... 意図して書いてはいるんですが、改めてみると何かおかしいですね? C言語のみ利用しているつもりですので、直した方がいいんでしょうか。 問題なのは、 >ここでフリーズしているわけでは無いと思います。 >これが原因だとしても、実際にフリーズするのは別の場所では? >例えば、このzahyouを使って何かを表示している箇所とか。 ここでしか、このコードが書かれていない事なんです。 ちなみに実験的に動くかどうか、を試しで入れてみたので、別の場所で全く利用していません。 何かアホなミスをしているんでしょうか・・・。 前回は == を入れる所を = にしてしまっていて、半日悩みましたorz

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

群盲象をなでる状態になりそうな気がするので, 可能ならそのような問題を生じる短いプログラムを出した方がいいんじゃないでしょうか.

mitara42k
質問者

お礼

家に戻ったので色々とやってみた所、ポインタではなく配列の方で問題が生じているようでした。 ありがとうございました。

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.1

x,y,zahyouの型はなんですか? >zahyou[i] = x; iの値は問題ありませんか?

mitara42k
質問者

お礼

とりあえず、問題の箇所が判明しまして、アドバイスをいただけました。 ありがとうございました。

mitara42k
質問者

補足

それぞれ、 static int x,y; static int zahyou[20]; static int i=0; で宣言されています。 正確に書くならば、 static int x.y; static int zahyoux[20],zahyouy[20]; static int i=0; /*** ここから ***/ GetMousePoint(&x,&y); int *a = &x; int *b = &y; zahyou[i] = *a; //ここと zahyou[i] = *b; //ここ i++; if (i == 20) i=0; /*** ここまでの処理をマウスが離されたかどうか、を変数fと、GetMouseInput関数を利用して繰り返しています ***/ 右側にコメントを入れてある配列の箇所を除けば、問題なく動くことは確認してあります。きちんと座標も得られているようです。 単純にポインタの知識が不足しているものだと思っているのですが、違うのでしょうか。

関連するQ&A

  • 配列のポインタについて

    C言語で処理が下記のような処理を作成したいと思っております。 関数の引数によって、データを代入する配列を切り替えたいと考えております。 下記のような処理を考えた場合、if文の中・for文のbuffをどのように処理すれば よいでしょうか? アドバイスよろしくお願い致します。 int a[100][150]; int b[100][150]; void sample(int flg) { int i,j; unsigned short *buff; if(flg == 0){ buff = &a; }else{ buff = &b; } for( j=0 ; j<100 ; j++ ){ for( i=0 ; i<150 ; i++ ){ buff[y][x] = data; x++; } x = 0; y++; } }

  • ポインタ配列

    "one","two","three","four","five","six","seven","eight","nine","ten" のポインタ配列の文字列を、ASCIIコード順に並べ変えようと思ったのですが、 もうどこが間違っているかさえわからないぐらいになってしまいました。 まだまだはじめたばかりなもので、わからないことだらけなんで、 できるだけわかりやすい説明おねがいします。 関数の引数に問題があるのじゃないかと思ったのですが、 何かいいアドバイスありましたら、お願いします。 #include <stdio.h> /* 関数のプロトタイプ宣言 */ int strmp(char *,char *); void cpy(char *,char *); int main (void) { /* ポインタ配列の定義 */ char *x[10]={"oneee","twooo","three","fourr","fivee","sixxx","seven","eight","ninee","tennn"}; /* ポインタのポインタの定義 */ char **pp=x; char k[100]; char *p=k; int i,t,a,b,c,d; a=0; /* ポインタ配列を自作関数を使って、ASCIIコードの大きいほうからに並び替える */ for(i=0;i<9;i++) { for(t=1;t<10;t++) { a=strmp(*(pp+i),*(pp+t)); if(a<0) { cpy(p,*(pp+i) ); cpy(*(pp+i),*(pp+t) ); cpy(*(pp+t),p); } } } for(i=0;i<10;i++) { printf("%s ,",x[i]); } printf("\n"); return 0; } /* 文字の比較をする関数 */ int strmp(char *x,char *y) { int i; for(i=0;*(x+i)==*(y+i);i++) { if( *(x+i)=='\0') { return 0; } } return *(x+i)-*(y+i); } /* 文字をコピーする関数 */ void cpy(char *a,char *b) { int i; for(i=0;*(b+i)!='\0';i++) { *(a+i)=*(b+i); } *(a+i)='\0'; }

  • ポインタ配列

    配列をポインタでとって、配列要素を足していこうと思ったのですが、 #include <stdio.h> int main (void) { int p[11]={11,23,43,66,54,67,51,88,22,43,-1}; int *e=p; int x=0; int i=0; while( *e!=-1 ) { x + = ( * (e+i) ); i++; } printf("%d\n",x); return 0; } x = ( * ( e+i ) ); ↑この部分がなぜだめなのか理解できません どなたか教えてくださるとありがたいです

  • 2次元配列とポインタ配列の違い

    2次元配列とポインタ配列の違いを比較するプログラムを作成したつもりなのですが、下のプログラムの printf("we[%d]=%u\n",i,&we[i][0]); という文がどうやら違うらしいのですが、全く分かりません。 なので、なんとなくでも構わないので分かる方がいらっしゃったらお願いします。 #include<stdio.h> int main(void) { int i; char *we[]={"Monday","Tuesday","Wednesday"}; char ek[][10]={"Monday","Tuesday","Wednesday"}; printf("2次元配列で格納したアドレス\n"); for(i=0;i<3;i++){ printf("ek[%d]=%u\n",i,&ek[i]); } printf("ポインタ配列のアドレス\n"); for(i=0;i<3;i++){ printf("we[%d]=%u\n",i,&we[i]); } printf("ポインタ配列で格納したアドレス\n"); for(i=0;i<3;i++){ printf("we[%d]=%u\n",i,&we[i][0]); } printf("ポインタ配列で格納した文字列\n"); for(i=0;i<3;i++){ printf("we[%d]=\%s\n",i,we[i]); } printf("2次元配列で格納した文字列\n"); for(i=0;i<3;i++){ printf("ek[%d]=\%s\n",i,ek[i]); } return(0); }

  • できているとは、思うのですが。ポインタの配列を

    コンパイラではちゃんと動いてます。 1 2 3 0 1 2 3 という具合です。 気になるのは、printarrayの部分が正しいのか、ちょっと悩んでいます 問題としては main関数では0の値を読み込むまで最大99(MAX-1)個の値を配列 xに読み込んでいる。引数のポインタからの値を、値が0になるまで すべて1行に1つづつ画面に出力する関数printarray()を作成し、 プログラムを完成せよ。 引数はアドレスとして受け取る事。(配列としてでなく) フォーマットは、 "%d¥n" とする。(余計な出力はしない事。) (0は出力しない。) main内部を変更してはならない。 以下がソースです。 ご指摘よろしくお願いします。 #include <stdio.h> #define MAX 5 void printarray(int *); int main() { int x[MAX], i; int *p; x[MAX-1] = 0; for (i = 0, p = x; i < MAX-1; ++i, ++p) { scanf("%d", p); if (*p == 0) { break; } } printarray(x); return 0; } void printarray(int *a) { int i,*p; for(i = 0, p = a; i < MAX-1; ++i,++p) { if(*p == 0){ // continue; break; }else{ printf("%d\n", *(a+i)); } } }

  • 配列とポインタについて

    #include <stdio.h> int main() { char x[3]; char *y; x[0]='a'; x[1]='b'; x[2]='\0'; y="abc"; printf("xの値は%s\n",x); printf("yの値は%s\n",y); } 通常の配列宣言では、このままだと文字列をまとめて 代入できないのに対して、ポインタ変数ならまとめて代入することができるのは何故ですか?そういう仕組みだと言われてしまえば、それまでなんですが・・・

  • 助けてください ポインタと配列

    #include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 0}; int i, *ptr; ptr = &a[0]; while (*ptr!= 0){ if(*ptr!=0) *ptr=0; } for (i = 0; i < 5; i++) printf("a[%d]=%2d &a[%d]=%p\n",i,a[i],i,ptr); // 配列aの値とアドレスを表示せよ putchar('\n'); ptr = &a[0]; for (i = 0; i < 5; i++){ printf("ptr値 =%d ptrアドレス =%p \n",*ptr,ptr); ; } // ポインタptr を使用して、修正後の配列aの値とアドレスを表示せよ printf("\n"); return (0); } /* 処理結果 a[0]= 0 &a[0]=0013FF3C a[1]= 2 &a[1]=0013FF3C a[2]= 3 &a[2]=0013FF3C a[3]= 4 &a[3]=0013FF3C a[4]= 0 &a[4]=0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C 続行するには何かキーを押してください . . .*/ 一次元配列a[]の一番目の要素以外を0にするプログラムを作成せよ。 ただし、最後の要素は0とする。 上記の問題文とこの結果は合致しているでしょうか?

  • ポインタ配列の開放について

    いつもお世話になっております。 C++言語初心者です。 ポインタ配列の開放(delete)について質問です。 ※includeは省略します。 int main(){   int *a[10];   for(int i=0;i<10;i++){     a[i]=new int[5];   }   delete[] *a;   return 0; } ポインタ配列を開放する場合、 上記のような書き方で正しいのでしょうか? ただ、上記のような記述方法が間違っている場合、 for(int i=0;i<10;i++){   delete[] a[i]; } とやるのはスマートでない気がするので、 もし他に方法がありましたらお願いします。

  • 2次元配列とポインタの引数受け渡しについて

    2次元配列を関数に渡すときは、引数に渡す2次元配列と同じサイズを指定、もしくは2次元目のサイズのみ合わせて渡す方法がありますが、両方とも違うサイズで同じ関数を使いたいです。 最初は中身が同じで引数で受け取る2次元配列のサイズだけ、それぞれに合わせた引数を持つ関数を2つ作っていたのですが、なんだか冗長な気がしました。 そこで、2次元配列の先頭ポインタとサイズを受け取るようにすればいいのかと思い、テストとして次のプログラムを作成してみました。 #include <stdio.h> void func(unsigned char *a, int y, int x); int main(void) { unsigned char a[10][10]; func(a, 10, 10); printf("%d\n", a[7][4]); return 0; } void func(unsigned char *a, int y, int x) { int i, j; for (i = 0; i < y; i++) { for (j = 0; j < x; j++) { *(a + i*y + j) = i * j; } } } もちろんこれでも動くのですが、やはりこういう書き方はルールにはないので、コンパイルで警告が出ます。 a.c: In function ‘main’: a.c:10: warning: passing argument 1 of ‘func’ from incompatible pointer type a.c:4: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[10]’ このような書き方はやはりやめたいいのでしょうか。 また、その際はサイズ別に関数を作るしかないのでしょうか。 他にいい方法があれば教えていただけると助かります。

  • ポインタ配列のアドレスについて

    #include <stdio.h> int main() { int i; char *ary[] = { "a" , "b" , "c" }; for(i=0; i<3; i++) printf("%u\n" , &ary[i]); return 0; } /*実行結果 6618616 6618620 6618624 */ 上記のプログラムを実行したときポインタ配列*aryがchar型だろうがdouble型だろうがアドレスが4つとびになるのですがなぜなんでしょう?アドレスを求めるプログラム自体が間違っているのでしょうか?

専門家に質問してみよう