ヘッダファイルの勉強
include< >とinclude" "の違い?
include<>を使用すると,プリプロセッサは「システム標準のディレクトリ」内でヘッダーファイルを検索する。
include""を使用すると,プリプロセッサは「カレントディレクトリ⇒コンパイラーの-Iオプションなどで命名されたディレクトリ⇒システム標準のディレクトリ」の順でヘッダーファイルを検索する。
実験
以下の3種類のファイルを作成する。
/* main.c */ #include<stdio.h> #include<thank.h> int main(){ thank(); return 0; } /* thank.h */ void thank(void); /* thank.c */ #include<stdio.h> #include<thank.h> void thank(void){ printf("Thank you!\n"); }
これでコンパイルすると,
$ gcc main.c thank.c main.c:3:18: fatal error: thank.h: そのようなファイルやディレクトリはありません compilation terminated. thank.c:3:18: fatal error: thank.h: そのようなファイルやディレクトリはありません compilation terminated.
システム標準のディレクトリにはthank.hがないのでエラーがでる.ということで,以下のように書き直す。
/* main.c */ #include<stdio.h> #include"thank.h" int main(){ thank(); return 0; } /* thank.h */ void thank(void); /* thank.c */ #include<stdio.h> #include"thank.h" void thank(void){ printf("Thank you!\n"); }
同様にコンパイルすると
$ gcc main.c thank.c $ ./a.out Thank you!
さっきと違い無事に実行ファイルが作成できる。
#ifndefとか#endifって何?
#ifndef
機能 : 識別子が定義されていないかどうかの判定
書式 :
#ifndef <識別子名><処理>
詳細 : <識別子名>が未定義なら<処理>を実行。<処理>が複数行にわたる場合は、処理ブロックの最後を示すために#endifを記述する。
#endif
機能 : #ifdef、#ifndefなどによる処理ブロックの最後を明示
詳細 : #ifndefの結果が「真」なら続く<処理>を1行実行。複数行の処理を実行させたい場合は、その最後に#endifを記述してブロックの終端を示す。処理の構造を分かりやすくするため、1行の処理の最後に#endifを記述してもよい。
実験
以下の2種類のファイルを作成する。
/* main.c */ #include "num.h" #include "num.h" int main(){ return 0; } /* num.h */ int number = 3;
これでコンパイルすると,
$ gcc main.c In file included from main.c:2:0: num.h:1:5: error: redefinition of ‘number’ int number = 3; ^ In file included from main.c:1:0: num.h:1:5: note: previous definition of ‘number’ was here int number = 3; ^
変数numberが再定義されているというエラーが出る。したがって、num.hを以下のように書きなおす。
/* num.h */ #ifndef _NUM_H_INCLUDED_ #define _NUM_H_INCLUDED_ int number = 3; #endif
同様にコンパイルすると
$ gcc main.c $
といったように、コンパイル完了しエラーを回避できた。