C言語のマクロとプリプロセッサを徹底解説!主要ディレクティブと定義済みマクロの使い方
Cプリプロセッサ(CPP)は、コンパイラの一部ではなく、コンパイル処理における独立したステップとして動作します。簡単に言えば、Cプリプロセッサはテキストの置換を行うツールであり、実際のコンパイルが始まる前に必要な前処理をコンパイラに指示する役割を担っています。
プリプロセッサディレクティブの基本ルール
すべてのプリプロセッサコマンドはハッシュ記号(#)で始まります。この記号は空白以外の最初の文字でなければならず、可読性の観点から、プリプロセッサディレクティブは行の先頭(第1カラム)から記述することが推奨されます。
以下に、重要なプリプロセッサディレクティブを一覧でまとめました。
| 番号 | ディレクティブと説明 |
|---|---|
| 1 | #define プリプロセッサマクロを定義(置換)します。 |
| 2 | #include 別のファイルから特定のヘッダを挿入します。 |
| 3 | #undef 定義済みのプリプロセッサマクロを解除します。 |
| 4 | #ifdef 指定したマクロが定義されている場合に真を返します。 |
| 5 | #ifndef 指定したマクロが定義されていない場合に真を返します。 |
| 6 | #if コンパイル時の条件が真かどうかを判定します。 |
| 7 | #else #if の条件が偽の場合の代替処理を指定します。 |
| 8 | #elif #else と #if を1つの文にまとめたものです。 |
| 9 | #endif プリプロセッサの条件分岐を終了します。 |
| 10 | #error 標準エラー出力(stderr)にエラーメッセージを出力します。 |
| 11 | #pragma 標準化された方法で、コンパイラに特別な命令を発行します。 |
プリプロセッサの実例
ここからは、具体的なコード例を通じて、各ディレクティブの使い方を詳しく見ていきましょう。
#define による定数定義
#define MAX_ARRAY_LENGTH 20
このディレクティブは、ソースコード内の MAX_ARRAY_LENGTH をすべて 20 に置き換えるようCPPに指示します。定数に #define を使うことで、コードの可読性が向上します。
#include によるヘッダファイルの読み込み
#include <stdio.h> #include "myheader.h"
1行目は、システムライブラリから stdio.h を取得し、その内容を現在のソースファイルに追加するよう指示します。2行目は、カレントディレクトリから myheader.h を取得して同様に追加することを意味します。山括弧(<>)と二重引用符("")で使い分ける点に注意しましょう。
#undef と #define の組み合わせ
#undef FILE_SIZE #define FILE_SIZE 42
この例では、既に定義されている FILE_SIZE の定義を一度解除し、改めて 42 として再定義しています。
#ifndef による二重定義の防止
#ifndef MESSAGE #define MESSAGE "You wish!" #endif
このディレクティブは、MESSAGE がまだ定義されていない場合にのみ、MESSAGE を定義するようCPPに指示します。ヘッダファイルのインクルードガードとして頻繁に使われるパターンです。
#ifdef によるデバッグコードの切り替え
#ifdef DEBUG /* ここにデバッグ用の処理を記述 */ #endif
この例では、DEBUG が定義されている場合にのみ、囲まれた処理がコンパイル対象となります。gccコンパイラでコンパイル時に -DDEBUG フラグを渡すと DEBUG が定義されるため、デバッグ処理のオン/オフをコンパイル時に簡単に切り替えられます。
ANSI C の定義済みマクロ
ANSI Cでは、あらかじめ定義された複数のマクロが用意されています。これらはプログラム内で自由に参照できますが、直接変更してはいけません。
| 番号 | マクロと説明 |
|---|---|
| 1 | __DATE__ 現在の日付を "MMM DD YYYY" 形式の文字列リテラルとして返します。 |
| 2 | __TIME__ 現在の時刻を "HH:MM:SS" 形式の文字列リテラルとして返します。 |
| 3 | __FILE__ 現在のファイル名を文字列リテラルとして格納します。 |
| 4 | __LINE__ 現在の行番号を10進数の定数として格納します。 |
| 5 | __STDC__ コンパイラがANSI規格に準拠している場合に 1 として定義されます。 |
定義済みマクロの使用例
以下のサンプルコードは、各定義済みマクロの実際の出力を確認できるものです。
#include <stdio.h>
int main() {
printf("File :%s\n", __FILE__ );
printf("Date :%s\n", __DATE__ );
printf("Time :%s\n", __TIME__ );
printf("Line :%d\n", __LINE__ );
printf("ANSI :%d\n", __STDC__ );
}
実行結果
File :test.c Date :Jun 2 2012 Time :03:36:24 Line :8 ANSI :1
このように、定義済みマクロを活用することで、ファイル名や行番号などの情報を簡単に取得でき、デバッグやログ出力の際に非常に役立ちます。プリプロセッサの仕組みを理解することは、効率的なC言語プログラミングの第一歩と言えるでしょう。
-
Microsoft Excelでマクロを作成・実行する方法を徹底解説
Microsoft Excelでは、マクロはVisual Basic(VBA)というプログラミング言語で記録され、さまざまな方法で実行できます。開発タブの「マクロ」コマンドから実行する方法、ショートカットキーの組み合わせを使う方法、図形オブジェクトをクリックする方法、クイックアクセスツールバーのボタンから実行する方法などがあります。この記事では、Excelでマクロを作成して実行する手順をわかりやすく解説します。 マクロとは? マクロとは、一連の操作やアクションを自動化するための機能です。同じ作業を何度も繰り返す手間を省き、日常業務の効率化に大きく役立ちます。 Excelでマクロを作成・実行する
-
Pythonで3の倍数と7の倍数の組み合わせで数値nを作れるか判定する方法
ある正の整数 n が与えられたとき、その n を「3の非負の倍数」と「7の非負の倍数」の合計として表すことができるかどうかを判定する問題を考えてみましょう。例えば、入力が 13 の場合、出力は True になります。なぜなら、13 = 1×7 + 2×3 と表せるからです。解法のアプローチこの問題は、次の手順で解くことができます。i を 0 から n+1 まで、7 ずつ増やしながら繰り返します。各 i について、(n − i) が 3 で割り切れるかどうかを確認します。割り切れる場合は True を返します。ループを最後まで回っても条件を満たさなかった場合は、False を返します。このアルゴ