0Pricing
C Academy · レッスン

複数ファイルのプロジェクト

ヘッダーと翻訳単位です。

「複数ファイルのプロジェクト」はCoddyKit上の無料C Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C Academyコースには全4レッスンが含まれています。

ファイルを分割する理由

実際のプログラムが1つの.cファイルだけで構成されることはありません。コードを複数のファイルに分割すると、次のことが可能になります。

  • 関連する関数をまとめられます
  • 変更された部分だけをコンパイラーで再ビルドできます
  • コードを複数のプロジェクトで再利用できます
  • チームで作業しても、頻繁な競合を避けられます

各部品がどのようにリンクされるかを理解することが重要です。

翻訳単位

各.cファイルは、#includeがプリプロセッサによって展開された後、翻訳単位になります。

コンパイラーは各翻訳単位を独立してオブジェクトファイル(.o)に変換します。この段階では、他のファイルについて認識していません。

宣言と定義

宣言は、関数が存在することとそのシグネチャをコンパイラーに伝えます。定義は、実際の本体を提供します。

他のファイルは、関数を呼び出すために宣言だけを必要とします。定義は1か所にだけ存在します。

int add(int a, int b);          /* declaration: a promise */

int add(int a, int b) {         /* definition: the body */
    return a + b;
}

ヘッダーファイル

宣言はヘッダー(.h)に記述します。その関数を使いたいファイルは、ヘッダーをインクルードします。

ヘッダーは公開インターフェースであり、対応する.cファイルは非公開の実装です。

/* math_utils.h */
#ifndef MATH_UTILS_H
#define MATH_UTILS_H

int add(int a, int b);
int mul(int a, int b);

#endif

実装ファイル

.cファイルでは、自分自身のヘッダーをインクルードして関数を定義します。

自分自身のヘッダーをインクルードすると、定義が宣言と一致しているかをコンパイラーが検証できます。

/* math_utils.c */
#include "math_utils.h"

int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }

モジュールを使う

別のファイルはヘッダーをインクルードして関数を呼び出します。関数本体を見えるようにする必要はありません。

コンパイラーは宣言を信頼し、後でリンカーが呼び出しを実際の定義に接続します。

/* main.c */
#include <stdio.h>
#include "math_utils.h"

int main(void) {
    printf("%d\n", add(2, 3));
    return 0;
}

コンパイルとリンク

2つの段階があります。まず各ファイルを-cでコンパイルしてオブジェクトファイルにします。次に、そのオブジェクトファイルをリンクして1つの実行ファイルにします。

リンカーはmath_utils.oで定義を見つけることにより、addへの各呼び出しを解決します。

gcc -c main.c          # -> main.o
gcc -c math_utils.c    # -> math_utils.o
gcc main.o math_utils.o -o app

二重引用符と山かっこ

インクルード構文によって検索パスが決まります。

  • #include "math_utils.h"は、まずプロジェクトのディレクトリを検索します
  • #include <stdio.h>は、システムのインクルードパスだけを検索します

自作のヘッダーには二重引用符を、標準ライブラリには山かっこを使います。

externキーワード

ファイル間でグローバル変数を共有するには、1つの.cファイルで定義し、ヘッダーでexternを使って宣言します。

externは「この変数は別の場所に存在する」という意味になり、定義の重複を防ぎます。

/* in config.h */
extern int g_verbose;   /* declaration */

/* in config.c */
int g_verbose = 0;      /* the single definition */

staticキーワード

ファイルスコープでstaticを指定すると、関数や変数がその翻訳単位に対して非公開になります。

staticなヘルパー関数は他のファイルからリンクできないため、名前の衝突を防ぎ、実装の詳細を隠せます。Cでは、内部用であることを示す方法です。

/* visible only inside this .c file */
static int helper(int x) {
    return x * 2;
}

One Definition Rule

非 static 関数やグローバル変数は、プログラム全体で正確に1回だけ定義できます。複数のファイルで宣言しても、定義するのは1つのファイルだけにします。

addを2回定義すると、multiple definition of 'add'のようなリンカーエラーが発生します。これが、ヘッダーファイルに本体を記述しない理由です。

クイックチェック

ヘッダーに何を記述すべきか考えてみましょう。

まとめ

これで、複数ファイルから成るプロジェクトを構成できるようになりました。

  • 各.cファイルは翻訳単位であり、それぞれ独立して.oファイルにコンパイルされます
  • ヘッダーには宣言を記述し、各定義は1つの.cファイルに記述します
  • リンカーがオブジェクトファイル間の呼び出しを解決します
  • externでグローバル変数を共有し、staticでファイルローカルのシンボルを非公開にします

次は、Makefileを使ってビルドを自動化します。

よくある質問

「複数ファイルのプロジェクト」レッスンは無料ですか?

はい。「複数ファイルのプロジェクト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C Academyコースには全4レッスンが含まれています。

「複数ファイルのプロジェクト」で何を学びますか?

ヘッダーと翻訳単位です。 ブラウザで直接実行するハンズオンコードでC Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「複数ファイルのプロジェクト」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC Academyレッスンでコードを書いて実行できますか?

はい。すべてのC Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 条件付きコンパイル
  2. 複数ファイルのプロジェクト
  3. Makefile
  4. 静的ライブラリと共有ライブラリ
← C Academyに戻る