⬆️

ポインタや参照の振り返り「"&", "*"」

2024/12/27に公開

&*の概念をわかりやすく解説し、さまざまな場面での使い方について説明します。


基本的な意味

  1. *(ポインタ)

    • データのアドレスを保持する特殊な型。
    • 例:
      int x = 10;
      int *ptr = &x; // xのアドレスをポインタptrに保存
      
      ポインタは「他の変数が格納されているメモリの場所」を指します。
  2. &(参照)

    • 既存の変数へのエイリアス(別名)を作るための型。
    • 例:
      int x = 10;
      int &ref = x; // refはxへの参照
      
      参照は「実際の変数そのもの」として動作します。
  3. &(アドレス演算子)

    • 変数のアドレスを取得します。
    • 例:
      int x = 10;
      int *ptr = &x; // xのアドレスをポインタptrに格納
      
  4. *(間接演算子 / デリファレンス演算子)

    • ポインタが指しているアドレスの値にアクセスします。
    • 例:
      int x = 10;
      int *ptr = &x;
      *ptr = 20; // xの値を20に変更
      

関数での使用

1. 値渡し

  • 引数として値そのものを渡します。
  • コピーが渡されるため、関数内での変更は元の変数に影響しません。
  • 例:
    void modifyValue(int val) {
        val = 20; // valを変更しても元の変数には影響なし
    }
    
    int x = 10;
    modifyValue(x);
    // xは10のまま
    

2. 参照渡し(&)

  • 引数として変数そのものを渡します。
  • コピーが作られず、直接操作できるため、関数内での変更が元の変数に反映されます。
  • 例:
    void modifyValue(int &val) {
        val = 20; // valを変更すると元の変数も変更される
    }
    
    int x = 10;
    modifyValue(x);
    // xは20に変更される
    

3. ポインタ渡し(*)

  • ポインタを渡し、変数を操作します。
  • 参照渡しと似ていますが、ポインタの操作が必要です。
  • 例:
    void modifyValue(int *val) {
        *val = 20; // ポインタが指す変数の値を変更
    }
    
    int x = 10;
    modifyValue(&x); // xのアドレスを渡す
    // xは20に変更される
    

戻り値での使用

  1. 値を返す

    • 新しい値を返す方法。
    • 例:
      int addOne(int val) {
          return val + 1;
      }
      
  2. 参照を返す(&)

    • 既存の変数そのものを返す方法。
    • 元の変数を変更可能。
    • 例:
      int& getReference(int &val) {
          return val;
      }
      
      int x = 10;
      int &ref = getReference(x);
      ref = 20; // xも20に変更される
      
  3. ポインタを返す(*)

    • ポインタで既存の変数を返す方法。
    • 例:
      int* getPointer(int &val) {
          return &val;
      }
      
      int x = 10;
      int *ptr = getPointer(x);
      *ptr = 20; // xも20に変更される
      

オブジェクトの使用例

ポインタと参照をメンバに持つクラス

class MyClass {
private:
    int value;      // 通常の値
    int *ptrValue;  // ポインタ
    int &refValue;  // 参照

public:
    MyClass(int v, int &r) : value(v), ptrValue(&v), refValue(r) {}

    void showValues() {
        std::cout << "value: " << value << "\n";
        std::cout << "ptrValue: " << *ptrValue << "\n";
        std::cout << "refValue: " << refValue << "\n";
    }
};

ポインタ vs 参照の違い

  • ポインタ
    • 初期化後でも別のアドレスを指すように変更可能。
  • 参照
    • 初期化時に必ず対象を設定し、後から変更できない。

間違いの具体例

以下は間違い:

void learnSpell(*ASpell &spell) const; // エラー

修正例:

void learnSpell(ASpell *spell);  // ポインタ渡し
void learnSpell(ASpell &spell);  // 参照渡し

どちらを使うべきか?

  1. ポインタを使うべき場面:

    • 可変性が必要(対象を変更可能)。
    • nullptrを扱う必要がある場合。
  2. 参照を使うべき場面:

    • NULLの概念が不要。
    • 必ず有効な変数を操作する場合。

このように、&*はポインタ、参照、アドレスの操作を可能にする重要な要素です。それぞれの役割を理解し、適切に使い分けることが重要です。

Discussion