友達に本を届ける方法は2つあります。1つは本そのものを手渡す方法。もう1つは「その本は市立図書館の3階、棚B-12にあります」と書いたメモを渡す方法です。
C言語のポインタは、後者のメモです。中身そのものではなく、中身がどこにあるかを書いた紙切れ。それ以上でも以下でもありません。

ポインタは「番地を入れる変数」
前のトラックで、すべての変数には番地があると学びました。その番地も数値なので、変数に入れて持ち歩くことができます。番地を入れるための変数、それがポインタです。
int a = 5; // 中身は 5
int *p = &a; // 中身は 「a の番地」p の中に 5 は入っていません。入っているのは 0x7ffd5a2c のような番地です。p は5の居場所を知っているだけで、5そのものは持っていません。
もっともな疑問です。答えを3つ挙げます。
うれしいこと①:相手の本体を書き換えられる
トラック7で、関数に変数を渡すとコピーが渡ると学びました(値渡し)。だから関数の中でいくら変数をいじっても、呼び出し元の変数は変わりません。ところが番地を渡せば、関数は本体そのものに手が届きます。これができないと、scanfのように「呼び出し元の変数に値を入れて返す」関数は作れません。
うれしいこと②:大きなものをコピーせずに渡せる
1000要素の配列を関数に渡すたびに全部コピーしていたら、時間もメモリも無駄です。番地なら、どれだけ大きなデータでも渡すのは8バイトぶんの数値ひとつで済みます。図書館ごと運ぶかわりに、棚の番号を伝えるわけです。
うれしいこと③:形の変わるデータを作れる
必要なぶんだけ箱を借り、それをメモでつないでいけば、あとから伸び縮みするデータ構造(連結リストなど)が作れます。これは第4部の主役です。
なぜ難しいと言われるのか
ポインタでつまずく原因は、実はポインタそのものではありません。「値」と「番地」の2階建てを、頭の中で同時に扱う必要があるからです。
p の話をしているのか、p が指している先の話をしているのか。この切り替えができれば、ポインタの9割は終わりです。だからこのトラックでは、常にメモリの図とメモの比喩を並べて進めます。
まとめ
ポインタは値そのものではなく、値の居場所(番地)を入れておく変数です。相手の本体を書き換える・大きなデータを軽く渡す・形の変わるデータを作る、という3つの力を持ちます。次のレッスンから、番地を書く道具 & と、番地を訪ねる道具 * を手に取ります。