本文へスキップ
BecomeCoder

C言語コース · 第6章 ポインタとメモリ · レッスン23

ポインタ入門 ― 住所(&)と中身(*)

ブラウザで完結

導入

前のレッスンで、変数メモリ上に「住所(アドレス)」を持つと学びました。ポインタは、その住所を入れておくための変数です。「住所を書いたメモ」だと考えてください。

説明

ポインタを使うには、2つの記号を覚えます。ここで &* の役割を混同しないことが最初の関門です。

  • &変数 … その変数の住所を取り出す(アドレス演算子)。**「&=住所を聞く」**と覚えましょう。
  • *ポインタ … その住所に置かれている中身を読み書きする(間接参照)。**「*=中身をたどる」**と覚えましょう。
#include <stdio.h>

int main() {
    int x = 5;
    int *p = &x;       // pは「xの住所」を持つポインタ
    printf("xの値   : %d\n", x);          // 5
    printf("xの住所 : %p\n", (void *)&x);  // 例: 0x... (番地)
    printf("pの中身 : %p\n", (void *)p);   // &xと同じ番地
    printf("*p      : %d\n", *p);          // 5(pの指す先の中身)
    *p = 10;            // *pへの代入は、その住所にあるxを書き換える
    printf("x = %d\n", x);                 // 10
    return 0;
}

図にすると、ポインタ px を「指している」だけの、別の小さな箱です。p の中身は x の住所(番地)で、*p はその矢印をたどった先=x そのものを表します。

flowchart LR
  p["ポインタ p<br/>中身 = 1002(xの番地)"] -->|"*p でたどる"| x["1002番地<br/>x = 5"]

int *p は「int を指すポインタ」という宣言です。p = &x で x の住所を入れ、*p で x の中身にアクセスします。*p = 10; は「p が指している先=x」を書き換えるので、x 自身が 10 になります。

ポインタは「別名でその変数を操作するリモコン」だと考えると分かりやすいです。手元のリモコン(p)が、離れた場所のテレビ(x)を操作するイメージです。

flowchart LR
  A["&x<br/>(xの住所を取り出す)"] --> P["pに住所を保存"]
  P --> B["*p<br/>(住所をたどって中身にアクセス)"] --> X["xを読む/書く"]

&* は、いつも「反対の向き」だと考えると混乱しにくいです。&変数 は「変数 → 住所」、*ポインタ は「住所 → 変数(中身)」という、たどる方向がちょうど逆になっています。

やってみよう

*p = 10; の値を変えたり、x を直接書き換えたりして、x*p がいつも同じ値を指していることを確かめましょう。&xp を表示して、同じ番地になっていることも見てください。

演習

int n = 3; を指すポインタ p を作り、*p を使って n の値を 99 に書き換え、n を表示してください(結果は 99)。

ヒント1を見る

int *p = &n; のあと *p = 99;、最後に printf("%d\n", n);

実際に動かしてみよう

下のエディタにCを書いて「実行」を押すと、ブラウザ内のインタプリタで出力が表示されます。本文の例をそのまま試したり、書き換えたりしてみましょう(scanf を使う回は「標準入力」欄に値を入れてから実行します)。

C/C++ — ブラウザ内で実行

ブラウザ内でC/C++を動かす学習用インタプリタ(JSCPP)を読み込みます(入門向けのサブセットです)。
スクロールして表示された時点でも自動で読み込まれます。