ポインタの使い方
こんばんは
研究の進捗がなく苦しんでおりますが、マウス関連の進捗はあるという本分を忘れている今日この頃です。
とりあえず、マウス関連でここ一週間やったことを書きます。
・迷路シミュレータ作り
・タイヤの径をφ48からφ44に変更(足回りの改善)
・C言語のポインタの理解と実装
こんな感じですかね。
⇒シミュレータ作りは、新たな探索方法を試すのに、将来有用だと思い作り始めました。Visual Studio を使ったり、ライブラリを使ったりと、いつも使ってるHEWと違い戸惑う部分もありますが、プログラムを実行してマウス(*ロボットのことではありません!)で操作できるプログラムをつくるのはなかなか面白いです。
⇒タイヤの径は、自分より大きいモータを使っているのにもかかわらず、自分より小さい径の車輪を使っている人がいて、なおかつ自分はもっと小さい径の車輪がほしかったので、利害が一致し交換しました。車輪を交換したのに加えて、マウスの底面が今まで養生テープで滑るようにしていたのを、テフロンテープに変えより滑るようにし、また錘で重心の位置を調整するなど、足回りの改善を行いました。
⇒ポインタは、ずっとやろう!理解しよう!と思いつつちょっと理解しては、よーわからん!と投げていたものです。シミュレーター作りの時に、ライブラリを使う関係で触れる機会があったので、ついでに理解しました。使ってみると、これが便利で今まで作ったマウスのプログラムをポインタを使って書き直そうかと思う程です。今日はこのポインタについて書きたいと思います。
ポインタの使い方
ポインタの使い方と書きましたが、詳しいことはGoogle先生に聞いてください(笑)
自分よりよっぽど詳しく、解りやすく説明してくれるので...
ポインタを使うとは、値を変数に"a=2;"のように代入するのではなく、"*p=2"のようにアドレス値を介して変数に値を代入することと自分は理解しています。ここで、もう謎の言葉、「アドレス値」というものが出てきました。さらに"*p=2"ってなんじゃこりゃ?と思ったかもしれません。順番に説明します。
アドレスとは、変数がメモリのどの場所に保存されているかを示す住所のようなものと理解すれば大丈夫です。
次に"*p=2"ですがこれは少しややこしいです。
通常、変数に値を代入するときは、
(変数の宣言⇒変数に代入)
1 int a;
2 a=2;
3 printf("a=%d",a);
とやりますが、ポインタを使う場合は、
1 int a;
2 int *p;
3 p=&a;
4 *p=2;
5 printf("a=%d",*p);
となります。二つのプログラムの実行結果は両方とも"a=2"となります。
ポインタを知らない人はこの例を見てなんでこんな面倒臭いことをやらなくちゃいけないのか?と思ってしまうかもしれません。でもすごく便利なんです。使っていくうちにわかります。
で、ポインタ変数を使う場合は、どんなことをやっているかと言うと、
【1行目】int a;
⇒普通に変数に代入するのと同じように変数を宣言
【2行目】int *p;
⇒アドレス値を保存するための変数(ポインタ変数と呼ばれる)
ポインタ変数を宣言するときは、変数名の前に*をつけなければならない。
【3行目】p=&a;
⇒変数"a"のアドレス値をポインタ変数"p"に代入する。
ポインタ変数にアドレスを代入するとき、アドレス値はどこから持ってこれるんだ?と思うかもしれません。
これは変数名(普通の変数,ポインタ変数ではない!←ここ注意)の前に"&"を付けることにより持ってくることができます。
つまり、"&a"で変数"a"のアドレス値となり、その値をポインタ変数"p"に代入します。
ここで、もう一つ注意点。ポインタ変数を宣言するときは"*p"で宣言しましたが、アドレス値を代入するときは、"*"をつけません。
【4行目】*p=2;
⇒これは、ポインタ変数"p"に入っているアドレス値が示すメモリの場所に2を代入しています。
"&a"を"p"に代入したので、ポインタ変数"p"に入っているアドレス値が示すメモリの場所は変数"a"の値が保存されている場所となります。
ポインタ変数の前に"*"を付けて、普通の変数のように代入すると、そのポインタ変数が指すメモリの場所に値を保存します。
つまり、まとめると、p=&a"をすると、"*p"と"a"は、同じように扱えます。(=を使うことによって同じように値を保存できます。)
【5行目】printf("a=%d",*p);
⇒*pが指すメモリの場所に保存されてる値を表示する
4行目の説明で"*p"と"a"は、同じように扱えると言ったのと同様に、
"printf("a=%d",*p);"は"printf("a=%d",a);"と同じです。
また、一行前で、"*p=2;"つまり、"a=2;"と同じことをしているので、2が表示されます。
ポインタの基本は以上です。
てか、これ以上は自分理解してません(笑)
ポインタを関数の引数として使った例を↓に載せときます

ポインタを使うと何がいいのかって言うと、グローバル変数を使わなくても、呼び出された関数から、元の関数のローカル変数をいじれることです。←文字だけ見てもピンと来ないかもしれません。
それから、関数のreturn値は一つしか取れないので、2つ以上の値を返したいときはグローバル変数に頼らなきゃいけなかったのが、ポインタを使うことによりいらなくなります。←これもピンときませんね(笑)
↑のプログラムは、main文でpointと名付けられた関数(名前は自分で決めてもいい)を呼び出して、その結果を画面に出力するプログラムです。
point関数は2つの値と、2つのアドレス値を引数としています。
"(2,4,&s,&t)"は"2"と"4"を数値として関数に渡し、"&s"と"&t"はmain文で宣言されたローカル変数"s""t"のアドレス値を関数に渡しています。(プログラムの19行目)
point関数内では、渡された数値を計算し、その結果を"*s_po = s;""*t_po = t;"のように代入しています。
つまり、このプログラムでのpoint関数は、"point(int x, int y, int *s_po , int *t_po)"の"x""y"には値が代入され、"*s_po"と"*t_po"にはアドレス値が代入されます。そして、計算結果は代入されたアドレス値が指すメモリの場所に保存されます。
ここで、ん?と思った人がいるかもしれません。この場合"*t_po = アドレス値"になっているのではないかと
これは、
"int *p = &a"
が良くて
"int *p;"
" *p = a"
がダメと同じ理由だと思います。
ぶっちゃけ詳しいことは自分は知りせん。
ふぅ・・・つかれた
簡単な説明ですが、なんとなく使えるようになると思います←(適当w)
では、おやすみなさい。
研究の進捗がなく苦しんでおりますが、マウス関連の進捗はあるという本分を忘れている今日この頃です。
とりあえず、マウス関連でここ一週間やったことを書きます。
・迷路シミュレータ作り
・タイヤの径をφ48からφ44に変更(足回りの改善)
・C言語のポインタの理解と実装
こんな感じですかね。
⇒シミュレータ作りは、新たな探索方法を試すのに、将来有用だと思い作り始めました。Visual Studio を使ったり、ライブラリを使ったりと、いつも使ってるHEWと違い戸惑う部分もありますが、プログラムを実行してマウス(*ロボットのことではありません!)で操作できるプログラムをつくるのはなかなか面白いです。
⇒タイヤの径は、自分より大きいモータを使っているのにもかかわらず、自分より小さい径の車輪を使っている人がいて、なおかつ自分はもっと小さい径の車輪がほしかったので、利害が一致し交換しました。車輪を交換したのに加えて、マウスの底面が今まで養生テープで滑るようにしていたのを、テフロンテープに変えより滑るようにし、また錘で重心の位置を調整するなど、足回りの改善を行いました。
⇒ポインタは、ずっとやろう!理解しよう!と思いつつちょっと理解しては、よーわからん!と投げていたものです。シミュレーター作りの時に、ライブラリを使う関係で触れる機会があったので、ついでに理解しました。使ってみると、これが便利で今まで作ったマウスのプログラムをポインタを使って書き直そうかと思う程です。今日はこのポインタについて書きたいと思います。
ポインタの使い方
ポインタの使い方と書きましたが、詳しいことはGoogle先生に聞いてください(笑)
自分よりよっぽど詳しく、解りやすく説明してくれるので...
ポインタを使うとは、値を変数に"a=2;"のように代入するのではなく、"*p=2"のようにアドレス値を介して変数に値を代入することと自分は理解しています。ここで、もう謎の言葉、「アドレス値」というものが出てきました。さらに"*p=2"ってなんじゃこりゃ?と思ったかもしれません。順番に説明します。
アドレスとは、変数がメモリのどの場所に保存されているかを示す住所のようなものと理解すれば大丈夫です。
次に"*p=2"ですがこれは少しややこしいです。
通常、変数に値を代入するときは、
(変数の宣言⇒変数に代入)
1 int a;
2 a=2;
3 printf("a=%d",a);
とやりますが、ポインタを使う場合は、
1 int a;
2 int *p;
3 p=&a;
4 *p=2;
5 printf("a=%d",*p);
となります。二つのプログラムの実行結果は両方とも"a=2"となります。
ポインタを知らない人はこの例を見てなんでこんな面倒臭いことをやらなくちゃいけないのか?と思ってしまうかもしれません。でもすごく便利なんです。使っていくうちにわかります。
で、ポインタ変数を使う場合は、どんなことをやっているかと言うと、
【1行目】int a;
⇒普通に変数に代入するのと同じように変数を宣言
【2行目】int *p;
⇒アドレス値を保存するための変数(ポインタ変数と呼ばれる)
ポインタ変数を宣言するときは、変数名の前に*をつけなければならない。
【3行目】p=&a;
⇒変数"a"のアドレス値をポインタ変数"p"に代入する。
ポインタ変数にアドレスを代入するとき、アドレス値はどこから持ってこれるんだ?と思うかもしれません。
これは変数名(普通の変数,ポインタ変数ではない!←ここ注意)の前に"&"を付けることにより持ってくることができます。
つまり、"&a"で変数"a"のアドレス値となり、その値をポインタ変数"p"に代入します。
ここで、もう一つ注意点。ポインタ変数を宣言するときは"*p"で宣言しましたが、アドレス値を代入するときは、"*"をつけません。
【4行目】*p=2;
⇒これは、ポインタ変数"p"に入っているアドレス値が示すメモリの場所に2を代入しています。
"&a"を"p"に代入したので、ポインタ変数"p"に入っているアドレス値が示すメモリの場所は変数"a"の値が保存されている場所となります。
ポインタ変数の前に"*"を付けて、普通の変数のように代入すると、そのポインタ変数が指すメモリの場所に値を保存します。
つまり、まとめると、p=&a"をすると、"*p"と"a"は、同じように扱えます。(=を使うことによって同じように値を保存できます。)
【5行目】printf("a=%d",*p);
⇒*pが指すメモリの場所に保存されてる値を表示する
4行目の説明で"*p"と"a"は、同じように扱えると言ったのと同様に、
"printf("a=%d",*p);"は"printf("a=%d",a);"と同じです。
また、一行前で、"*p=2;"つまり、"a=2;"と同じことをしているので、2が表示されます。
ポインタの基本は以上です。
てか、これ以上は自分理解してません(笑)
ポインタを関数の引数として使った例を↓に載せときます

ポインタを使うと何がいいのかって言うと、グローバル変数を使わなくても、呼び出された関数から、元の関数のローカル変数をいじれることです。←文字だけ見てもピンと来ないかもしれません。
それから、関数のreturn値は一つしか取れないので、2つ以上の値を返したいときはグローバル変数に頼らなきゃいけなかったのが、ポインタを使うことによりいらなくなります。←これもピンときませんね(笑)
↑のプログラムは、main文でpointと名付けられた関数(名前は自分で決めてもいい)を呼び出して、その結果を画面に出力するプログラムです。
point関数は2つの値と、2つのアドレス値を引数としています。
"(2,4,&s,&t)"は"2"と"4"を数値として関数に渡し、"&s"と"&t"はmain文で宣言されたローカル変数"s""t"のアドレス値を関数に渡しています。(プログラムの19行目)
point関数内では、渡された数値を計算し、その結果を"*s_po = s;""*t_po = t;"のように代入しています。
つまり、このプログラムでのpoint関数は、"point(int x, int y, int *s_po , int *t_po)"の"x""y"には値が代入され、"*s_po"と"*t_po"にはアドレス値が代入されます。そして、計算結果は代入されたアドレス値が指すメモリの場所に保存されます。
ここで、ん?と思った人がいるかもしれません。この場合"*t_po = アドレス値"になっているのではないかと
これは、
"int *p = &a"
が良くて
"int *p;"
" *p = a"
がダメと同じ理由だと思います。
ぶっちゃけ詳しいことは自分は知りせん。
ふぅ・・・つかれた
簡単な説明ですが、なんとなく使えるようになると思います←(適当w)
では、おやすみなさい。
スポンサーサイト