Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

  1. トップページ
  2. C言語辞典
  3. ポインタの基本(* / &)

ポインタの基本(* / &)

ポインタは「変数のメモリアドレス(番地)を格納する変数」です。『&』演算子でアドレスを取得し、『*』演算子でそのアドレスが指す値を読み書きします。ポインタはC言語の核心的な機能であり、配列・文字列・動的メモリ・関数ポインタのすべてに関わります。

構文
// ポインタ変数を宣言します(型へのポインタ)。
型 *ポインタ変数名;

// 変数のアドレスを取得します(アドレス演算子)。
&変数名

// ポインタが指す場所の値を取得・変更します(間接参照演算子)。
*ポインタ変数名

// ポインタの宣言と初期化を同時に行います。
型 *ポインタ変数名 = &変数名;

// ヌルポインタ(どこも指さない状態を表します)。
型 *ポインタ変数名 = NULL;
ポインタ演算子一覧
演算子名称概要
&アドレス演算子変数のメモリアドレスを返します。ポインタ変数に代入したり、関数に渡したりするために使います。
*(宣言時)ポインタ宣言変数がポインタであることを示します。型の後ろに付けます。
*(式中)間接参照演算子ポインタが指すアドレスにある値を読み書きします。デリファレンスとも呼ばれます。
NULLヌルポインタ定数どのアドレスも指さないことを表します。ポインタの初期化や無効状態の表現に使います。
サンプルコード
#include <stdio.h>

// ポインタで呼び出し元の変数を変更する関数です。
void double_value(int *p) {
    *p = *p * 2; // ポインタが指す場所の値を2倍にします。
}

// 2つの変数の値を交換する関数です。
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(void) {
    int x = 10;
    int *p = &x; // x のアドレスを p に格納します。

    printf("x の値: %d\n", x);   // 『10』と出力されます。
    printf("x のアドレス: %p\n", (void *)&x);
    printf("p の値(アドレス): %p\n", (void *)p);
    printf("p が指す値: %d\n", *p); // 『10』と出力されます。

    // ポインタを通じて値を変更します。
    *p = 20;
    printf("変更後の x: %d\n", x); // 『20』と出力されます。

    // 関数にポインタを渡して値を変更します。
    double_value(&x);
    printf("2倍後の x: %d\n", x); // 『40』と出力されます。

    // 値の交換です。
    int a = 5, b = 9;
    swap(&a, &b);
    printf("a = %d, b = %d\n", a, b); // 『a = 9, b = 5』と出力されます。

    // NULL チェックの例です。
    int *q = NULL;
    if (q == NULL) {
        printf("ポインタは NULL です。\n");
    }

    return 0;
}
概要

C言語では関数の引数は値渡し(コピー)が基本です。関数内で変数の値を変更したい場合はポインタを渡します。ポインタを受け取った関数は、そのアドレスに書き込むことで呼び出し元の変数を変更できます。

初期化していないポインタや解放済みのメモリを指すポインタを参照(デリファレンス)すると、クラッシュや予測不能な動作を引き起こします。ポインタを宣言したら必ず初期化し、使い終わったら『NULL』を代入する習慣をつけてください。

ポインタと配列の関係については『ポインタと配列』を、動的メモリの確保・解放については『malloc() / free()』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。