ソースファイル
CoddyのCジャーニー「Object Oriented Programming」セクションの一部 — レッスン 3/61。
これまでは、関数の宣言をヘッダーファイルに配置してきましたが、実際の関数のコード(定義)はメインファイルに記述されていました。モジュール化プログラミングの次のステップは、それらの定義を独自のソースファイル(.cファイル)に移動することです。
これにより、クリーンな3部構成が作成されます。ヘッダーで関数を宣言し、別のソースファイルでそれらを定義し、mainでそれらを使用するという構成です。実際の構成は次のようになります:
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif
// math_utils.c
#include "math_utils.h"
int add(int a, int b) {
return a + b;
}
// main.c
#include <stdio.h>
#include "math_utils.h"
int main() {
printf("%d\n", add(5, 3));
return 0;
}
math_utils.c が自身のヘッダーをインクルードしていることに注目してください。これにより、関数の定義が宣言と一致することが保証されます。もし一致しない場合は、コンパイラがエラーを検出します。メインファイルは関数を使用するためにヘッダーをインクルードするだけでよく、add が内部でどのように動作するかを知る必要はありません。
この分離により、実装の詳細が隠蔽され、それらの関数を使用するファイルに手を加えることなく、関数のロジックを変更できるようになります。
チャレンジ
簡単コードを適切な3つのファイル構造(宣言用のヘッダー、実装用のソースファイル、およびそれらを使用するメインファイル)に整理して、シンプルな数学ユーティリティを作成しましょう。
以下の3つのファイルを作成します:
math_ops.h:multiplyとsubtractの2つの操作の関数宣言を含むヘッダーファイルです。両方の関数は2つの整数を受け取り、整数を返します。シンボルMATH_OPS_Hを使用したインクルードガードを忘れないでください。math_ops.c:multiplyとsubtractの実際の実装を含むソースファイルです。このファイルは、宣言と定義が一致することを確認するために、自身のヘッダーをインクルードする必要があります。main.c: ヘッダーをインクルードし、両方の関数を使用して計算を実行するメインファイルです。
multiply 関数は2つの整数の積を返し、subtract は最初の整数から2番目の整数を引いた値を返す必要があります。
2つの整数の入力 a と b を受け取ります。
メイン関数で、両方の操作の結果を別々の行に出力してください:
Product: {result of multiply}
Difference: {result of subtract}例えば、入力が 8 と 3 の場合、出力は以下のようになります:
Product: 24
Difference: 5チートシート
関数定義は、メインファイルから別のソースファイル(.cファイル)に移動させることができ、3つのパートからなるモジュール構造を作成できます。
- ヘッダーファイル(
.h):関数の宣言が含まれます - ソースファイル(
.c):関数の定義が含まれます - メインファイル(
main.c):関数を使用します
構造の例:
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif
// math_utils.c
#include "math_utils.h"
int add(int a, int b) {
return a + b;
}
// main.c
#include <stdio.h>
#include "math_utils.h"
int main() {
printf("%d\n", add(5, 3));
return 0;
}
ソースファイル(.c)は、関数の定義が宣言と一致することを保証するために、自身のヘッダーをインクルードする必要があります。メインファイルは、関数を使用するためにヘッダーをインクルードするだけでよく、実装の詳細は隠蔽されます。
自分で試してみよう
#include <stdio.h>
#include "math_ops.h"
int main() {
int a, b;
scanf("%d", &a);
scanf("%d", &b);
// TODO: a と b を引数にして multiply 関数を呼び出し、結果を保存する
// TODO: a と b を引数にして subtract 関数を呼び出し、結果を保存する
// TODO: 次の形式で結果を表示する:
// Product: {multiply の結果}
// Difference: {subtract の結果}
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。