前処理司令とは、コンパイルの前に、テキスト上の処理を行う
前処理司令を使うことで、別のファイルを読み込んだり、記号定数を用意したり、条件付きコンパイルなどを行うことができる
前処理の工程を行うのがプリプロセッサ(preprocessor)
### 前処理司令
– #inclue: 指定されたファイルを挿入
– #define: マクロ定義
– #undef: マクロ定義を取り消す
– #if #ifdef #ifndef: 条件付きコンパイル
– #elif #else #endif: 同上
– defined: #if, #elifの中で判定処理に用いる単項演算子
– #line: 行番号の付け替え
– #pragma: コンパイラへのオプション指示
– #error: 前処理時のエラー表示
– # : #defineの中で使用時:仮引数の文字列化、単独使用時: 空司令であり何も実行しない
– ## : 字句の連結
### #inclue
指定されたファイルをディスクから読み込み、その場所に挿入する
/* myhead.h */ int hdt = 1234; void myfunc(void){ printf("test program\n"); }
#include <stdio.h> #include "myhead.h" int main(void){ myfunc(); printf("hdt=%d\n", hdt); return 0; }
includeで指定するファイルはヘッダファイルと呼ばれる
ヘッダファイルは.hが付いており、標準ディレクトリから対象ファイルを探す
### #define
– オブジェクト形式マクロ
defineは文字列の置き換えを行う。関数のような形式でマクロ置換をすると言う意味をもつ
大文字で書くのが慣例
#define MYSIZE 100
#define MYSTR “abc”
#define MYCH ‘A’
#define begin {
#define end }
stdio.hではEOFは(-1)と定義されている
– 関数形式マクロ
#define average(a,b) (a+b)/2
#define putd(dt) printf(“%d\n”,dt);
関数式マクロは慎重に記述する必要がある
#include <stdio.h> #define MAXSIZE 1234 #define average(a,b) (a+b)/2 #define putd(dt) printf("%d\n", dt) int main(void){ int n1, n2; n1 = MAXSIZE; n2 = average(1111, 3333); printf("n1=%d\n", n1); printf("n2=%d\n", n2); putd(n2); return 0; }
$ ./dev
n1=1234
n2=2222
2222
### #if
if, elif, else, endifで条件付きコンパイル
デバッグ用によく使用される
#define JAPAN_MODE 1 #if JAPAN_MODE == 1 char msg[] = "こんにちは"; #else char msg[] = "Hello"; #endif int main(void){ printf("msg=%s\n", msg); return 0; }
フレームワークだと、#defineなどの定義はまとめて別ファイルに書くことが多いように思いますが、includeの下に書くんですね。言語の歴史が見れて面白い。