6日でできる 新C言語入門|ソースコード分割の基本

長くなったプログラムは、役割ごとに分けると読みやすくなる。
ヘッダファイルとソースファイルを使って、C言語のコードを整理できるようになろう。

C言語でプログラムを作っていると、最初は1つのmain.cだけで十分に見えるかもしれません。短いサンプルなら、すべての処理を1つのファイルに書いても大きな問題はありません。

しかし、プログラムが少しずつ大きくなると、関数の数が増え、処理の内容も複雑になっていきます。main.cの中に入力処理、計算処理、表示処理、共通関数などをすべて書き続けると、どこに何があるのか分かりにくくなります。

そこで役立つのが、ソースコード分割です。

ソースコード分割とは、プログラムを機能ごとに複数のファイルへ分けて管理する方法です。C言語では、主にソースファイルとヘッダファイルを使って分割します。

ソースファイルは、関数の本体を書くファイルです。拡張子は.cです。
ヘッダファイルは、関数のプロトタイプ宣言や定数、型情報などをまとめるファイルです。拡張子は.hです。

たとえば、掛け算を行う関数を別ファイルに分けたい場合、main.c、multiply.h、multiply.cのようにファイルを分けます。main.cは全体の流れを担当し、multiply.cは掛け算処理の本体を担当し、multiply.hはその関数をほかのファイルから使うための宣言を担当します。

この記事では、Visual StudioでC言語のプロジェクトを作成し、ヘッダファイルとソースファイルを追加しながら、ソースコード分割の基本をやさしく解説していきます。

ソースコードを分割する理由

ソースコードを分割する目的は、プログラムを見やすく、修正しやすくすることです。

すべての処理を1つのmain.cに書くと、ファイルが長くなり、目的の関数を探すのに時間がかかります。さらに、複数人で開発する場合、同じファイルを何人も編集することになり、作業がぶつかりやすくなります。

ソースコードを分割すると、機能ごとにファイルを整理できます。

ファイル主な役割
main.cプログラム全体の流れを書く
multiply.h関数のプロトタイプ宣言を書く
multiply.c関数の本体を書く

このように分けると、main.cを見るだけでプログラムの大まかな流れが分かり、詳しい処理は別ファイルで確認できます。

ヘッダファイルとソースファイルの役割

C言語でソースコードを分割するときは、ヘッダファイルとソースファイルの役割を理解することが大切です。

ヘッダファイルには、他のファイルから使いたい情報を宣言します。たとえば、関数のプロトタイプ宣言、定数、構造体の定義などです。

ソースファイルには、実際の処理を書きます。関数が何をするのか、どのような計算をするのかといった本体部分を記述します。

種類拡張子書く内容
ヘッダファイル.h関数の宣言、定数、型情報など
ソースファイル.c関数の本体、具体的な処理
main.c.cプログラムの開始地点と全体の流れ

たとえば、multiply関数を別ファイルに分ける場合、multiply.hに関数の宣言を書き、multiply.cに関数の本体を書きます。

main.cではmultiply.hを読み込み、multiply関数を呼び出します。

図:ヘッダファイルとソースファイルの役割

この図から分かること

この図から分かるのは、ソースコード分割では、ファイルごとに役割を分けることが大切だということです。

main.cはプログラムの流れを担当します。multiply.hは関数を使うための宣言をまとめます。multiply.cは実際の関数本体を持ちます。このように分けることで、プログラムの構成が見やすくなります。

Visual Studioでプロジェクトを準備する

Visual StudioでC言語のプログラムを分割して作る場合、まずプロジェクトを作成します。

画面やメニュー名はVisual Studioのバージョンや設定によって少し異なる場合がありますが、基本的な流れは同じです。

新しいプロジェクトを作成する

Visual Studioを起動し、新しいプロジェクトの作成を選びます。

C言語として学習する場合は、空のプロジェクトを選ぶと、余計なファイルが少なく、学習しやすくなります。

プロジェクト名は、ここではMultiFileSampleとします。

項目内容
プロジェクトの種類空のプロジェクト
プロジェクト名MultiFileSample
使用する主なファイルmain.c、multiply.h、multiply.c

1.Visual Studio 2026を起動します。

2.「新しいプロジェクトの作成」を選択して「次へ」ボタンをクリックします。

3.「空のCプロジェクト」または「空のプロジェクト」を選択し、プロジェクト名(例:MultiFileSample)を入力して「作成」ボタンをクリックしてプロジェクトを開始します。

プロジェクトを作成したら、ソリューションエクスプローラーにソースファイルやヘッダーファイルの項目が表示されます。

main.cを追加する

ソリューションエクスプローラーでソースファイルを右クリックし、追加、新しい項目を選びます。

C++ファイルとして追加する画面が表示される場合でも、ファイル名をmain.cに変更すれば、C言語のソースファイルとして扱えます。

main.cは、プログラムの入口となるmain関数を書くファイルです。

1.ソリューションエクスプローラーで「ソースファイル」フォルダーを右クリックし、「追加」→「新しい項目」を選択します。

2.「FileName.cpp」を「main.c」に変更し「追加」をクリックします。

ヘッダファイルには宣言を書く

ヘッダファイルには、他のソースファイルから使いたい関数の情報を書きます。

今回の例では、multiply関数をmain.cから呼び出したいので、multiply.hにプロトタイプ宣言を書きます。

プロトタイプ宣言とは、関数の戻り値の型、関数名、引数の型をコンパイラへ知らせるための宣言です。

int multiply(int, int);

この宣言により、main.cはmultiply関数が存在することを知ることができます。

ヘッダファイルは、関数本体を書く場所ではありません。関数の本体はmultiply.cに書きます。

インクルードガードで多重読み込みを防ぐ

ヘッダファイルには、インクルードガードを書くのが基本です。

インクルードガードとは、同じヘッダファイルが複数回読み込まれても、内容が重複して展開されないようにする仕組みです。

たとえば、multiply.hでは次のように書きます。

#ifndef _MULTIPLY_H_
#define _MULTIPLY_H_

int multiply(int, int);

#endif

この書き方では、最初に_MULTIPLY_H_が定義されているかを確認します。まだ定義されていなければ、ヘッダファイルの中身を有効にし、同時に_MULTIPLY_H_を定義します。

次に同じヘッダファイルが読み込まれた場合は、すでに_MULTIPLY_H_が定義されているため、中身は再び展開されません。

記述役割
#ifndef MULTIPLY_Hまだ読み込まれていないか確認する
#define MULTIPLY_H読み込んだ印を付ける
int multiply(int, int);関数のプロトタイプ宣言
#endifインクルードガードの終わり

インクルードガードを入れておくことで、ヘッダファイルの多重読み込みによるエラーを防ぎやすくなります。

multiply.hを追加して記述する

Visual Studioでヘッダファイルを追加する場合は、ソリューションエクスプローラーのヘッダーファイルを右クリックし、追加、新しい項目を選びます。

ヘッダーファイルを選び、ファイル名をmultiply.hにします。

プロジェクト/ファイル名: MultiFileSample/multiply.h

#ifndef _MULTIPLY_H_    // インクルードガード(1行目)
#define _MULTIPLY_H_    // インクルードガード(2行目)

// ここにプロトタイプ宣言
int multiply(int, int); // 2つのint値を掛け算する関数

#endif // _MULTIPLY_H_  // インクルードガード(終了)

このファイルでは、multiply関数のプロトタイプ宣言だけを書いています。

int multiply(int, int);

これにより、main.cからmultiply関数を呼び出せるようになります。

図:ヘッダファイルは関数の情報を共有する

この図から分かること

この図から分かるのは、ヘッダファイルが複数のソースファイルに共通の情報を知らせる役割を持つということです。

main.cはmultiply関数を使うためにmultiply.hを読み込みます。multiply.cも同じヘッダファイルを読み込むことで、宣言と関数本体の対応を確認しやすくなります。

multiply.cには関数の本体を書く

次に、multiply関数の本体を書くソースファイルを追加します。

ソリューションエクスプローラーでソースファイルを右クリックし、追加、新しい項目を選びます。C++ファイルとして追加する画面が表示される場合でも、ファイル名をmultiply.cに変更します。

multiply.cでは、multiply.hを読み込み、multiply関数の本体を書きます。

プロジェクト/ファイル名: MultiFileSample/multiply.c

#include "multiply.h"

// 2つの整数を掛け算して結果を返す関数
int multiply(int a, int b) {
    return a * b;
}

このファイルでは、multiply関数の実際の処理を書いています。

return a * b;

multiply.cは関数の中身を担当するファイルです。main.cから直接この中身を見る必要はありません。main.cは、multiply.hを通じてmultiply関数の使い方を知り、関数を呼び出します。

main.cではヘッダファイルを読み込んで関数を使う

main.cでは、標準入出力用のstdio.hと、自分で作ったmultiply.hを読み込みます。

#include <stdio.h>
#include "multiply.h"

stdio.hは標準ライブラリのヘッダファイルなので、山かっこで読み込みます。

multiply.hは自分のプロジェクト内にあるヘッダファイルなので、ダブルクォーテーションで読み込みます。

書き方主な用途
#include <stdio.h>標準ライブラリのヘッダファイルを読み込む
#include "multiply.h"自作ヘッダファイルを読み込む

main.cでは、multiply関数を呼び出して計算結果を表示します。

プロジェクト/ファイル名: MultiFileSample/main.c

#include <stdio.h>
#include "multiply.h"

int main(void) {
    int width = 6;
    int height = 9;
    int area;

    // multiply関数を使って長方形の面積を計算する
    area = multiply(width, height);

    printf("幅 %d、高さ %d の長方形の面積は %d です。\n", width, height, area);

    return 0;
}

実行結果

幅 6、高さ 9 の長方形の面積は 54 です。

このプログラムでは、main.cの中でmultiply関数を呼び出しています。

area = multiply(width, height);

main.cにはmultiply関数の本体はありません。それでも関数を呼び出せるのは、multiply.hを読み込んでいるためです。

multiply.hにはmultiply関数のプロトタイプ宣言があり、multiply.cにはmultiply関数の本体があります。ビルド時には、main.cとmultiply.cがそれぞれコンパイルされ、最後にリンクされて1つの実行ファイルになります。

3つのファイルの関係を整理する

今回の構成では、3つのファイルが連携して1つのプログラムを作ります。

ファイル内容役割
main.cmain関数プログラム全体の流れ
multiply.hmultiply関数の宣言関数の使い方を知らせる
multiply.cmultiply関数の本体実際の計算処理

main.cはmultiply.hを読み込みます。multiply.hによって、main.cはmultiply関数の戻り値の型や引数の型を知ることができます。

multiply.cには関数の本体があるため、実際の計算処理はmultiply.cで行われます。

ビルドすると複数の.cファイルがまとめられる

Visual Studioでソリューションのビルドを実行すると、プロジェクト内のソースファイルがコンパイルされます。

今回であれば、main.cとmultiply.cがコンパイル対象になります。

その後、コンパイルされた結果がリンクされ、1つの実行ファイルになります。

手順内容
コンパイルmain.cやmultiply.cをそれぞれ機械語に近い形へ変換する
リンク複数のコンパイル結果をつなげて実行ファイルを作る
実行完成した実行ファイルを動かす

main.cだけを見てもmultiply関数の本体はありません。しかし、multiply.cも同じプロジェクトに含まれているため、リンク時に関数本体が結び付けられます。

図:複数のソースファイルはビルド時に1つの実行ファイルになる

この図から分かること

この図から分かるのは、複数に分けたソースファイルが、ビルド時にまとめられて1つの実行ファイルになるということです。

main.cとmultiply.cは別々のファイルですが、同じプロジェクトに含まれていれば、それぞれコンパイルされ、リンクによって結び付けられます。multiply.hは関数の宣言を共有する役割を持ち、main.cとmultiply.cの橋渡しをします。

Visual Studioでビルドする流れ

ファイルの作成が終わったら、ビルドしてプログラムが正しく作れるか確認します。

Visual Studioでは、メニューからビルドを選び、ソリューションのビルドを実行します。

ビルドが成功すると、main.cとmultiply.cがコンパイルされ、リンクされます。エラーがなければ、実行ファイルが作成されます。

ビルド時には、出力ウィンドウに次のような情報が表示されることがあります。

ビルド開始: プロジェクト: MultiFileSample
main.c
multiply.c
コードを生成中...
ビルド: 成功

ここでmain.cとmultiply.cの両方が表示されていれば、複数のソースファイルがビルド対象になっていることを確認できます。

実行して結果を確認する

ビルドが成功したら、デバッグなしで開始を選んで実行します。

今回のプログラムでは、次のような結果が表示されます。

幅 6、高さ 9 の長方形の面積は 54 です。

この結果から、main.cからmultiply関数が正しく呼び出され、multiply.cに書いた関数本体が実行されたことが分かります。

ソースコード分割で起こりやすいミス

ソースコードを分割するときは、いくつか注意したい点があります。

ヘッダファイルを読み込み忘れる

main.cでmultiply関数を使う場合、multiply.hを読み込む必要があります。

#include "multiply.h"

これを忘れると、multiply関数の宣言が分からず、エラーや警告の原因になります。

multiply.cをプロジェクトに追加していない

multiply.cを作成していても、プロジェクトに正しく追加されていないと、ビルド時に関数本体が見つからないことがあります。

main.cからmultiply関数を呼び出しているのに、multiply.cがビルド対象になっていない場合、リンクエラーになることがあります。

プロトタイプ宣言と関数本体が一致していない

multiply.hに書いた宣言と、multiply.cに書いた関数定義は一致している必要があります。

int multiply(int a, int b) {
    return a * b;
}

戻り値の型、関数名、引数の型が合っていないと、正しくビルドできない原因になります。

インクルードガードを書き忘れる

ヘッダファイルにはインクルードガードを書いておくと安全です。

#ifndef _MULTIPLY_H_
#define _MULTIPLY_H_

int multiply(int, int);

#endif

小さなプログラムではすぐに問題にならないこともありますが、ファイルが増えると多重読み込みが起こりやすくなります。

ヘッダファイルに書くものと書かないもの

ヘッダファイルには、他のファイルから共有したい宣言を書きます。

ヘッダファイルに書くもの
関数のプロトタイプ宣言int multiply(int, int);
定数の定義#define MAX_VALUE 100
構造体の定義typedef structで作る型情報
インクルードガード#ifndef、#define、#endif

一方、通常は関数の本体をヘッダファイルに書きません。関数本体は.cファイルに書きます。

書く場所内容
.hファイル宣言、定数、型情報
.cファイル関数の本体、具体的な処理

この分け方を守ると、ファイルの役割が分かりやすくなります。

ソースコード分割で意識したい考え方

ソースコード分割では、ただファイルを増やせばよいわけではありません。大切なのは、役割ごとに分けることです。

たとえば、計算関数、表示関数、入力関数など、機能単位でファイルを分けると管理しやすくなります。

今回の例では、multiply関数を別ファイルに分けました。

処理担当ファイル
プログラム全体の流れmain.c
multiply関数の宣言multiply.h
multiply関数の処理multiply.c

このように分けることで、main.cの中身を短く保ちながら、計算処理を別ファイルで管理できます。

ソースコード分割を使うと保守しやすくなる

ソースコード分割は、プログラムが大きくなったときにとても役立ちます。

1つのファイルにすべての処理を書くと、関数が増えるほど読みづらくなります。どこに何が書かれているのか分かりにくくなり、修正も大変になります。

ヘッダファイルとソースファイルを使って役割を分けると、プログラムを機能ごとに整理できます。

main.cには全体の流れを書き、multiply.hには関数の宣言を書き、multiply.cには関数本体を書きます。この構成を理解できると、C言語のプログラムをより実践的に整理できるようになります。

Visual Studioでは、ソリューションエクスプローラーからソースファイルやヘッダファイルを追加し、ビルドによって複数のファイルを1つのプログラムとしてまとめられます。

ソースコード分割に慣れると、関数の再利用、保守性の向上、チーム開発への対応がしやすくなります。小さなプログラムでも、ファイルごとの役割を意識しておくと、より分かりやすいC言語プログラムを書けるようになります。