C言語ポインタ完全マスター: 実践的エキスパートガイド
C言語ポインタをマスターする
C言語のポインタの核心概念を、メモリアドレスから実践例、よくある落とし穴まで網羅。実践的なコードで理解を深めたい開発者向けのチュートリアルです。
ポインタは効率的なCプログラミングの基石です。ポインタに入る前に、C言語におけるメモリアドレスの仕組みを復習しましょう。
C言語におけるメモリアドレス
変数varがあるとき、式&varはvarが格納されているアドレスを生成します。
アドレス操作はscanf()などで頻繁に登場します:
scanf("%d", &var);
これはユーザーの入力をvarのメモリ位置に直接格納します。簡単なデモ:
#include <stdio.h>
int main() {
int var = 5;
printf("var: %d\n", var);
printf("address of var: %p", &var);
return 0;
}
出力
var: 5 address of var: 0x7fffc1a2b1c8
注意: アドレスは実行ごと、システムごとに異なります。
ポインタとは何か?
ポインタは、通常の値ではなくメモリアドレスを保持する変数です。アドレスを格納することで、データへの間接アクセスを可能にし、動的メモリ管理、効率的なデータ構造、低レベルシステム制御を実現します。
ポインタの宣言
典型的な宣言構文:
int *p;
以下のバリエーションも一般的です:
int *p1; int *p2;
アスタリスク周りのスペースは宣言に影響しません。ただし、カンマ区切りの宣言には注意が必要です:
int *p1, p2; /* p1はポインタ、p2はint */
ポインタへのアドレス代入
例:
int *pc, c;
c = 5;
pc = &c;
ここでは、cに値5が代入され、pcにcのアドレスが格納されます。
ポインタの逆参照
ポインタが参照しているアドレスに格納された値にアクセスするには、逆参照演算子*を使用します:
int *pc, c;
c = 5;
pc = &c;
printf("%d", *pc); /* 5を出力 */
pcはポインタであり、*pcがその指す値を取得します。*pcにアドレスを代入しようとする(例:*pc = &c;)のは無効です。
*演算子は逆参照演算子と呼ばれます。
ポインタを通じた値の変更
ポインタ経由で元のデータを変更できます:
int *pc, c;
c = 5;
pc = &c;
*pc = 1; /* cが1になる */
printf("%d", c); /* 1を出力 */
再代入により、複数の変数が同じポインタを共有できます:
int *pc, c, d;
c = 5;
d = -15;
pc = &c;
printf("%d", *pc); /* 5 */
pc = &d;
printf("%d", *pc); /* -15 */
実践例
以下の完全なプログラムを実行して、ポインタの値(アドレス)が一定である一方、参照先のデータが変化する様子を観察してください:
#include <stdio.h>
int main() {
int *pc, c;
c = 22;
printf("Address of c: %p\n", &c);
printf("Value of c: %d\n\n", c);
pc = &c;
printf("Address of pointer pc: %p\n", pc);
printf("Content of pointer pc: %d\n\n", *pc);
c = 11;
printf("Address of pointer pc: %p\n", pc);
printf("Content of pointer pc: %d\n\n", *pc);
*pc = 2;
printf("Address of c: %p\n", &c);
printf("Value of c: %d\n\n", c);
return 0;
}
出力
Address of c: 0x7fffc1a2b1c8 Value of c: 22 Address of pointer pc: 0x7fffc1a2b1c8 Content of pointer pc: 22 Address of pointer pc: 0x7fffc1a2b1c8 Content of pointer pc: 11 Address of c: 0x7fffc1a2b1c8 Value of c: 2
解説
int *pc, c;– ポインタpcとintcを宣言。c = 22;– cのメモリに22を格納。pc = &c;– pcをcに向ける。c = 11;– 直接アクセスで値を更新。*pc = 2;– ポインタ経由で値を変更。
ポインタでよくある間違い
典型的なエラーには、ポインタと値の取り違えがあります:
int c, *pc;
// 間違い – 値をポインタに代入
pc = c; // エラー
// 間違い – 逆参照先にアドレスを代入しようとする
*pc = &c; // エラー
// 正しい – アドレスをポインタに代入
pc = &c; // OK
// 正しい – ポインタが指す場所に値を代入
*pc = c; // OK
初心者にはint *p = &c;の構文がわかりにくいかもしれません。これは以下と等価です:
int *p;
p = &c;
int* p = &c;と書くと曖昧さが減らせます。
ポインタを理解したら、次は配列との関係性を次のチュートリアルで学びましょう。
C言語
- C# Hello World – 初めてのC#アプリケーション構築
- C# キーワードと識別子:ルール、一覧、ベストプラクティス完全ガイド
- C# 変数とプリミティブデータ型:完全マスターガイド
- C#演算子完全ガイド:C#における演算子の包括的解説
- C# ビット演算子とビットシフト演算子をマスターする:包括的ガイド
- C# 入出力の基礎:ユーザー入力と出力の基本をマスター
- C# の式、文、ブロック:実践例で徹底理解
- C# コメントをマスターする:種類、ベストプラクティス、XML ドキュメント
- C言語ポインタ完全マスター: 実践的エキスパートガイド
- C言語における配列とポインタの関係を理解する
- C言語: アドレスとポインタを関数に渡す – 実践ガイド