悩む人
このようなお悩みを解決する記事です。
記事の内容
- C言語のポインタとは
- C言語のポインタの使用例
- なぜC言語のポインタは必要なのか
記事の信頼性
- 本記事を書いている僕は、プログラミング歴6年の現役エンジニアです。
- 仕事でC言語を扱っています。
C言語のポインタについて知りたいあなた。
C言語のその他のコードについては分かるけど、ポインタだけ分かりづらいな〜と感じているのではないでしょうか。
僕もその状態から抜け出したので、気持ちめちゃくちゃ分かります。
そこで本記事では、C言語のポインタについて、僕が分かるようになった方法で解説しました。
この記事を読むと、今までのC言語のポインタに関するもやもやが晴れるはずですよ。
それではさっそく見ていきましょう!
目次
C言語のポインタとは?

ポインタを一言で表すと、「変数のアドレスを格納している変数」です。
アドレスとは、変数のメモリ上の位置のことです。
変数を宣言すると、使用するコンピュータのメモリが変数のサイズ分割り当てられます。このメモリ上の位置を表す言葉がアドレスになります。
はい、分かりずらいですよね。(笑)
例をあげます。
下記の場合の変数aのポインタは、値が変わろうと10024です。

何となくイメージが持てればOKです。
C言語のポインタの使用例

C言語のポインタを理解するためには、引数の理解が必須です。
なので、まずは引数について理解しておきましょう。(引数が分かる人は飛ばしてOKです。)
引数について
引数は関数内に値やアドレスを渡すために存在しています。
例をあげていきますね。まずは下記のコードを見てください。

このソースコードの例では、circle関数とmain関数があり、circle関数の引数はrとなっています。
circle関数内では、このrを用いて処理が行われ、printfで円の面積を出力しているというわけですね。
では、このrの値には何が入っているのでしょうか。
それは、main関数の中に記述されています。
main関数では、circle関数を呼び出す際に、引数として1を入れて呼び出しています。
よって、r=1として計算され、出力結果は下図のようになります。

引数については以上です。
C言語のポインタをやるなら引数の理解は必須ですので、しっかり理解しておきましょう。
続いて、C言語のポインタの例についてあげていきます。
C言語のポインタの具体例
アドレスと値の違い
よくアドレスは「住所のようなもの」で、値は「そこに住んでいる特定の人」という表現がなされます。これは、理解出来ると思います。
しかし、「いざポインタ型のソースコードを見ると、理解できない」
この状態の人は何気に多いです。まずは、これを解決していきますね。
下記のプログラムとその実行結果を見てください。


これは有名なswap関数というもので、値を入れ替える処理で用います。
ですからuとvの値が入れ替わって、u=3,v=2になるはずです。
しかし、なっていませんよね?
これはswap関数の引数がポインタ型になっていないからです。
この時のアドレスと値は下図のようになっています。

変数や引数はメモリ(記憶しておく場所)の中のスタック領域という場所に格納されています。
上図のように、関数の中の変数のアドレスは、それぞれ違います。
main関数の中のuとvのアドレス(住所)は、それぞれ1000番地、1004番地。
swap関数の中のuとvのアドレス(住所)は、ぞれぞれ2000番地、2004番地となっています。
値が一緒でも、アドレス(住所)が違うので値(そこに住んでいる人)もそれぞれ違うとみなされます。
swap関数で値を入れ替えているuとvのアドレスがmain関数のuとvのアドレスと違うため、別々のものとみなされ、swap関数内でいくら値を変えたりしても、main関数で指定したu=2,v=3と出力されてしまいます。
そこで、main関数とswap関数のように別々の関数で同じもの(同じ住所のもの)をいじるためにポインタが使用されます。
ポインタには、「*」や「&」が出てきます。
「*」は、引数での宣言の時は、アドレスで、それ以外の時は指す先の中身(そのアドレスにある値)をみます。
一方で、「&」はアドレスのみ見ます。
ですから、&aはaのアドレスということです。
これだけは覚えておきましょう。
下図を見てください。


swap関数に渡す引数をポインタ型にすると、値が入れ替わって出力されていることが分かるかと思います。
引数に「*」が付くと、アドレスを指すことになると言いました。
ですから、main関数内でswap関数に渡す引数は「&」を付けてアドレスを渡しています。
この時のアドレスと値は下図のようになっています。

引数としてアドレスが渡されることで、swap関数の中で「*」が付いたものは、そのアドレスの中身(値)を直接操作しています。
よって上図のようになるというわけですね。
ぶっちゃけC言語のポインタなんて、これだけ分かっておけばOKです。
意外と簡単じゃないですかね?
なぜC言語のポインタは必要なのか

結論から言うと、別の関数からローカル変数へアクセスすることが可能になるから。

上記の画像を見てもらうと分かりやすいのですが、ポインタを使うことで、本来別関数からアクセスできないローカル変数の「number」にアクセスできていることが分かるかと思います。
こういった場合にC言語のポインタは非常に便利になってきます。
まとめ:C言語のポインタは割と簡単
以上、本記事では、C言語のポインタについて解説しました。
「*」は、引数での宣言の時はアドレスで、それ以外の時は指す先の中身(そのアドレスにある値)をみる。「&」はアドレスのみ見る。 ということだけ理解しておけばOKです。
割と簡単なので、しっかり理解しておきましょう。
今回は以上です。