C言語何でも質問掲示板の方でちょっと気になった投稿があったので…。
http://dixq.net/forum/viewtopic.php?f=3&t=14855
投稿者さんもポインタで躓いているようだったのでちょっと覗いてみたんです。
まずポインタ変数を宣言していないのはどうなんでしょうか…。
void PLAYER::GetPosition(double *x,double *y){
*x=this->x;
*y=this->y;
//DrawFormatString(50,50,GetColor(255,255,255),"player差出座標(%f,%f)",this->x,this->y);
}
おそらくこの部分でポインタ変数を宣言した…ということなのかもしれませんが、これで行けたっけなぁ…とちょっと困惑気味だったり。void PLAYER::GetPositionより外側に取ってきたい変数があったとしたらこれはうまく機能してくれるのか?と、思ったり。
まあ、勉強中の身なので間違った点で見ているかもしれないので、おとなしく解決になるまで見守ろうかと思います。(ついでに私も勉強させてもらおう…)
…でも、何の意図があって自機の現在の座標が必要になったのかちょっとよくわからなかったです。(ポインタにすることで何か利点があるのか?)
ピチューンしたら初期位置に戻る方式なら別に現在の位置は必要ないと思ったんですが…リトライで同じ位置から復活したいのか?とも考えたけど…リトライしますか?って画面の時に座標を捨てずに置いておけばなんとかできるんじゃないかなぁ…とか思ったり。
3Dならわからないんですが、xyしかないのを見るに2Dゲームだと思うのですけれど…。
何かポインタ変数にすることで利点が生まれるのでしょうか?おしえてーかしこい人ー
ポインタはまだよくわかってないですが…
RE: ポインタはまだよくわかってないですが…
適当にコードを書いて試したところ、この書き方は別に問題ないと思います。annojyou さんが書きました:void PLAYER::GetPosition(double *x,double *y){
*x=this->x;
*y=this->y;
//DrawFormatString(50,50,GetColor(255,255,255),"player差出座標(%f,%f)",this->x,this->y);
}
おそらくこの部分でポインタ変数を宣言した…ということなのかもしれませんが、これで行けたっけなぁ…とちょっと困惑気味だったり。
#include
struct AsumiKana {
double x,y;
AsumiKana();
AsumiKana(double xx,double yy);
void movexy(double dx,double dy);
void getxy(double* x,double* y);
};
AsumiKana::AsumiKana() {
x=y=0;
}
AsumiKana::AsumiKana(double xx,double yy) {
x=xx;
y=yy;
}
void AsumiKana::movexy(double dx,double dy) {
x+=dx;
y+=dy;
}
void AsumiKana::getxy(double* x,double* y) {
*x=this->x;
*y=this->y;
}
int main(void) {
double bx,by;
AsumiKana mizuhasu(100,200);
mizuhasu.getxy(&bx,&by);
printf("%f,%f\n",bx,by);
mizuhasu.movexy(20,50);
mizuhasu.getxy(&bx,&by);
printf("%f,%f\n",bx,by);
return 0;
}
Re: ポインタはまだよくわかってないですが…
みけCATさん
書き方自体には問題はないんですね…勉強になります。
ふと思ったんですが、int型をdouble型に代入しなおしてやればさっきのプログラムは動くんじゃないかと思ったんですが…どうなんでしょう?
見たところint型をdouble型に置き換えてるのにdouble型にint型を代入する処理をして無いっぽいので、動かないのかなぁ…と。
int x,y;
double xx = x, yy = y;
とすれば動く…かも?しかし自信はないので書かない(`・ω・´)
書き方自体には問題はないんですね…勉強になります。
ふと思ったんですが、int型をdouble型に代入しなおしてやればさっきのプログラムは動くんじゃないかと思ったんですが…どうなんでしょう?
見たところint型をdouble型に置き換えてるのにdouble型にint型を代入する処理をして無いっぽいので、動かないのかなぁ…と。
int x,y;
double xx = x, yy = y;
とすれば動く…かも?しかし自信はないので書かない(`・ω・´)
Re: ポインタはまだよくわかってないですが…
#include "pch.h"
#include "player.h"
#include "control.h"
PLAYER::PLAYER(){
gh=LoadGraph("dat/画像/自機/001.png");
psgh=LoadGraph("dat/画像/自機/ショット/0.png");
memset(shot,0,sizeof(shot));
speed=3.0; //スピード
count=0;//カウント
//初期位置
x=180;
y=420;
//追加したdouble型
double xx = x;
double yy = y;
//移動制御
sayu=zyoge=0;
naname=1.0;
life=true;// 生きてるかどうか
for(int i=0;ixx;
*yy=this->yy;
//DrawFormatString(50,50,GetColor(255,255,255),"player差出座標(%f,%f)",this->xx,this->yy);
}
と、書いてたけどxyの型書いて無くね?と困惑中…何型なんだろう。
とりあえずせっかく書き換えたし投下。
► スポイラーを表示
最後に編集したユーザー annojyou on 2014年3月23日(日) 19:10 [ 編集 1 回目 ]
Re: ポインタはまだよくわかってないですが…
これだけでは、どう見ても動かなそうな予感ですね。annojyou さんが書きました:一部分だけ書き換えてみたけど、こんな風にすれば動きそうな予感。
なぜPLAYER::GetPosition関数の中でPLAYER::PLAYER関数のローカル変数の値が取得できると考えるのでしょうか…?
いや、仮に取得できるとしても、むしろx,yの値がxx,yyに反映されず常に初期値が返りそうですし…?
(◕‿‿◕)わけがわからないよ。
Re: ポインタはまだよくわかってないですが…
この日記を書いたかたは本当に全くポインタがわかっていないようですから、あまりいじめちゃダメですよみけさん。
質問の方は、GetPosition関数ではなくそれを呼び出す場所に問題があると思います。そもそも初期座標が返ってきておかしくない時に呼び出しているんじゃないですかね。そんな気がします。
質問の方は、GetPosition関数ではなくそれを呼び出す場所に問題があると思います。そもそも初期座標が返ってきておかしくない時に呼び出しているんじゃないですかね。そんな気がします。
Re: ポインタはまだよくわかってないですが…
いろいろわかってないですね…ポインタのお勉強をちょっとずつしていかないと。
さっき出したやつのローカル変数の値が取得…とかは全然わからないです…。でもとりあえず入門からやっていこうかと。
(しかし…ポインタって勉強してても実感がわかないなぁ…。)
さっき出したやつのローカル変数の値が取得…とかは全然わからないです…。でもとりあえず入門からやっていこうかと。
(しかし…ポインタって勉強してても実感がわかないなぁ…。)
Re: ポインタはまだよくわかってないですが…
ポインタは自分も理解できませんでした。というか、現在進行形で理解できていません。
自分はコードを書いて書いて書きまくり、そのコードの中で少しずつポインタを使って、そのうちに慣れてくるはず!作戦をとっています。
習うより慣れよ ってことです。
自分はコードを書いて書いて書きまくり、そのコードの中で少しずつポインタを使って、そのうちに慣れてくるはず!作戦をとっています。
習うより慣れよ ってことです。
► スポイラーを表示
Re: ポインタはまだよくわかってないですが…
annojyouさんの場合、ポインタ以前にスコープについての知識が足りないかと思います。
このように関数内部で変数を宣言した場合、それはローカル変数になります。thisポインタからアクセスすることはもちろんできませんし、この場合コンストラクタを抜ける時点でxxとyyは破棄されます。
スコープがわからないということは多くの基本的なローカル変数の寿命について正しく判断できない事を示します。そうなるとまだポインタを考えるのは早いと思います。ポインタとは変数のアドレスの事ですから、寿命についてわかっていない段階で触るべきではありません。
3D_3Dさんが書いていますが、質問先の内容の書き方はいくつか問題があります。本題から逸れるのでトピックの一貫性を保つために指摘はしませんでしたが。 まず、違いとしてはconst指定です。Getという名前なのに関数内部でDrawなどという関数を呼び出しているのは明らかに呼び出し側からは想像できない挙動です。3D_3Dさんのようにconst指定をすれば少なくとも何かの書き換えが起きないことを保証できます。
ポインタを引数に取る場合ですが、これはどちらかと言うとC言語的な書き方になります。C++ではこうは書かないです。ポインタを引数にしてしまうとconst性に支障も出ます。もちろんポインタを引数に取る場面はありますが、C++ではあまり良い例ではありません(C言語的書き方をしていくスタイルなら問題ないと思いますが)。
C++で書く方法は幾つもあります。幾つかあげときますね。
ポインタがわからないと参照はわからないと思いますが…。掲示板はあまり見ませんが日記は見てるので、ポインタについてわからないところがあったら日記にしてみれば私や私より熟練の方が返事をくれると思います。もちろん掲示板でもいいですよ。
スコープがわからないということは多くの基本的なローカル変数の寿命について正しく判断できない事を示します。そうなるとまだポインタを考えるのは早いと思います。ポインタとは変数のアドレスの事ですから、寿命についてわかっていない段階で触るべきではありません。
3D_3Dさんが書いていますが、質問先の内容の書き方はいくつか問題があります。本題から逸れるのでトピックの一貫性を保つために指摘はしませんでしたが。 まず、違いとしてはconst指定です。Getという名前なのに関数内部でDrawなどという関数を呼び出しているのは明らかに呼び出し側からは想像できない挙動です。3D_3Dさんのようにconst指定をすれば少なくとも何かの書き換えが起きないことを保証できます。
ポインタを引数に取る場合ですが、これはどちらかと言うとC言語的な書き方になります。C++ではこうは書かないです。ポインタを引数にしてしまうとconst性に支障も出ます。もちろんポインタを引数に取る場面はありますが、C++ではあまり良い例ではありません(C言語的書き方をしていくスタイルなら問題ないと思いますが)。
C++で書く方法は幾つもあります。幾つかあげときますね。
// 3D_3Dさん的書き方。doubleの場合はコピーでもポインタと速度は変わらないですが、クラス宣言内部またはinline指定をすべきです。
inline double PLAYER::getX() const
{
return this->x;
}
// 構造体にして返す コピーコストがあるがプリミティブ型のみなので問題ない
struct Position
{
double x;
double y;
};
Position PLAYER::getPosition() const
{
return Position{ this->x, this->y };
}
// tuple
std::tuple PLAYER::getPosition() const
{
return std::make_tuple( this->x, this->y );
}
// 仮にサイズの大きい変数を返す場合、const参照させる方が効率的ではある(ただしPLAYER変数が生きている間しか参照は有効でない)
const BigVar& PLAYER::getBigVar() const
{
return this->bigVar;
}
Re: ポインタはまだよくわかってないですが…
ポインタがピンと来ないなら,とりあえず
「ポインタなんか無くても書けるよ派」になってみるとか.
(脳内シミュレーション的な意味で.本当になってしまってはダメですよ!)
自分でも60%くらい何言ってるかわからない感じですが,
ある機能を使わないというのは一種の「縛り」状態だと思うので もしかすると
そうすることで逆にその機能のありがたみとか意味とかがわかったりして…みたいな?
例えば,「おまえは自分で関数を作ることを禁ずる」と言われたら
そんな苦行命令を下した者を呪うと同時に,「くそっ,こんなとき関数があれば…!」と2分に一回くらいの頻度で思うでしょう.
ポインタでも同じように「ポインタさえあれば…!」とか思った時点でポインタのことがわかってるというかそういう謎の仕組み.
「ポインタなんか無くても書けるよ派」になってみるとか.
(脳内シミュレーション的な意味で.本当になってしまってはダメですよ!)
自分でも60%くらい何言ってるかわからない感じですが,
ある機能を使わないというのは一種の「縛り」状態だと思うので もしかすると
そうすることで逆にその機能のありがたみとか意味とかがわかったりして…みたいな?
例えば,「おまえは自分で関数を作ることを禁ずる」と言われたら
そんな苦行命令を下した者を呪うと同時に,「くそっ,こんなとき関数があれば…!」と2分に一回くらいの頻度で思うでしょう.
ポインタでも同じように「ポインタさえあれば…!」とか思った時点でポインタのことがわかってるというかそういう謎の仕組み.
Re: ポインタはまだよくわかってないですが…
関数を作ると、任意に関数を呼び出して使うことができますよね。
ポインタを使うと、任意の変数を処理対象にすることができます。
関数はコンパイル時に存在しないとコンパイルエラーになりますが、ポインタはコンパイル時には存在しない変数も使えます。
だから実行するたびに変化するものに強いのです。
余談ですが、スコープとライフサイクルは混同しないように注意しましょう。
ポインタを使うと、任意の変数を処理対象にすることができます。
関数はコンパイル時に存在しないとコンパイルエラーになりますが、ポインタはコンパイル時には存在しない変数も使えます。
だから実行するたびに変化するものに強いのです。
余談ですが、スコープとライフサイクルは混同しないように注意しましょう。