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

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

※どちらもprintf関数にて同じ値が表示される

役割の違い

C言語において#defineと変数は、
使い分ける対象ではなく、役割が最初から分かれているものです。

  • 変わらない仕様・条件・構造を定義 → #define
  • 実行中に変化する値・状態を定義 → 変数

この役割分担を理解すると、
#defineと変数の違いは「覚えるもの」ではなく、
自然に選ばれるものになります。

※この違いは、複雑な構造を扱うようになると
イメージしやすくなります。
単純な動作だけを学習している段階では、
分かりにくく感じるかもしれません。

具体的には処理段階が違う

#defineとグローバル変数では処理段階の違いがあり、処理段階の違いから生じる特徴があります。

C言語のソースコードは、いきなり実行されるわけではありません。
実行ファイルになるまでに、いくつかの段階を経ています。

簡単に整理すると、次の流れです。

  1. プリプロセス
  2. コンパイル
  3. リンク
  4. 実行

#define が処理されるのは、この最初の プリプロセス段階 です。
ここでは、ソースコードはまだ C 言語として解釈されておらず、
コードは単なる文字列として扱われます。

プリプロセッサが行うのは、

  • #defineによる置換
  • 条件付きでのコードの削除・残存
  • #includeの展開

といった、機械的な前処理だけです。

プリプロセス後はAと入力されていた個所に#defineにて設定した10が置換される処理までが実行される。

一方、変数はプリプロセス後、
コンパイル段階以降で扱われます。
この段階で初めて型が決まり、
メモリ配置や実行時の振る舞いが定義されます。

このように、
#defineと変数は、
処理されるタイミングそのものが異なる
という点が根本的な違いです。

処理段階から生じる特徴

プリプロセス段階で処理されることにより、

#define には次のような特徴が生じます。

  • 型を持たない
  • メモリを確保しない
  • 実行時には存在しない

型を持たない
プリプロセッサは型を理解しません。
#defineで定義されたものは、
数値や文字列として扱われているのではなく、
単なる文字列の置き換えです。

メモリを確保しない
#define は値を保持する存在ではありません。
コードを書き換えるためのルールであり、
メモリ上に実体は作られません。

実行時には存在しない
プリプロセスが完了した時点で、
マクロ名はソースコード上から消えています。
実行中に参照や変更を行うことはできません。

まとめ

#defineとグローバル変数は、
見た目や使い方が似ているため、
同じもののように感じられがちです。

しかし実際には、
処理される段階が異なります。

  • #define はプリプロセス段階で処理される
  • 変数はコンパイル・実行段階で扱われる

この違いから、次の性質が生まれます。

  • #defineは型を持たない
  • メモリを確保しない
  • 実行時には存在しない

一方、変数は、

  • 型を持ち
  • メモリに配置され
  • 実行中の値や状態を表す

という役割を担います。

そのため、
#defineと変数は「使い分ける対象」ではなく、
役割が最初から異なるものです。

処理段階と役割の違いを理解すれば、
どちらを使うべきか迷うことはなくなります。

関連記事

C言語:

【C言語】グローバル変数はなぜ使わない方がいいのか

1 COMMENT

【C言語】グローバル変数はなぜ使わない方がいいのか | nana log へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です