この記事では「#defineと変数は、実際に使ってみると同じように動くが、本当に同じなのか」
という疑問に対して解説しています。

※どちらもprintf関数にて同じ値が表示される
役割の違い
C言語において#defineと変数は、
使い分ける対象ではなく、役割が最初から分かれているものです。
- 変わらない仕様・条件・構造を定義 → #define
- 実行中に変化する値・状態を定義 → 変数
この役割分担を理解すると、
#defineと変数の違いは「覚えるもの」ではなく、
自然に選ばれるものになります。
※この違いは、複雑な構造を扱うようになると
イメージしやすくなります。
単純な動作だけを学習している段階では、
分かりにくく感じるかもしれません。
具体的には処理段階が違う
#defineとグローバル変数では処理段階の違いがあり、処理段階の違いから生じる特徴があります。
C言語のソースコードは、いきなり実行されるわけではありません。
実行ファイルになるまでに、いくつかの段階を経ています。
簡単に整理すると、次の流れです。
- プリプロセス
- コンパイル
- リンク
- 実行
#define が処理されるのは、この最初の プリプロセス段階 です。
ここでは、ソースコードはまだ C 言語として解釈されておらず、
コードは単なる文字列として扱われます。
プリプロセッサが行うのは、
- #defineによる置換
- 条件付きでのコードの削除・残存
- #includeの展開
といった、機械的な前処理だけです。

プリプロセス後はAと入力されていた個所に#defineにて設定した10が置換される処理までが実行される。
一方、変数はプリプロセス後、
コンパイル段階以降で扱われます。
この段階で初めて型が決まり、
メモリ配置や実行時の振る舞いが定義されます。
このように、
#defineと変数は、
処理されるタイミングそのものが異なる
という点が根本的な違いです。
処理段階から生じる特徴
プリプロセス段階で処理されることにより、
#define には次のような特徴が生じます。
- 型を持たない
- メモリを確保しない
- 実行時には存在しない
型を持たない
プリプロセッサは型を理解しません。
#defineで定義されたものは、
数値や文字列として扱われているのではなく、
単なる文字列の置き換えです。
メモリを確保しない
#define は値を保持する存在ではありません。
コードを書き換えるためのルールであり、
メモリ上に実体は作られません。
実行時には存在しない
プリプロセスが完了した時点で、
マクロ名はソースコード上から消えています。
実行中に参照や変更を行うことはできません。
まとめ
#defineとグローバル変数は、
見た目や使い方が似ているため、
同じもののように感じられがちです。
しかし実際には、
処理される段階が異なります。
- #define はプリプロセス段階で処理される
- 変数はコンパイル・実行段階で扱われる
この違いから、次の性質が生まれます。
- #defineは型を持たない
- メモリを確保しない
- 実行時には存在しない
一方、変数は、
- 型を持ち
- メモリに配置され
- 実行中の値や状態を表す
という役割を担います。
そのため、
#defineと変数は「使い分ける対象」ではなく、
役割が最初から異なるものです。
処理段階と役割の違いを理解すれば、
どちらを使うべきか迷うことはなくなります。
関連記事
C言語:


[…] 【C言語】#defineとグローバル変数の違い […]