先ほどの「inline」の例で、関数「half」のまったく同じ宣言が「main.c」と「test.c」の2箇所にありました。
inline double half(double arg) { return arg / 2.0; }
このように複数のファイルで同じ内容を参照する場合、それをヘッダーファイルにまとめられます。ヘッダーファイルを用意して、各ソースファイルはそれを参照するように整理すれば、修正があっても1カ所で済ませることができ、開発がしやすくなります。
#ifndef HALF_H_ #define HALF_H_ inline double half(double arg) { return arg / 2.0; } #endif // HALF_H_
#include <stdio.h> #include <stdlib.h> #include "half.h" void test(void); int main(void) { printf("1 / 2 = %f\n", half(1.0)); test(); return EXIT_SUCCESS; }
#include <stdio.h> #include "half.h" extern inline double half(double arg); void test(void) { printf("3 / 2 = %f\n", half(3.0)); }
ヘッダーファイルの最初と最後にあるマクロは、ヘッダーファイルの内容が重複定義されないようにするためのものです。詳しくは前回を参照してください。
このようにしておくと、「half」関数に変更があった場合でも「half.h」を変更するだけで済みます。インライン関数の他にも、次のようなものをヘッダーファイルに書いておくと便利です。
よく行われるのは、モジュール(ソースファイル)の外部インターフェースをヘッダーファイルにまとめておき、その機能を利用したい別のモジュールがそのヘッダーファイルをインクルードできるようにしておくというものです。
次の例を参考にしてみてください。
#include "module1.h" // このオブジェクトは外部から参照できる。 int module_value = 1; // この関数は外部から呼ばれる。 int module_func(const struct STR *p) { /* ... */ return MODULE1_ERROR_SUCCESS; }
#ifndef MODULE1_H_ #define MODULE1_H_ // 外部からオブジェクト module_value を参照できるようにする。 extern int module_value; // 構造体 STR を宣言できるようにする。 typedef struct STR_t { int x, y; } STR; // 関数 module_func が返すコードを定義する。 #define MODULE1_SUCCESS (0x0000) #define MODULE1_ERROR_UNKNOWN (0x0001) #define MODULE1_ERROR_INVALID (0x0002) // 外部から関数 module_func を参照できるようにする。 int module_func(const struct STR *p); #endif // MODULE1_H_
#include <stdlib.h> #include "module1.h" int main(void) { // modulde1 の module_value の値を参照する。 printf("module_value = %d\n", module_value); // modulde1 の module_func 関数を呼び出す。 STR str = { .x = 200, .y = 100}; int code = module_func(str); printf("result = %d\n", code); return EXIT_SUCCESS; }
今回で連載は終了です。連載を通して「Cには確かに学ぶだけの価値がある」と思っていただけたでしょうか。学んだことを活用して、皆さんのプログラミングライフがより楽しくなればと思っています。
最後に、記事を読んでいただいた皆さん、ありがとうございました。
Copyright © ITmedia, Inc. All Rights Reserved.