
C言語入門|アドレス専用の型:ポインタ
「場所」を入れるための特別な箱―
前の記事では、
& 演算子を使うことで 変数のアドレス(番地)を取得できる
ことを学びました。
ここで、多くの人が次のように考えます。
アドレスって符号なしの大きな数値だし、
unsigned long 型に入れればいいんじゃない?
一見すると正しそうですが、
この考え方には落とし穴 があります。

unsigned long 型にアドレスを入れると何が問題?
次の例を見てください。
unsigned long total_users = 5000000UL; // ユーザー数
unsigned long server_id = 1024UL; // サーバ識別番号
unsigned long addr_server = (unsigned long)&server_id; // アドレス3つとも unsigned long 型 ですが、中身の意味はまったく違います。
| 変数名 | 中身の意味 |
|---|---|
| total_users | 計算や比較に使う数値 |
| server_id | 識別番号としての数値 |
| addr_server | メモリ上の番地 |
ここが重要なポイントです。
- unsigned long は 数値計算のための型
- アドレスは 計算したり比較したりする対象ではない
にもかかわらず、
同じ型に入れてしまうと、こうなります。
unsigned long を使うことの弊害
| 問題点 | 説明 |
|---|---|
| 意味が区別できない | 数値なのかアドレスなのか、コードを見ただけでは分からない。 |
| 誤った演算ができてしまう | 加算・減算・比較が文法上できてしまう。 |
| バグの温床になる | アドレスを数値として扱う事故が起きやすい。 |
つまり、
unsigned long に入るから安全
ではなく
入ってしまうから危険
なのです。
アドレスは「数値」ではなく「場所」
ここで考え方を切り替えましょう。
| 種類 | 本質 |
|---|---|
| 数値 | 大小比較・計算するもの |
| アドレス | メモリ上の場所を示すもの |
アドレスはたまたま
「大きな符号なし整数っぽい見た目」
をしているだけです。
意味が違うものは、型も分けるべき
これが C 言語の考え方です。
アドレス専用の型が用意されている
そこで登場するのが、
アドレスを格納するための専用の型 です。
C 言語では最初から用意されています。
アドレスを格納する型の書式
ポインタ型の基本形
| 書式 | 意味 |
|---|---|
| void* 変数名 | アドレス専用の変数を宣言する。 |
void* 型は、
- 計算用の数値を入れる型ではない。
- メモリの場所を示すためだけの型
です。
void* の void に惑わされないで
よくある誤解があります。
void って、関数の戻り値で使った void と同じ?
名前は同じですが、役割は別です。
| 用途 | 意味 |
|---|---|
| 関数の void | 戻り値・引数が存在しない。 |
| void* | 型未定のアドレスを格納する。 |
今回は
void *= アドレス専用の箱
と覚えてOKです。
サンプルプログラムで確認してみよう
unsigned long を使わず、
ポインタ型で正しく書いてみます。
プロジェクト名:9-6-1 ソースファイル名: sample9-6-1.c
#include <stdio.h>
int main(void)
{
int level = 5;
printf("現在のレベルは %d です。\n", level);
void* address = &level;
printf("level のアドレスは %p です。\n", address);
return 0;
}実行結果例
現在のレベルは 5 です。
level のアドレスは 0x7ffdd3a8c41c です。※ アドレスは環境・実行ごとに変化します。
このプログラムで使っている命令
| 要素 | 書式 | 役割 |
|---|---|---|
| & 演算子 | &変数 | 変数の先頭アドレスを取得 |
| void* | void* 変数名 | アドレスを格納する |
| printf | printf(書式, 値) | 情報を表示 |
| %p | 書式指定子 | アドレス表示専用 |
| return | return 値 | main関数を終了 |
特に重要なのは %p です。
アドレス表示では 必ず %p を使う のがルールです。
ポインタとは何か
ここで整理しましょう。
| 項目 | 内容 |
|---|---|
| ポインタ型 | アドレスを格納する型 |
| ポインタ変数 | アドレスを値として持つ変数 |
| 格納されるもの | データそのものではない |
ポインタは、
値を持つ箱ではなく
値がある場所を指す矢印
のような存在です。
まとめ:なぜ unsigned long ではダメなのか(まとめ)
| 観点 | unsigned long | ポインタ型 |
|---|---|---|
| 意味の明確さ | あいまい | 明確 |
| 計算の危険 | 高い | 低い |
| 可読性 | 悪い | 良い |
| C言語らしさ | 低い | 高い |
アドレスはアドレスとして扱う
これが C 言語の世界の基本ルールです。
次の一歩へ
ここまでで、
- アドレスは & で取得する
- アドレスは unsigned long に入れない
- ポインタ型に格納する
という大切な考え方を身につけました。
次は、
ポインタが指している先の値を操作する方法
に進みます。
ここからが、C言語の本領発揮です。
この理解ができたあなたは、
もう 「アドレスを数値として扱わない」Cエンジニア です。
次は、
そのアドレスを使って 中身にアクセスする方法 に進みましょう。
