3 プリプロセッサー

3.1 ファイルの挿入とマクロ定義

3.1.1 #include

諸君は,#includeをおまじないのように使ってきた.いよいよ,その役割を学習す るときがきた.

#includeはファイルの挿入を行う.例えば,#include <stdio.h>はこれが 書かれた位置に/usr/include/stdio.hというファイルを挿入する.ただ,それだけ のことを行うのである.また,#include "myfunc.h"と書けば,myfunc.hとい うファイルが挿入される.<ファイル名>"ファイル名"は,ファイルの 検索するパスが異なる.<ファイル名>の場合は,標準ヘッダーファイルがあるディ レクトリー--通常は/usr/include--が検索される.一方,"ファイル名"の場 合はカレントディレクトリーが検索される.

リスト1とリスト2をプリプロセッサーで処理した 例を示す.このような書き方は通常のプログラムでは行うことは無い.#includeの 処理を分かり易く示すために極端な例を使っている.通常は,ヘッダーファイルを挿入す るため,プログラムの先頭付近にファイル名.hをインクルードする.

   1 int main(void)
   2 {
   3   #include "main.c"
   4 
   5   return 0;
   6 }

   1 int a, b;
   2 
   3 b=0;
   4 a=b+3;

リスト1とリスト2は,コマンド「gcc -E include.c > include.i」により,プリプロセスの処理が行われる.処理の結果, include.iという処理済のテキストファイルであるリスト3ができ る.このリスト中で行頭が#ではじまる行はラインマークと呼ばれ,次の処理を 行うコンパイラーは,注釈行(コメント)として取り扱う.すなわち,アセンブラ言語に変 換するときに無視する.行頭が#の部分を取り除くと,元のリスト 1の3行目にリスト2が挿入されたことが分かるだろ う.

   1 # 1 "include.c"
   2 # 1 "<built-in>"
   3 # 1 "<コマンドライン>"
   4 # 1 "include.c"
   5 int main(void)
   6 {
   7 # 1 "main.c" 1
   8 int a, b;
   9 
  10 b=0;
  11 a=b+3;
  12 # 4 "include.c" 2
  13 
  14   return 0;
  15 }

3.1.2 #define

マクロ定義#defineには文字列の定義マクロ関数の作成というふた つの使い方がある.これらを使った例をリスト4に示す.これを,プ リプロセッサーで処理した結果をリスト5に示す.

マクロ定義は,「#define マクロ名 文字列」と書く.これ以降,マクロ名で指定した文 字列が指定の文字列に変換される.C言語の慣習では,マクロ名は大文字で書く.

マクロ定義は,文字列の置き換えを行っているだけである.これに注意して使わなくては ならない.

   1 #define HOGE 123
   2 #define FUGA 456
   3 #define SUM(i,j) i+j
   4 
   5 int main(void)
   6 {
   7   int c;
   8 
   9   c=SUM(HOGE,FUGA);
  10 
  11   return 0;
  12 }

   1 # 1 "define.c"
   2 # 1 "<built-in>"
   3 # 1 "<コマンドライン>"
   4 # 1 "define.c"
   5 
   6 
   7 
   8 
   9 int main(void)
  10 {
  11   int c;
  12 
  13   c=123 +456;
  14 
  15   return 0;
  16 }

3.2 組込みマクロ

デバッグのとき,便利である.興味のある者は,自分で学習せよ.

また,教科書のpp.65-66のcoffee breakに書かれているassertマクロは便利である.機 能を理解して使ってみると良い.

3.3 条件付き取り込み

これは,いろいなオプションつきでコンパイルするときに使う.興味のある者は,自分で 学習せよ.


ホームページ: Yamamoto's laboratory
著者: 山本昌志
Yamamoto Masashi
平成19年11月6日


no counter