C言語 プリプロセッサ1
間違っている場所あったら優しく教えてね
種類としては, ファイルの読み込み, 定数(マクロの定義, 条件付きコンパイルがあります)
ファイルの読み込み(ヘッダーファイル)
フィルの読み込みではヘッダーファイルを読み込みます. これは.h
の修飾子がついたファイルのことです.
ヘッダーファイル
ヘッダーファイルには2種類のファイルがあります. 一つ目は標準ヘッダーファイルと呼ばれるもの. もう一つが自作のヘッダーファイルです. それぞれ読み込み方が違います.
- 標準ヘッダーファイル
C言語が元から用意したヘッダーファイル. よく使う<stdio.h>などのファイルは標準ヘッダーファイルの一つです. - 自作ヘッダーファイル
自分で作ったヘッダーファイルです. 自分で名前をつけます.
ヘッダーファイルは以下の様に使う
// 標準ヘッダーファイルの読み込み #include <stdio.h> // 自作ヘッダーファイルの読み込み #incluce "myhedder.h"
標準ヘッダーファイルは<>で囲み自作ヘッダーファイルは""で囲みます.
マクロの定義(#define )
マクロを自分で定義することができます. マクロはコンパイル時には指定したものに置き換わっています.
// 標準ヘッダーのインクルード #include<stdio.h> // マクロの定義 #define message "Hello World!" int main (void) { printf( message ); return 0; }
実行して出力を確認すると
$ ./a.out Hello World!
Hello World!が出力される. defineで定義したものはプリプロセッサでコンパル前に書き換わります.
// 標準ヘッダーのインクルード #include<stdio.h> // マクロの定義 #define message "Hello World!" int main (void) { printf( "Hello World! ); return 0; }
この様に書き換わった状態でコンパイラに渡されます.
よっていつも通りのHello World が出力されます.
以下のソースファイルをコンパイルして実行すると出力結果はどうなるか
#include<stdio.h> #define p printf("HelloWorld!\n"); int main(void){ p p p return 0; }
$ ./a.out Hello World! Hello World! Hello World!
Hello world!が三回出力されます.
なんとこれでも通りました.
#incude <stdio.h> #define p printf("Hello World\n" int main (void){ p ); p ); return 0; }
以下の様な場合はコンパイルエラーが出てしまいました.
文字リテラルの"
と"
の間は分けてはいけない様です.
#include<stdio.h> #define p printf("Hello World!\n int main(void){ p "); return 0;
数字の取り扱い以下の出力はどうなるか
#include <stdio.h> #define four 1 + 3 int main (void) { printf("four = %d\n", four ); printf("four + 1 = %d\n", four + 1 ); printf("four * 2 = %d\n", four * 2 ); printf("four \ 3 = 5d\n", four / 3 ); return 0; }
出力
four = 4 four + 1 = 5 four * 2 = 7 four / 3 = 2
4 * 2 = 8にならず 4 * 2 = 7になってしまっています. defineで定義したマクロはプリプロセッサによって置換されるだけの仕様になっているので printf( four + 2 ); とすると printf( 1 + 3 * 2 ); とコンパイル直前に書き換わります. なので乗法先に計算するルールに則って計算結果の7が出力されます.
改善策としてはこのどちらかの様に () の中を先に計算させることを意識した書き方をすると良いでしょう
#define four (1 + 3) printf( (four) * 2);