C言語のプリプロセッサマクロは、ソースコードの移植性、可読性、および設定の簡便さを確保するために言語の一部として導入されました。#define、#ifdef、#ifndefディレクティブを使用して、条件付きコードセクションを作成したり、定数を宣言したり、外部ファイルを含めたり(#include)できます。
問題の歴史:
プリプロセッサディレクティブは、さまざまなシステムやコンパイラに合わせてソースコードを適応させる簡素化、ならびに繰り返し作業の自動化のために導入されました。
問題:
プリプロセッサなしではプラットフォームの違いから抽象化することができず、コードのフラグメントを繰り返し使用したり、ヘッダーファイルの二重インクルードから保護したりすることができません。また、マクロは型付けされておらず、スコープを持たないため、注意が必要です。
解決策:
定数の宣言、インライン関数、条件付きコンパイルのために、複数回のヘッダーファイルのインクルードを防ぐためにプリプロセッサマクロを使用します。
コード例:
#ifndef MY_HEADER_H #define MY_HEADER_H #define MAX_SIZE 100 #ifdef DEBUG #define LOG(x) printf("%s\n", x) #else #define LOG(x) #endif #endif /* MY_HEADER_H */
主な特徴:
ヘッダーファイルでインクルードガードを忘れたらどうなりますか?
ヘッダーファイルは別の.cファイルに複数回含まれる可能性があり(他の.hを通じての暗黙の参照も含む)、再定義エラーが発生します。
#defineマクロとインライン関数の宣言の違いは何ですか?
#defineは単にテキストを置き換えるだけで、型や構文の正確性をチェックしませんが、インライン関数は通常の関数であり、型解析のステージでコンパイラがチェックします。
マクロは副作用を含むことがありますか?
はい、マクロが不正確に定義されている場合、引数として渡された式は複数回計算されるかもしれません。例えば:
#define SQUARE(x) (x) * (x) int a = SQUARE(++i); // ++iは2回実行されます!
副作用を引き起こす式を伴った括弧なしのマクロの使用:
#define DOUBLE(x) x + x int result = DOUBLE(1+2); // 結果は6ではなく、1+2+1+2=6?いいえ、1+2+1+2=6ではありません、結局1+2+1+2です。 // しかし、実際には1 + 2 + 1 + 2 = 6になりますが、DOUBLE(++i)の場合、++iは2回適用されます。
利点:
欠点:
括弧を持ち、単純な定数に使用されるマクロの定義:
#define DOUBLE(x) ((x) + (x)) #define BUFFER_SIZE 1024
利点:
欠点: