授業/C言語基礎/前処理 のバックアップ差分(No.1)


  • 追加された行はこの色です。
  • 削除された行はこの色です。
Cプログラムをコンパイルすると、まず''前処理''が行われ、その後、機械語への翻訳が行われます。
前処理を行うための命令をプリプロセッサーと言います。

前処理では、主に、''ヘッダー・ファイル''の読み込みと、''マクロ定義''の置き換えが行われます。


*ヘッダー・ファイル [#r82ea154]

**#include [#c4be082c]

printf関数は他のファイルで定義された関数であるのに、externを付けたプロトタイプ宣言なしで使っていました。

実は、printf関数のプロタイプ宣言は、''stdio.h'' という''ヘッダー・ファイル''に、以下のように書いてあります。
#geshi(c){{
extern int printf(const char* ...);
}}
(printf関数は、第1引数の文字列に含まれる変換指定子の数によって引数の数が変わるので、定義やプロトタイプ宣言が特殊な形をしています。)

これを ''#include'' プリプロセッサーでCプログラムに読み込むことによって、printf関数が使えるようになります。
#geshi(c){{
#include <stdio.h>

int main(void) {
  printf("Hello World!\n");
  return 0;
}
}}


**< >と" " [#w843e42f]

C言語には標準でいくつかのヘッダー・ファイルが用意してあります。

標準で用意されているヘッダー・ファイルは、ヘッダー・ファイルの名前を不等号記号の確固 ''< >'' で囲んで指定します。

ヘッダー・ファイルは、自分で用意することもできます。

自分で用意したヘッダー・ファイルは、ヘッダー・ファイルの名前をダブル・クォーテーション ''" " '' で囲んで指定します。

例えば、次のようなプログラムとヘッダー・ファイルを用意します(プログラム1a, 1b)。
#geshi(c){{
/*
 *  add.c
 */
double add(double x, double y) {
  return x + y;
}
}}
#geshi(c){{
/*
 *  add.h
 */
extern double add(double, double);
}}


このヘッダー・ファイルを読み込むには、ファイル名をダブル・クォーテーション " " で囲んで、次のように指定します(プログラム1c)。
#geshi(c){{
/*
 *  main.c
 */
#include <stdio.h>
#include "add.h"

int main(void) {
  double x = 1.0, y = 2.0;
  double z = add(x, y);
  printf("%f\n", z);
}
}}
main.c をコンパイルすると、プリプロセッサーによって add.h が読み込まれてから翻訳が行われます。


**演習1 [#mc46541f]
プログラム1a, 1b, 1cを作成し、コンパイルせよ。


*マクロ定義 [#e1c69192]

**#define [#i953841c]

#define はマクロ定義を置換するプリプロセッサーです。
#geshi(c){{
#define 置換される文字列 置換後の文字列
}}






**注意点 [#idc9f798]
マクロ定義は、単に置換されるだけなので、置換後にどうなるかに注意する必要があります。

たとえば、次のプログラムについて考えてみましょう。
#geshi(c){{
/*
 *  main.h
 */
#define X 1 + 1
}}
#geshi(c){{
#include <stdio.h>
#include "main.h"

int main(void) {
  int y = X * 2;
  printf("%d\n", y);
  return 0;
}
}}
main関数だけを見ると、Xの2倍を求めています。

このプログラムをコンパイルすると、まず、マクロ定義 X が 1 + 1 に置き換えられます。
したがって、前処理が行われ、実際に翻訳されるプログラムは次のようになります。
#geshi(c){{
#include <stdio.h>

int main(void) {
  int y = 1 + 1 * 2;
  printf("%d\n", y);
  return 0;
}
}}
X が 1 + 1 に置き換えられ、式が 1 + 1 * 2 になりました。
すると、加算演算子 + よりも乗算演算子 * の方が優先順位が高いので、計算結果は X の2倍の 4 ではなく、3 になってしまいます。



*まとめ [#lf098902]

前処理(''プリプロセッサー'')には、主に、''ヘッダー・ファイル''の読み込み (''#include'') と、マクロ定義の置換 (''#define'') があります。

Cプログラムをコンパイルすると、前処理が行われてから、翻訳が行われます。

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS