C言語を学ぶ上でポインタは重要概念で、この概念を理解していないと実務で通用するプログラミングはできません。
にもかかわらず、C言語の主要なつまずきポイントにもなってしまっており、未経験者のみならず他言語を学んできた方にとっても難しい概念です。
ポインタの難しさはイメージのしにくさにあり、イメージするにはコンピュータ内部の仕組みを理解する必要があります。
今回の記事では、ポインタのイメージをなるべく簡単に書きたいと思います。
【変数の領域の確保】
コンピュータにはメモリ領域が存在し、メモリ領域の中に様々なデータがセットされています。
メモリ領域は区分けされており、それぞれの区分けごとにアドレスが割り振られています。
プログラムで変数を宣言すると、そのメモリ領域の一部がその変数用に確保され、他の用途で使用されないようにします。
変数に値をセットすると、その変数用のメモリ領域が変更されます。
以上のことを図にすると以下のようになります。
なお、この挙動はC言語に限った話ではなく、他言語にも言えることです。
【アドレスの参照と値の参照】
ここからがC言語ならではの話になります。
他の言語では変数のメモリ領域が指す値のみを使用するのですが、C言語では変数のメモリ領域の(先頭)アドレスを使用することがあります。
通常の変数でも、「&」演算子をつけて参照することでアドレスを取得することができます。
そして、C言語では普通の変数の他にポインタ変数というものがあり、変数の宣言時に「*」演算子をつけることでポインタ変数になります。
ポインタ変数はアドレスを扱う用の変数であり、演算子をつけずに普通に参照するとアドレスを取得できます。
また、「*」演算子を付けて参照することで、その変数のメモリ領域が指す値を取得することができます。
以上のことを図にすると以下のようになります。
【コーディング例】
・test.c
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <stdio.h> int main() { int a = 3; int *p; p = &a; //アドレスの代入 printf("変数aの値 %d\n", a); printf("ポインタ変数pの値 %d\n", *p); printf("変数aのアドレス %p\n", &a); printf("ポインタ変数pのアドレス %p\n", p); return 0; } |
※HTMLエスケープ回避のため、特殊文字を全角文字にしています。ご了承ください。
・実行結果
1 2 3 4 |
変数aの値 3 ポインタ変数pの値 3 変数aのアドレス (アドレスの値。実行環境によって変わります。) ポインタ変数pのアドレス (↑と同じアドレスの値が表示されます。) |
【ポインタは何のために使うのか】
ポインタを使う理由は主に以下の2つです。
・関数で参照渡しをするために使う
簡単に書くと、引数でポインタ変数を指定し、呼び出し先の関数でそのポインタ変数に値を代入すると、呼び出し元でもその代入された値を使用可能になります。
C言語の関数は、多くの場合「ビジネスロジックで使用するアウトプットは参照渡しされた変数に代入し、returnではリターンコード(例:0なら正常、1以上ならエラー)を返す」という形になっています。
・インクリメント/デクリメントで次の/前の変数の値を取得するために使う
文字列や配列の処理で使用します。
コメント