1. #include <ファイル名> 2. #include "ファイル名" |
形式1 はコンパイラに最初から用意されている標準ライブラリ用のヘッダファイル、標準ヘッダファイルを取り込むときに記述します。今までのサンプルの一番最初は呪文のように「#include <stdio.h>」となっていたのですが、これは基本的な入出力を扱う標準ライブラリを使いたかったからなのです。ほとんどのプログラムはこの標準ライブラリの力を借りてプログラムされるので、何はともあれ stdio.h はインクルードするようにしましょう。
ちなみにLSI-Cコンパイラでは include で検索するシステムディレクトリを変えられます。変えたいときは第1章の「コンパイラの設定」で_lccの中の -I(ディレクトリ) のところを設定したいディレクトリに変更して下さい。
形式2 はユーザーが作ったヘッダファイルを取り込みたい時に使います。ファイル名はソースファイルと同じにしておくと分かりやすく良いでしょう。
なお、ヘッダファイル中で他のヘッダファイルをインクルードしたり、定義マクロを使ったりしても構いません。
/* ヘッダファイル */ /* defs.h */ #define TRUE 1 #define FALSE 0 #define ON 1 #define OFF 0 #define BUF_SIZE 256 #define ITEM_MAX 1000 /* ソースファイル */ /* prog.c */ #include "defs.h" void main (void) { 〜 } | = 右と左の ソースは 同等 |
/* ソースファイル */ /* prog.c */ #define TRUE 1 #define FALSE 0 #define ON 1 #define OFF 0 #define BUF_SIZE 256 #define ITEM_MAX 1000 void main (void) { 〜 } |
#if 定数式 (定数式が真の場合ここをコンパイル) #else (定数式が偽の場合ここをコンパイル) #endif |
#if 定数式1 (定数式1 が真の場合ここをコンパイル) #elif 定数式2 (定数式2 が真の場合ここをコンパイル) #elif 定数式3 (定数式3 が真の場合ここをコンパイル) ・・・・ #endif |
● #ifdef マクロ名 (マクロ名が定義されている場合ここをコンパイル) #else (マクロ名が定義されていない場合ここをコンパイル) #endif ● #ifndef マクロ名 (マクロ名が定義されていない場合ここをコンパイル) #else (マクロ名が定義されている場合ここをコンパイル) #endif |
◇デバッグがしやすくなる
次のようにコーディングしておくとデバッグしやすくなります。
こうしておけば DEBUG を定義すれば変数の値などを追うことができ、プログラムの実行過程が把握できます。
DEBUG は #define で定義する方法の他にコンパイラの起動オプションを使っても定義できます。この場合、コンパイラの起動オプションを変えるだけでコンパイルする部分を変更できます。つまり、エディタでソースを変更しなくても簡単にデバッグしたりやめたりできます。
コンパイラの起動オプションはコンパイラによって違います。ここで使っているLSI-Cのコンパイラの場合はコンパイルするときに次のようにします。
lcc -DDEBUG test.c
この起動オプションを付けると「#define DEBUG 1」という文がコンパイル時に自動的に挿入されます。
[ 例 ] 条件付きコンパイルでデバッグする例 ex7-1.c
◇コメントとして利用できる
プログラムを修正していくときに修正する前のコードをコメントとして残しておくことがあります。「 /* 」と「 */ 」を使えばコメントにできますが、コメントの入れ子はできないのでコメントにしたい部分が長いと不便です。
この時に #ifdef を使ってコメントにすることが可能です。
#ifdef COMMENT
・・・・・ /* ・・・・・ */
・・・・・・ /* ・・ */
・・・・・
#endif
COMMENT が定義されていなければ、上記部分はコンパイルされずコメントと同じにことになるわけですね。余談ですが、LSI-Cのコンパイラではオプション -cn を指定すればコメントの入れ子も使えるようになります。
◇ヘッダの二重取り込みを避けられる
ヘッダファイルの中でさらに別のヘッダファイルを取り込むことが良くあります。そうすると同じヘッダファイルを1つのソースファイル中に何度も取り込んでしまうことになります。そうすると同じ定義が何度もされてしまいコンパイルエラーとなります。
◇ソースファイル
/* file.c */ | ◇ヘッダファイル1
/* head1.h */ | ◇ヘッダファイル2
/* head2.h */ |
/* def.h */
#ifndef __DEF_H /* __DEF_H が定義されていなければ
ここから下もコンパイル */
#define __DEF_H /* __DEF_H を定義。
これで2回目以降の取り込みではコンパイルされない */
・・・・・・
(ヘッダ本体)
・・・・・・
#endif
1回目のヘッダの取り込みでは __DEF_H は定義されていないので、#define 、本体部分と取り込まれます。この時に __DEF_H が定義されます。
よってこれ以降に def.h を再度取り込んでも既に __DEF_H が定義されているので、本体は取り込まれません。こうしてヘッダファイルの二重取り込みを防止しています。
マクロを定義するときに他のマクロ名と重なっていると1回目の取り込みもされない可能性があるので注意が必要です。できるだけヘッダファイルの名前を使うなどしてユニークなマクロ名にします。