ポインタで挫折しそう…
C言語のポインタって難しいですよね。
教科書で見ても分からないし、ググってもなかなかイメージできないと思います。
ということで、C言語を習得するにあたっての最大の難関であるポインタを分かりやすく解説します!
・C言語歴18年
・学生の時はポインタがかなり苦手でした
私が学生の時、C言語の授業でポインタを説明されましたが、ちんぷんかんぶんでした。
「わかった!」
翌日の私「 うーん、何だっけ。よく分からない」
この繰り返しでした。
今ならC言語でポインタの高度な使い方(ポインタのポインタのポインタの構造体の構造体など笑)もやっていますが、最初は私も分かりませんでした。
なので、ポインタが全然分からない!というのは全く普通で当たり前です!
C言語を習得する上で、最大の難関がポインタでしょう。
ある意味で、ポインタをマスターすればSEやプログラマーになれるといっても過言でもはないです。
SEの平均年収550万円です。私はC言語しか習得していませんが、20代でもこれを超えていました。
ということで、今回は ”分かりやすい!C言語のポインタ” として解説していきます。
目次
C言語のポインタを分かりやすく解説
ポインタをイメージでとらえる
まずはアドレスをイメージで理解する
ポインタは絵(イメージ)でとらえて覚えましょう。
多くの方を悩ませている原因は、ポインタをイメージでとらえられていないのが理由です。
そもそも多くの教科書などはコードや文章だけ、または簡単な図しか記載されていません。
そんなのでは分かりにくいんですよね。
まずはポインタを理解する上で必要な”アドレス(住所)”の考え方を説明します。
この図の場合、それぞれの意味するものはこちらです。
箱A、箱B、箱C | 変数 |
置き場所001、置き場所002、置き場所003 | アドレス |
りんご、みかん | 変数の中のデータ |
倉庫 | メモリ |
全ての変数(箱Aなど)のデータ(りんごなど)はメモリ(倉庫)に格納されています。
メモリのアドレス(置き場所)が上の図の ”置き場所001~003” です。
この図を覚えてしまいましょう。そうすればあとはイメージしやすくなります。
アドレスはデータの置き場所
アドレスはデータの置き場所です。
もう少し詳しく見てみましょう。
まずは実際のコード例です。
コード例:
- int main(void)
- {
- int hakoA = 123;
- printf("箱Aの中は:%d¥n",hakoA);
- printf("箱Aの置き場所001は:%p¥n",&hakoA);
- }
実行結果:
- 箱Aの中は:123
- 箱Aの置き場所001は:0x7FFF5678
※6行目の「&」(アンパサンド)は、変数の前に入れるとアドレスを表すことができます。
「&」を変数 ”hakoA” の前に入れているので、”0x7FFF5678” が出力されていますね。
変数 ”hakoA” のアドレス(置き場所)が ”0x7FFF5678” ということです。
アドレスを確認したかったら「&」を入れる と、覚えておきましょう。
このコード例は先ほどの図で例えるとこちらです。
りんご | 値 123 |
箱 | ローカル変数 hakoA |
置き場所001 | アドレス 0x7FFF5678 |
データ(りんご)の置き場所が、アドレスと覚えましょう。
ポインタ変数は「*」と「&」を使う
アドレスにある値を見たい場合はポインタ変数を使います。
このポインタ変数を使って
・「&」でアドレスを呼び出す(先ほど説明したとおり)
・「*」で中の値を呼び出す
この2つをすることができます。
まずは絵でイメージしましょう。
ポインタ子ちゃんは「&」でアドレスを教えてもらいます。
「&」を唱えることで、ポインタ子ちゃんは「置き場所001」を覚えました。
「置き場所001」を覚えているポインタ子ちゃんは「*」を唱えて、中身を見れました。
「&」でアドレスを教えてもらい、「*」で中を見られると覚えましょう。
コードが読める人は読んでみましょう。
コード例:
- int main(void)
- {
- int hakoA = 123;
- int *pointaA; /* *をつけることでポインタ変数の宣言となる*/
- pointaA = &hakoA;
- printf("箱Aの中は:%d¥n",hakoA);
- printf("箱Aの置き場所001は:%p¥n",pointaA);
- printf("箱Aの中は:%d¥n",*pointaA);
- }
実行結果:
- 箱Aの中は:123
- 箱Aの置き場所001は:0x7FFF5678
- 箱Aの中は:123
ポインタ変数は定義箇所に「*」をつけます。
4行目の ”int *pointaA” でポインタ変数 "pointaA" が定義されます。
これはそういうものだと思っておきましょう。
次に5行目で「&」を ”hakoA” の前につけて、 ”hakoA” のアドレスを ”pointaA” に入れています。
9行目で「*」を ”pointaA” の前につけて、 ”pointaA” の中の値を呼び出しました。
このコード例は先ほどの図で例えるとこちらです。
りんご | 値 123 |
ポインタ子ちゃん | ポインタ変数 pointaA |
置き場所001 | アドレス 0x7FFF5678 |
*を唱えたポインタ子ちゃん | 値 123 |
「&」でアドレスを呼び出す
「*」で中の値を呼び出す
この2つを覚えておきましょう!
ポインタのメリットは関数から複数のデータを操作できるから
なぜポインタなんて使うの?
直接見ればいいじゃん!
と思うかもしれません。
ポインタを使うメリットは「関数から複数のデータを操作できるから!」と覚えましょう。
関数は下記の通り1つのデータしか返せないですよね。
コード例:
- function(int A, int B)
- {
- return A+B;
- }
ですが、ポインタを使えば2つ以上のデータを返すことができます!
読める人は読んでみましょう。
コード例:
- int function(int *, int *);/*ここは今は覚えなくてOK*/
- int main(void)
- {
- int hakoA = 123;
- int hakoB = 456;
- function(&hakoA, &hakoB);
- printf("hakoAの中は:%d¥n",*hakoA);
- printf("hakoBの中は:%d¥n",*hakoB);
- }
- int function(int *hakoA, int *hakoB)
- {
- *hakoA = *hakoA + 1;
- *hakoB = *hakoB + 100;
- return 0;
- }
実行結果:
- hakoAの中は:124
- hakoBの中は:556
”hakoA” は 関数 ”function()” の中で +1 されているので、124になります。
”hakoB” は 関数 ”function()” の中で +100 されているので、556になります。
ポインタを使うことで2つの値を操作することができました。
便利ですよね。
これがポインタを使うメリットです。
「うーんよく分からない」という方は「関数から複数のデータを出力できるメリットがある!」と覚えておきましょう。
イメージとしてはこちらです。
ポインタを使わないと通常は関数から1つのデータしか出力できません。
ポインタを使うと関数からたくさんのデータを出力できます。
こう覚えておきましょう!
まとめ:ポインタは難しくない
今回はポインタの基礎をイメージで分かるように説明しました。
慣れれば難しくはありません。(慣れるまでが大変だとは思います)
説明したイメージさえ完璧におさえておけば、あとの配列や構造体はその応用でサクサク入ってくるかと思います。
「勉強していたら、またポインタがよく分からなくなってしまった…」
という方はまたこのページを見返してみることをおすすめします。
このポインタをマスターすればC言語はマスターできると言っても過言ではありません。
そうすればプログラマーやSEになれます!
SEの平均年収は550万円ですので、並以上の生活ができますし、キャリアアップして年収1000万円オーバーも全然可能な世界です。
頑張ってポインタを習得しましょう!