技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

C言語:入門者(初心者)向けにポインタの概念をなるべく簡単に書いてみた

未経験者向けのプログラミングの指導で色々悩んでいて、ググってみたら↓のようなページを偶然発見したのですが
 
プログラミングの勉強を始めたときに、文系が挫折しやすい7つのポイント - paiza開発日誌

https://paiza.hatenablog.com/entry/2015/10/20/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E5%8B%89%E5%BC%B7%E3%82%92%E5%A7%8B%E3%82%81%E3%81%9F%E3%81%A8%E3%81%8D%E3%81%AB%E3%80%81%E6%96%87%E7%B3%BB%E3%81%8C%E6%8C%AB

 
ポインタの項の「もう既にうまく例示もできません。」の一言が色々物語っていたので、この記事を書こうと思いました。
 
C言語を学ぶ上でポインタは重要概念で、この概念を理解していないと実務で通用するプログラミングはできないですし、基本情報処理技術者試験の言語選択の問題も解くことができません。
にもかかわらず、C言語の主要なつまづきポイントにもなってしまっており、未経験者のみならず他言語を学んできた方にとっても難しい概念です。
ポインタの難しさはイメージのしにくさにあり、イメージするにはコンピュータ内部の仕組みを理解する必要があります。
今回の記事では、ポインタのイメージをなるべく簡単に書きたいと思います。
 
【変数の領域の確保】
コンピュータにはメモリ領域が存在し、メモリ領域の中に様々なデータがセットされています。
メモリ領域は区分けされており、それぞれの区分けごとにアドレスが割り振られています。
 
プログラムで変数を宣言すると、そのメモリ領域の一部がその変数用に確保され、他の用途で使用されないようにします。
変数に値をセットすると、その変数用のメモリ領域が変更されます。
 
以上のことを図にすると以下のようになります。

f:id:akira2kun:20181124174158j:plain

 
なお、この挙動はC言語に限った話ではなく、他言語にも言えることです。
 
【アドレスの参照と値の参照】
ここからがC言語ならではの話になります。
 
他の言語では変数のメモリ領域が指す値のみを使用するのですが、C言語では変数のメモリ領域の(先頭)アドレスを使用することがあります。
通常の変数でも、「&」演算子をつけて参照することでアドレスを取得することができます。
 
そして、C言語では普通の変数の他にポインタ変数というものがあり、変数の宣言時に「*」演算子をつけることでポインタ変数になります。
ポインタ変数はアドレスを扱う用の変数であり、演算子をつけずに普通に参照するとアドレスを取得できます。
また、「*」演算子を付けて参照することで、その変数のメモリ領域が指す値を取得することができます。
 
以上のことを図にすると以下のようになります。

f:id:akira2kun:20181124174248j:plain

 
【コーディング例】
入門者向けのコーディング例としては、以下のページがお勧めです。
ポインタのイメージを頭に入れた上で、実際のコーディングを見ることで、理解が深まると思います。
 
ポインタ - C言語入門 - IT専科

http://www.itsenka.com/contents/development/c/pointer.html

 

【ポインタは何のために使うのか】
私の経験上、ポインタを使う理由は主に以下の2つです。

  • 関数で参照渡しをするために使う
    ざっくり言うと、引数でポインタ変数を指定し、呼び出し先の関数でそのポインタ変数に値を代入すると、呼び出し元でもその代入された値を使用可能になります。
    C言語の関数は、多くの場合「本当のアウトプットは参照渡しされた変数に代入し、returnではリターンコード(例:0なら正常、1以上ならエラー)を返す」という形になっています。
  • インクリメント/デクリメントで次の/前の変数の値を取得するために使う
    文字列や配列の処理で使用します。