カテゴリ: C++ 更新日: 2026/01/29

C++のアドレス演算子(&)と間接演算子(*)を徹底解説!ポインタの仕組みをマスター

アドレス演算子 (&) と間接演算子 (*) の意味
アドレス演算子 (&) と間接演算子 (*) の意味

先生と生徒の会話形式で理解しよう

生徒

「先生、C++のポインタに出てくる『&』と『*』がややこしくて混乱しています。どちらも記号だし、何が違うのかさっぱりで……。」

先生

「確かに、最初は戸惑いますよね。これらは『住所を調べる道具』と『その住所にある中身を見る道具』というペアだと考えると分かりやすいですよ。」

生徒

「住所と中身、ですか。具体的にはどう使い分けるんですか?」

先生

「それでは、ポインタ操作の基本となる2つの演算子について、詳しく見ていきましょう!」

1. アドレス演算子(&)とは?「場所」を特定する記号

1. アドレス演算子(&)とは?「場所」を特定する記号
1. アドレス演算子(&)とは?「場所」を特定する記号

C++のアドレス演算子(&)とは、変数という「箱」が置かれているメモリ上の住所(アドレス)を取得するための記号です。プログラミング未経験の方には、「住所を検索するボタン」だとイメージしていただくと分かりやすいでしょう。

パソコンを動かしているとき、数値や文字などのデータは「メモリ」という場所に保存されています。このメモリは巨大なロッカーのようなもので、一つ一つの扉に番号(住所)が振られています。私たちが int price = 100; と書くと、コンピューターはどこかのロッカーを選んで 100 を入れます。このとき、&price と書くことで、「priceが入っているロッカーの番号は何番ですか?」と問いかけることができるのです。

2. 間接演算子(*)とは?「中身」を操作する記号

2. 間接演算子(*)とは?「中身」を操作する記号
2. 間接演算子(*)とは?「中身」を操作する記号

一方、間接演算子(*)は、取得した住所(ポインタ)を頼りにして、その場所に実際に入っているデータを読み書きするための記号です。ポインタの世界では「デリファレンス」とも呼ばれます。住所だけ知っていても中身が見られなければ意味がないため、この演算子を使ってロッカーの扉を開けるわけです。

例えば、「東京都中央区1-2-3」という住所(ポインタ)が書かれた紙があるとします。これだけでは、そこにどんな家が建っているか分かりません。間接演算子は、その住所へ実際に行ってみて、「中には誰が住んでいますか?」と確認したり、「壁の色を塗り替えなさい」と命令したりする行動そのものを指します。

3. コードで見る「住所の取得」と「値の操作」

3. コードで見る「住所の取得」と「値の操作」
3. コードで見る「住所の取得」と「値の操作」

実際に、アドレス演算子 & と間接演算子 * を組み合わせた基本的なプログラムを見てみましょう。このペアの使い方を覚えることが、C++エンジニアへの第一歩です。


#include <iostream>

int main() {
    int apple = 10;      // 普通の変数
    int* ptr = &apple;   // &を使ってappleの「住所」を取得し、ポインタptrに保存

    std::cout << "appleの住所: " << ptr << std::endl;
    std::cout << "住所にある中身: " << *ptr << std::endl; // *を使って住所の「中身」を表示

    return 0;
}

appleの住所: 0x7ffd5e3a2b14 (※環境によって異なります)
住所にある中身: 10

このように、& で住所を取り出し、その住所に対して * を使うことで、元の数値 10 を取り出すことができました。この一連の流れが、C++のメモリ管理の基本となります。

4. 間接演算子(*)によるデータの書き換え

4. 間接演算子(*)によるデータの書き換え
4. 間接演算子(*)によるデータの書き換え

間接演算子は、単に中身を見るだけではありません。その場所にあるデータを書き換えることもできます。これは、元の変数名を使わずに、遠隔操作で値を変更するようなイメージです。

パソコンを触ったことがない方でも、テレビのリモコンを想像してください。テレビ本体のボタンを直接押さなくても、リモコン(ポインタ)を通して「チャンネルを変える(間接演算子による操作)」ことができますよね。実際のコードで確認してみましょう。


#include <iostream>

int main() {
    int score = 50;
    int* pScore = &score; // scoreの住所をメモ

    // 間接演算子を使って、住所にあるスコアを更新する
    *pScore = 100; 

    std::cout << "元のscore変数の値: " << score << std::endl;

    return 0;
}

元のscore変数の値: 100

score = 100; と直接書かなくても、ポインタ経由で数値が変わっているのが分かります。これが、間接演算子の強力な機能です。

5. 記号「*」の二つの顔に注意!

5. 記号「*」の二つの顔に注意!
5. 記号「*」の二つの顔に注意!

初心者が最も混乱するのは、アスタリスク(*)が二通りの意味で使われることです。これを見分けるのが、挫折しないための最大のコツです。

  • 宣言の「*」: int* ptr; のように、変数の種類(型)を決めるときに使います。これは「この変数は住所専用の箱ですよ」という意味です。
  • 間接演算子の「*」: *ptr = 20; のように、計算や代入の中で使います。これは「その住所の扉を開けろ」という命令(動作)を指します。

英語で言えば、同じ単語でも「名詞」として使われるか「動詞」として使われるかで意味が変わるようなものです。文脈の中で判断する練習をしましょう。

6. アドレスと間接演算子の関係をイメージ図で整理

6. アドレスと間接演算子の関係をイメージ図で整理
6. アドレスと間接演算子の関係をイメージ図で整理

これら二つの演算子の関係を図で整理してみましょう。C++におけるメモリのやり取りは、常にこの往復で成り立っています。

変数の箱から住所を取り出すのが &、住所を頼りに箱へ戻るのが * です。もし *(&変数) と書けば、住所に行って戻ってくるだけなので、元の変数と同じ意味になります。この「あべこべ」の関係性が分かると、複雑なプログラムを読んでも迷わなくなります。プログラミング初心者の方は、まずこの「往復の関係」を頭に叩き込みましょう。

7. 安全に使うためのルール:ヌルポインタ

7. 安全に使うためのルール:ヌルポインタ
7. 安全に使うためのルール:ヌルポインタ

間接演算子 * を使うとき、絶対にやってはいけないことがあります。それは、「存在しない住所(デタラメな番号)」の扉を開けようとすることです。これをやってしまうと、プログラムは即座に壊れてしまいます。

安全を確保するために、どこも指していないことを示す nullptr(ヌルポインタ)という特別な状態があります。間接演算子を使う前に、「この住所録は白紙じゃないかな?」と確認する癖をつけることが、一流のプログラマーへの近道です。


#include <iostream>

int main() {
    int* dataPtr = nullptr; // 最初はどこも指さないように初期化

    // 住所が入っているか確認してから中身を触る
    if (dataPtr != nullptr) {
        std::cout << *dataPtr << std::endl;
    } else {
        std::cout << "住所が登録されていません。" << std::endl;
    }

    return 0;
}

8. C++のメモリ管理を支えるポインタの重要性

8. C++のメモリ管理を支えるポインタの重要性
8. C++のメモリ管理を支えるポインタの重要性

なぜこんな面倒な記号を使うのでしょうか?それは、C++がコンピューターの性能を最大限に引き出すための言語だからです。巨大な写真や動画のデータを、いちいちコピーして別の場所に運ぶのは効率が悪いです。代わりに、「あのロッカーにデータがあるから、そこを見てね」と住所(ポインタ)だけを教えれば、動作が非常に高速になります。

アドレス演算子と間接演算子は、コンピューターという巨大な倉庫を効率よく管理するための「検索システム」と「鍵」のような存在です。最初は難しく感じるかもしれませんが、この二つの記号を使いこなせるようになれば、あなたはコンピューターを直接操っているという実感を得られるはずですよ!

カテゴリの一覧へ
新着記事
New1
C++
C++のメンバアクセス演算子を完全解説!初心者でもわかる . → :: の使い方まとめ
New2
Rust
Rustの文字列を極める!&str(文字列スライス)の基本概念とString型との違い
New3
C++
C++のキャスト演算子を完全解説!dynamic_cast・static_cast・const_cast・reinterpret_castを初心者向けに説明
New4
C++
C++開発のIDE選びを完全ガイド!初心者でもわかるCLion・Eclipse CDT・Qt Creator比較
人気記事
No.1
Java&Spring記事人気No1
C++
C++の主要な実装をわかりやすく解説!GCC・Clang・MSVCの違いと特徴
No.2
Java&Spring記事人気No2
C言語
C言語を学ぶ初心者におすすめの環境構築手順【2025年版】
No.3
Java&Spring記事人気No3
C言語
C言語のソースコードとヘッダファイルの役割とは?初心者向けにわかりやすく解説!
No.4
Java&Spring記事人気No4
C言語
C言語をオンラインで実行できる便利なコンパイラサービスまとめ【初心者向け】
No.5
Java&Spring記事人気No5
C言語
C言語開発でよく使われるエディタとIDEランキング【初心者向け完全ガイド】
No.6
Java&Spring記事人気No6
C言語
Visual Studio CodeでC言語を実行する方法【拡張機能の設定と実行手順】
No.7
Java&Spring記事人気No7
C++
C++リンカとコンパイラのオプション設定を完全ガイド!初心者にもわかる開発環境の基礎
No.8
Java&Spring記事人気No8
C言語
C言語の列挙型(enum)の使い方を完全ガイド!初心者でもわかる基本操作