【6日でできるC言語入門】ポインタ

C言語の大きな特徴のひとつが「ポインタ」です。
 ポインタはアドレス(メモリ上の場所)を格納する特別な変数であり、C言語ならではの強力な機能です。
 メモリ操作、関数へのデータ受け渡し、配列や文字列操作など、多くの場面で使われます。ポインタを正しく理解すれば、C言語のプログラムがさらに自由自在に書けるようになります。

1.ポインタとは何か

1.1. ポインタ変数の定義と意味

  • ポインタ変数とは、「変数のアドレス」を格納できる変数です。
  • 通常の変数は値そのものを保存しますが、ポインタ変数は「アドレス=メモリの場所」を保存します。

ポインタ変数の定義例

int* p;    // int型の変数のアドレスを保存できるポインタ変数p
double* q; // double型の変数のアドレスを保存できるポインタ変数q

ポインタ変数の特徴を表で整理

種類意味
通常の変数int a;aはint型の値を格納する。
ポインタ変数int* p;pはint型の変数のアドレスを格納する。
アドレス取得&aaのアドレスを取得する。
ポインタ参照*ppが指すアドレスに格納されたを取り出す。

2.ポインタの使い方(サンプルプログラム)

2.1. ポインタで値を間接的に操作

以下は、ポインタを使って変数の値を操作するサンプルです。

プロジェクト/ファイル名: Lesson50_1/main.c

#include <stdio.h>

void disp(int, int, int);

int main(void) {
    int a = 50;
    int b = 150;
    int* p = NULL; // ポインタ変数pをNULLで初期化

    p = &a;        // pにaのアドレスを代入
    disp(a, b, *p);

    *p = 300;      // *pはaと同じ。aの値が300に書き換わる
    disp(a, b, *p);

    p = &b;        // pにbのアドレスを代入
    *p = 500;      // bの値が500に書き換わる
    disp(a, b, *p);

    return 0;
}

void disp(int n1, int n2, int n3) {
    printf("a = %d, b = %d, *p = %d\n", n1, n2, n3);
}

実行結果

a = 50, b = 150, *p = 50
a = 300, b = 150, *p = 300
a = 300, b = 500, *p = 500

2.2. 詳細解説

  • int* p = NULL; … ポインタ変数はNULLで初期化するのが安全です。
  • p = &a; … 変数aのアドレスをpに代入(pは「aを指す」状態)。
  • *p = 300; … 「pが指す先」に値を代入。ここではaの値が300に変わる。
  • p = &b; … 今度はbのアドレスをpに代入(pは「bを指す」状態)。
  • *p = 500; … bの値が500に変わる。

3. ポインタと型の関係

3.1. 型の一致が大原則

ポインタ変数には、同じ型の変数のアドレスしか代入できません。
型が違うと動作が保証されません(例:int型のアドレスをdouble*には代入できない)。

変数の型OKなポインタNGなポインタ
int a;int* p = &a;char* p = &a;
double d;double* q = &d;int* q = &d;

4.NULLで初期化する理由

4.1. ポインタの安全な初期化

  • ポインタ変数を宣言しただけでは「どこを指しているか分からない」状態です。
  • NULL で初期化することで「どこも指していない」ことを明示できます。

5.ポインタの使い方まとめ

操作記述例意味
ポインタの宣言int* p;int型を指すポインタpを宣言
ポインタへのアドレス代入p = &a;pにaのアドレスを代入
ポインタ経由で値を参照*ppが指す先(aやb)の値を取得
ポインタ経由で値を書き換え*p = 200;pが指す先(aやb)の値を200に変更

まとめ

  • ポインタは「アドレス(場所)」を格納できる特別な変数。
  • *演算子で値にアクセスし、&演算子でアドレスを取得する。
  • ポインタの型は必ず格納する変数の型と一致させる。
  • ポインタ変数は初期化時にNULLを使うと安全。

ポインタを理解すれば、C言語の本格的な活用に大きく近づきます!