C言語文法解説シリーズ
本記事は「C言語文法解説シリーズ」の1つです。
C言語の文法を、組み込み開発の視点も交えて解説します。
C言語のポインタは、多くの人が最初につまずくポイントです。
記号が多く、見た目も難しく感じるからです。
しかし、やっていることはとてもシンプルです。
ポインタとは
**「変数の場所(アドレス)を扱うための仕組み」**です。
この記事では、C言語のポインタについて、& と * の意味から順番にわかりやすく解説します。
ポインタとは?
普通の変数は「値」を持ちます。
int a = 10;この場合
a の中身は 10 です。
一方、ポインタは
変数の場所(アドレス) を持ちます。
int a = 10;
int *p = &a;ここでの意味はこうです
- a → 10 を持つ変数
- &a → a の場所
- p → a の場所を持つ変数
つまり
p は
a を指している変数
になります。
メモリの視点での配列とポインタの違いはこちらの記事で解説しています。
& はアドレスを取得する
& は
変数のアドレスを取得する演算子 です。
int a = 10;
int *p = &a;このとき
- a = 10
- &a = a の場所
- p = a の場所
になります。
イメージ
アドレス 値
1000 10 ← ap = 1000p は
a の場所(1000)を覚えています。
* は中身を取り出す
* は
ポインタが指す先の値を取り出す ために使います。
int a = 10;
int *p = &a;
*p = 20;このコードを実行すると
a の値が変わります。
a = 20なぜなら
- p は a を指している
- *p は a の中身
- *p = 20 は a = 20 と同じ
だからです。
つまり
*p は「指している先の変数」
という意味になります。
* の意味は2つある
ポインタでは * が2回出てきます。
int *p = &a;この * は
ポインタ型の宣言 です。
一方こちら
*p = 10;この * は
ポインタの参照 です。
まとめると
| 書き方 | 意味 |
|---|---|
| int *p | ポインタ変数の宣言 |
| *p | 指している先の値 |
同じ記号ですが、意味が違います。
*が2つあるダブルポインタについてはこちらの記事で解説しています。
ポインタを使う理由
ポインタは次のような場面で使います。
関数の中で値を書き換える
void func(int *p)
{
*p = 100;
}
int main()
{
int a = 0;
func(&a);
printf("%d", a);
}結果
100関数の外の変数を変更できます。
配列を扱う
配列はポインタと密接な関係があります。
int arr[3] = {1,2,3};
int *p = arr;配列名は
先頭要素のアドレスになります。
このためポインタで扱えます。
(※これは次の記事で詳しく解説します)
ポインタと配列の違いはこちらの記事で詳しく解説しております。
構造体を効率よく扱う
struct Data data;
struct Data *p = &data;構造体はサイズが大きいので
ポインタで扱うことが多いです。
よくある間違い(未初期化ポインタ)
これは危険なコードです。
int *p;
*p = 10;これは
どこを指しているか分からないポインタに
書き込んでいます。
結果
- クラッシュ
- バグ
- 不定動作
になります。
必ずアドレスを代入してから使います。
int a;
int *p = &a;
*p = 10;ポインタが難しく見える理由
ポインタが難しい理由は
- 記号が多い
- メモリの概念が必要
- 宣言が分かりにくい
でもやっていることは単純です。
ポインタは
「変数の場所を覚える変数」
これだけです。
まとめ
- ポインタはアドレスを扱う変数
- & はアドレス取得
- は中身を参照
- *p は指している先の値
- 関数・配列・構造体で使う
ポインタはC言語の重要な基礎です。
ここを理解すると、配列や構造体の理解も深まります。
この記事が参考になった方へ
C言語の基本文法を一覧で整理しています。
技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。
小さなご相談からでもお気軽にご連絡ください。

コメント