【C言語】ポインターとはなんぞ?

ポインターとは?

→値の代わりにアドレスにアクセスできる変数だよ。

ハイ終わり!!あと宿題な!!ジャンプ買ってくる!!

 

・・・・さて?上記説明だけで「ポインター完全に理解した」

と言える人はツワモノだわ。色々教えて頂きたいですわ。

買ってきたジャンプあげるから。。

 

C言語最大にして、これさえ理解すれば大抵の言語は怖くないとまで思える、概念「ポインター

 

そもそもこの記事を書こうと思ったきっかけは?

・だいたいここで行き詰まる。

・「ポインターわかんねですよ・・」と同じチームのC言語やり始めた若い子がいた。

ツイッターポインターの理解に関して意味不明なことを言ってるツイートがあったから。

 

そんなに難しいかなぁ・・正直最初意味わからなかった覚えあるけど、使ってたら体で覚えた俺からすると、慣れですよ慣れ。としか思えない。。

ただ確かに説明するのはめっちゃ難しい。

これは間違いない。

 

というわけで俺はこう覚えた!というポインタの覚え方?理解の仕方?を一つ公開しようかと思う。

  • そもそも何がわからんのだ!
  • 理解する上で何が必要か!
  • まとめて・・ポインターとは?

こんな論調で進めていこうかと思う。

 

  • そもそも何がわからんのだ!!

 何がややこしいのか?原因を考えてみた!

  1. 変数との違いがわかんねぇ。。
  2. 説明が難しいよう。。
  3. プログラムが読めねぇ・・

といったところかなぁ。。

まず概念としてのポインターの説明は「値の代わりにアドレスにアクセスできる変数」でほんとに終わってしまう。

たとえ話としては色々あって

・住所の書かれたメモを渡す

・変数が箱だとすれば箱に書かれたNoがポインター

まあ、色々。。

間違ってないんだけど、ふわっとしてる。

確かに説明色々みた覚えあるけど、わかった感はあるけど理解はできない記憶だなぁ。。個人的に

 

  • 理解する上で何が必要か!

はっきり言って、C言語のことをずっと追いかけてもしょうが無い。視点としてはズバリ2つ必要。

  1. モリー(RAM)というものがPCやマイコンには存在する。
  2. そもそもプログラムの変数はどのようにPCやマイコン上では処理されるのか?

じゃあ、1.から

PCにはメモリーというものが存在する。

ナンノコッチャ?と思う人は

https://akiba-pc.watch.impress.co.jp/docs/dosv/695135.html 

 あたりを見ると良い。

モリーの役割として、プログラムやデータを一時的に置いておく役割とあるけど、まさにこの通り。

ソフトが起動したら、必ずメモリーに必要なものが置かれる。変数もその一つと思ってもらって問題ない。

 

ただ無造作に置いてしまうと良くない。

必要なときに必要なものを引き出せないということになる。

そこで出てくるのがポインターを語る上で必ず出てくる言葉

 

アドレス。

 

「値の代わりにアドレスにアクセスできる変数」

のアドレスは具体的にはPCのメモリー内部のアドレスを指す。

 

「PCのメモリー内部のアドレス」 これ大事!

 

そして話は2.に移る。

ここでメモリーの中身の話に移っちゃいます。頑張って付いてくるべし

https://brain.cc.kogakuin.ac.jp/~kanamaru/lecture/prog1/08-02.html 

 このあたりがとてもわかり易いかと。。

 

PCメモリー内部のイメージは以下の図の形になる。

 

f:id:tatekarito:20200112005320j:plain

大前提としてメモリーというものは

1bitずつアドレス(≒位置No)が振られている

というのを頭において欲しい。

 

この図で言うと一番左が始まりのアドレスになる。0x0という値から始まって

1番目のbitが0x0。2番目のbitが0x1。3番目のbitが0x2という要領で。

上部は4bitずつ数値を書いている。

 

例えば char str ="a";

とか宣言してこのメモリーに置いとくとすると

f:id:tatekarito:20200112005419j:plain

緑色の部分に変数strの値を置くために、PCのメモリー内部に場所が確保される。

char型は8bitの大きさのため0x0 - 0x7までの部分を使用することになる。この部分にstrに入る値を置くのだ。

変数を宣言することでメモリーに陣地が取れると思えばよいかと思う。

 

ここまで理解できるだろうか?わからなければ何度も図を見比べながら反芻しよう。ここまでの知識がポインター理解のための基礎となる。

 

さてここからが本題。結局ポインターってなんなのさ?

もう一度この図を見て欲しい。

f:id:tatekarito:20200112005419j:plain

char str ="a";

を実行したときのPCメモリー内部の様子である。ではこれを

char *str;

としたときどうなるのだろうか?

f:id:tatekarito:20200112011909j:plain

こんな感じになる。値が入ってないので、nullと一旦した。

(正確に言えばこの値が入るとは限らないが、今回は一旦無視。気にしたら負け)

 大事なのはメモリーに場所が確保されただけ!

という点である。

 

そしてもしprint関数で*strを表示したら値は

0x0と

返ってくる。そう、ポインターとは「値の代わりにアドレスにアクセスできる変数」と説明したが、その実態は

PCのメモリー内部に確保した場所の最初のアドレス(先頭アドレス)を返す。

が答えになる。

 

そう。ポインターと変数は全く意味合いが違うことがおわかりいただけただろうか?

たまたま変数でこの説明をしたが

char str[128];

とかだと以下のようにメモリーが確保される

f:id:tatekarito:20200112013141j:plain

char str[0];が黄色、char str[1];が黄緑、char str[2];が緑

char str[3];が青といった形でメモリーの場所を確保していく。

注目すべきは

char *str; と

char str[0]; が

PCのメモリー内部に確保した場所の最初のアドレス(先頭アドレス)を指す。

 ということ。この考え方はメチャ大事。

これに気づければほぼポインターを理解したと言っても良いかもしれない。

 

いかがでしょ?俺はこんな感じでポインター理解したけど、

是非ここは、わかるorわからないとか、

お前は間違っている!!とか

クソ野郎が!!とか、是非意見などが欲しい。

 

とりあえず身の回りでポインターわかんねぇ・・と言ってるチームの同僚にはチャンスが有ればここで説明してみよう・・。理解されるのだろうか??

 

最後の最後に。新人時代C言語の理解を深めるためお世話になったサイトを敬意を込めてご紹介しておこう。

https://9cguide.appspot.com/ 

 では!!