C言語におけるアドレス演算子と間接参照の使い分け

概要

C言語において、&* はポインタ操作やメモリ管理の基本となる演算子です。これらを正しく理解することで、関数間でのデータ共有や効率的なメモリ操作が可能になります。本記事では、これらの演算子の動作原理と使用方法を具体的なサンプルコードを交えながら解説します。

アドレス取得演算子 &

& は変数のメモリアドレスを取得するための演算子です。これは「アドレス取得」または「参照取得」とも呼ばれます。

基本的な使用例

以下のコードでは、変数の値とそのメモリアドレスを出力しています。

#include <stdio.h>

int main() {
    int value = 10;
    printf("値: %d\n", value);
    printf("アドレス: %p\n", (void*)&value);
    return 0;
}

出力結果:

値: 10
アドレス: 0x7ffeeaef7bfc

この例では、&value によって変数 value が配置されているメモリ位置が取得されています。

関数引数への適用

& を関数呼び出し時に使用することで、変数のアドレスを渡すことができます。これにより関数内で元の変数を直接変更することが可能です。

#include <stdio.h>

void update(int *target) {
    *target = 20;
}

int main() {
    int data = 10;
    printf("更新前: %d\n", data);
    update(&data);
    printf("更新後: %d\n", data);
    return 0;
}

出力結果:

更新前: 10
更新後: 20

このコードでは、update 関数に data のアドレスを渡すことで、関数内部から元の変数を変更しています。

間接参照演算子 *

* はポインタ変数を介してメモリ上の値を取得または更新するための演算子です。ポインタ宣言時にも使用されますが、その意味は文脈によって異なります。

ポインタの初期化方法

以下はポインタ変数の初期化方法の2つの例です。

// 方法1: 宣言時に初期化
int number = 5;
int *ptr1 = &number;

// 方法2: 初期化後に代入
int *ptr2;
ptr2 = &number;
値の取得と更新

以下は*を使用してポインタ経由で値を操作する例です。

#include <stdio.h>

int main() {
    int sample = 100;
    int *pointer = &sample;
    
    printf("値: %d\n", *pointer); // 間接参照で値取得
    *pointer = 200;              // 間接参照で値更新
    printf("更新後: %d\n", sample);
    return 0;
}

出力結果:

値: 100
更新後: 200

このコードでは、*pointer を使ってメモリ上の値を取得・変更しています。

&* の連携使用

両者の演算子は互いに補完する形で使用されます。以下のコードでは、引数をポインタとして受け取る関数を作成しています。

#include <stdio.h>

void calculate(int *a, int *b) {
    *a = 10;
    *b = *a + *b;
}

int main() {
    int x = 5, y = 3;
    
    calculate(&x, &y);
    printf("x = %d, y = %d\n", x, y);
    return 0;
}

出力結果:

x = 10, y = 13

この例では、& でアドレスを取得し、* で間接参照を行って変数の値を変更しています。

注意事項

  • 未初期化ポインタ 未初期化のポインタを間接参照すると未定義動作になるため、必ず初期化を行ってください。
int *ptr;   // 未初期化
*ptr = 42;  // 未定義動作
  • アドレス取得の誤用 ポインタ変数自身のアドレスを取得するようなミスには注意が必要です。
int *ptr = &value;
printf("%p\n", &ptr);  // ptr変数のアドレスを取得

タグ: C ポインタ アドレス演算子 間接参照 メモリ管理

6月4日 20:01 投稿