
C言語GUI入門|C言語プログラムが動くまで
C言語で書いたソースファイルは、そのままではWindows上で実行できません。GCCによってコンピューターが理解できる形式へ変換され、必要なライブラリと結び付けられることで、exe形式の実行ファイルになります。
この記事では、次の内容を解説します。
- ソースファイルとは
- コンパイルとは
- リンクとは
- 実行ファイルとは
- exeファイルが作られる流れ
全体の流れは次のようになります。
ソースファイル
↓
前処理
↓
コンパイル
↓
アセンブル
↓
オブジェクトファイル
↓
リンク
↓
exe形式の実行ファイルここでは、まだプログラムの作成やコンパイルは行いません。まずは、ソースファイルがどのような仕組みでexeファイルになるのか、全体像をつかんでいきましょう。
C言語のプログラムは変換してから実行する
C言語は、人が読み書きしやすい形式でプログラムを記述するためのプログラミング言語です。
C言語で記述した内容を読めば、関数を呼び出していることや、計算していること、条件によって処理を分けていることなどを理解できます。
しかし、コンピューターのCPUは、C言語で書かれた内容をそのまま実行するわけではありません。CPUが直接実行するのは、機械語と呼ばれる命令です。
そのため、C言語のプログラムを動かすには、次のような変換が必要です。
人が理解しやすいC言語
↓
コンピューターが実行できる機械語この変換を担当する代表的な開発ツールがGCCです。
GCCはソースファイルを読み取り、文法や型を確認しながら、最終的にWindowsで実行できるexeファイルを作ります。
| 種類 | 主に利用するもの |
|---|---|
| C言語のソースコード | プログラマー |
| 機械語 | CPU |
| GCC | ソースコードを機械語へ変換する |
| Windows | 完成した実行ファイルを読み込んで起動する |
図1:C言語から実行ファイルへの変換

この図から分かること
プログラマーが作成するのは、C言語で記述されたソースファイルです。しかし、CPUはソースファイルを直接実行できません。
GCCがソースファイルを変換することで、Windows上で実行できるexeファイルが作られます。ソースファイルと実行ファイルは、内容も役割も異なるファイルです。
ソースファイルとは
ソースファイルとは、プログラマーが作成したソースコードを保存するテキストファイルです。
C言語のソースファイルには、一般的に.cという拡張子を付けます。
ファイル名.cたとえば、hello.cという名前で保存した場合、helloがファイル名、.cが拡張子です。
| 部分 | 内容 |
|---|---|
| hello | ファイル名 |
| .c | C言語のソースファイルを表す拡張子 |
| hello.c | 完全なファイル名 |
ソースファイルには、C言語を使って次のような内容を記述します。
- プログラムの開始位置
- 変数や定数
- 計算処理
- 条件分岐
- 繰り返し処理
- 関数の定義や呼び出し
- 画面への表示
- キーボードからの入力
- プログラマー向けのコメント
ソースファイルは通常のテキストファイルなので、Visual Studio Codeなどのテキストエディターで作成、表示、編集できます。
ソースファイルは設計図に近いもの
ソースファイルは、建物を作るときの設計図にたとえられます。
設計図には、どのような部屋を作るか、どこに柱を置くかなどが記載されています。しかし、設計図そのものを建物として利用することはできません。
C言語のソースファイルも同じです。どのような処理を行うかが記述されていますが、そのままではコンピューター上で実行できません。
建物の設計図
↓
設計図をもとに建築
↓
完成した建物C言語では、次のように対応します。
ソースファイル
↓
GCCによる変換
↓
完成した実行ファイルこのように考えると、ソースファイルと実行ファイルの違いを理解しやすくなります。
ソースファイルと実行ファイルの違い
| 項目 | ソースファイル | 実行ファイル |
|---|---|---|
| 主な拡張子 | .c | .exe |
| 主な内容 | C言語のソースコード | CPUが実行する機械語など |
| 主に作成するもの | プログラマー | GCCやリンカー |
| 編集方法 | Visual Studio Codeなどで編集する | 通常は直接編集しない |
| 人が読む | 比較的読みやすい | そのままでは読みにくい |
| Windowsでの実行 | そのままでは実行できない | 実行できる |
| 変更方法 | ソースコードを書き換える | ソースを書き換えて作り直す |
ソースファイルを変更しても、すでに作成されている実行ファイルの内容は自動的には変わりません。
変更した内容を実行ファイルへ反映するには、ソースファイルからexeファイルをもう一度作り直す必要があります。
コンパイルとは
コンパイルとは、C言語で書かれたソースコードを、コンピューターが処理できる形式へ変換する作業です。
コンパイルを担当するプログラムをコンパイラーと呼びます。本コンテンツでは、コンパイラーとしてGCCを使用します。
コンパイラーは、単純に文字を機械語へ置き換えているだけではありません。ソースコードを詳しく解析しながら、次のような点も確認します。
- C言語の文法が正しいか
- 変数が正しく宣言されているか
- 関数の呼び出し方が正しいか
- データ型の使い方に問題がないか
- 閉じ波かっこやセミコロンが不足していないか
- 指定されたC言語規格に合っているか
- 警告の対象になる記述がないか
問題が見つかった場合は、エラーや警告が表示されます。
コンパイルエラーとは
C言語の文法などに問題があり、コンパイラーが処理を続けられない場合に発生するのがコンパイルエラーです。
主な原因には、次のようなものがあります。
- セミコロンを付け忘れている
- 波かっこの対応が間違っている
- 変数名を間違えている
- 宣言していない関数や変数を使用している
- データ型の使い方が正しくない
- C言語として解釈できない文字がある
コンパイルエラーが発生した場合、exeファイルは完成しません。
ソースファイル
↓
コンパイルエラー
↓
変換を中止
↓
exeファイルは作られないエラーを修正した後、あらためてコンパイルする必要があります。
エラーと警告の違い
コンパイラーが表示するメッセージには、主にエラーと警告があります。
| 種類 | 意味 | exeファイル |
|---|---|---|
| エラー | 処理を続けられない問題 | 通常は作られない |
| 警告 | 間違いの可能性がある問題 | 作られる場合がある |
| メッセージなし | 問題が検出されなかった | 作られる |
警告が表示されてもexeファイルが作られることがあります。しかし、警告は無視してよいという意味ではありません。
現在は動いているように見えても、入力内容や実行環境によって問題が起きる可能性があります。警告も内容を確認し、できるだけ解消することが大切です。
コンパイルという言葉には2つの使い方がある
コンパイルという言葉は、説明する場面によって少し違う意味で使われます。
| 使い方 | 意味 |
|---|---|
| 狭い意味 | C言語のソースコードをアセンブリ言語へ変換する処理 |
| 広い意味 | ソースファイルから実行ファイルを作る処理全体 |
初心者向けの説明では、前処理、コンパイル、アセンブル、リンクをまとめてコンパイルと呼ぶことがよくあります。
一方、処理の内部を詳しく見る場合は、コンパイルとリンクを別の段階として扱います。
この記事では、個々の処理を説明するときは、コンパイルとリンクを分けて考えます。
前処理とは
C言語のソースファイルは、本格的にコンパイルされる前に前処理が行われます。
前処理を担当する仕組みをプリプロセッサと呼びます。
前処理では、主に次の作業が行われます。
- ヘッダファイルに書かれた宣言を利用できるようにする
- マクロを展開する
- 条件付きコンパイルの対象を選ぶ
- コメントを取り除く
- コンパイラーが処理しやすい形へ整える
前処理が終わった内容は、コンパイラーへ渡されます。
ソースファイル
↓
プリプロセッサ
↓
前処理済みのソース
↓
コンパイラー通常はGCCが前処理も自動的に行うため、プログラマーが毎回個別に操作する必要はありません。
アセンブルとは
狭い意味でのコンパイルによって、C言語のソースコードはアセンブリ言語へ変換されます。
アセンブリ言語は、C言語よりもCPUの命令に近い形式です。しかし、まだCPUが直接実行する最終的な機械語ではありません。
そこで、アセンブラーがアセンブリ言語を機械語へ変換します。この処理をアセンブルと呼びます。
C言語
↓ コンパイル
アセンブリ言語
↓ アセンブル
機械語アセンブルによって、オブジェクトファイルと呼ばれるファイルが作られます。
オブジェクトファイルとは
オブジェクトファイルは、ソースファイルを機械語へ変換した中間ファイルです。
MSYS2のGCCでは、一般的に.oという拡張子が使われます。
ファイル名.oオブジェクトファイルには機械語が含まれていますが、通常はそのまま実行できません。実行ファイルを構成する部品のひとつだからです。
たとえば、プログラムが複数のソースファイルに分かれている場合、それぞれから別のオブジェクトファイルが作られます。
ソースファイルA.c → オブジェクトファイルA.o
ソースファイルB.c → オブジェクトファイルB.o
ソースファイルC.c → オブジェクトファイルC.o最後に、これらのオブジェクトファイルを結び付け、ひとつの実行ファイルを作ります。
図2:コンパイルとリンクの違い

この図から分かること
コンパイルは、ソースファイルを機械語の部品であるオブジェクトファイルへ変換する処理です。
リンクは、作成されたオブジェクトファイルと必要なライブラリを結び付け、ひとつの実行ファイルを完成させる処理です。
コンパイルとリンクは、どちらもexeファイルを作るために必要ですが、担当する役割が異なります。
リンクとは
リンクとは、オブジェクトファイルと必要なライブラリを結び付け、実行ファイルを作る処理です。
リンクを担当するプログラムをリンカーと呼びます。
リンクでは、主に次のものが結び付けられます。
- 自分のプログラムから作られたオブジェクトファイル
- ほかのソースファイルから作られたオブジェクトファイル
- Cの標準ライブラリ
- プログラムの開始や終了に必要な処理
- 外部ライブラリ
- Windowsの機能を利用するための情報
部品がひとつだけの小さなプログラムでも、Cの標準ライブラリやプログラム開始時の処理などが必要になります。
ライブラリとは
ライブラリとは、よく使われる機能をまとめたプログラムの部品です。
C言語には、文字の表示、文字列の処理、数学計算、メモリ管理などに利用できる標準ライブラリがあります。
ライブラリを利用すると、すべての処理を最初から自分で作る必要がありません。
自分で作成した処理
+
ライブラリが提供する処理
↓
完成した実行ファイル第4章以降で使用するGTK 4も、GUIアプリケーションを作成するためのライブラリです。
GTK 4のプログラムでは、自分のオブジェクトファイルとGTK 4のライブラリをリンクして、GUIアプリケーションのexeファイルを作ります。
ヘッダファイルとライブラリの違い
ヘッダファイルとライブラリは、同じものではありません。
| 種類 | 主な役割 |
|---|---|
| ヘッダファイル | 関数やデータ型の宣言をコンパイラーへ伝える |
| ライブラリ | 関数の実際の処理を提供する |
| オブジェクトファイル | 自分のソースコードを機械語へ変換した部品 |
| リンカー | オブジェクトファイルとライブラリを結び付ける |
コンパイラーはヘッダファイルの宣言を使って、関数の呼び出し方が正しいか確認します。
リンカーは、ライブラリの中から必要な関数の実体を探し、オブジェクトファイルと結び付けます。
リンクエラーとは
コンパイルに成功しても、リンクに失敗する場合があります。これがリンクエラーです。
リンクエラーの主な原因には、次のようなものがあります。
- 呼び出している関数の実体が見つからない
- 必要なオブジェクトファイルが指定されていない
- 必要なライブラリが見つからない
- ライブラリの指定が不足している
- 関数名が定義と呼び出しで一致していない
- 異なる環境向けのライブラリが混在している
コンパイルエラーとリンクエラーの違いは、次のように考えられます。
コンパイルエラー
C言語の内容を機械語の部品へ変換できない
リンクエラー
機械語の部品は作れたが、必要な部品を結合できないリンクエラーが発生した場合も、完成したexeファイルは作られません。
コンパイルとリンクを料理にたとえる
コンパイルとリンクは、料理の手順にたとえると理解しやすくなります。
コンパイルは、材料ごとに下ごしらえをする作業です。
野菜を切る
肉に下味を付ける
調味料を用意するリンクは、準備した材料を組み合わせてひとつの料理を完成させる作業です。
下ごしらえした材料
+
調味料
↓
完成した料理C言語では次のように対応します。
| 料理 | C言語 |
|---|---|
| 材料 | ソースファイル |
| 下ごしらえ | コンパイル |
| 下ごしらえ済みの材料 | オブジェクトファイル |
| 調味料や共通材料 | ライブラリ |
| 材料を組み合わせる | リンク |
| 完成した料理 | 実行ファイル |
オブジェクトファイルは重要な部品ですが、それだけでは完成品ではありません。必要な部品とライブラリをリンクして、初めて実行ファイルになります。
実行ファイルとは
実行ファイルとは、OSがプログラムとして読み込み、CPUに処理させることができるファイルです。
Windowsでは、一般的に.exeという拡張子が使われます。
ファイル名.exeexeはexecutableを短くした表記です。executableには、実行できるという意味があります。
実行ファイルには、主に次の内容が含まれます。
- CPUが実行する機械語
- プログラムで使用するデータ
- プログラムの開始位置
- 必要なDLLの情報
- Windowsがファイルを読み込むための管理情報
- メモリ上へ配置するときに必要な情報
ソースファイルとは異なり、実行ファイルの内容は人が直接読み書きするためのものではありません。
exeファイルはWindows向けの実行ファイル
exeファイルは、Windowsで使用される代表的な実行ファイルです。
ファイル名の例は次のようになります。
hello.exe
calculator.exe
tic_tac_toe.exeファイル名を見れば、それぞれ別のプログラムであることが分かります。
ただし、exeファイルであれば、どのコンピューターでも必ず動作するわけではありません。
実行するためには、次のような条件が関係します。
- 対応するWindowsの種類
- CPUの種類
- 32ビットと64ビットの違い
- 必要なDLLが存在するか
- 使用しているライブラリが利用できるか
- ファイルを実行する権限があるか
GTK 4を使用するGUIアプリケーションでは、exeファイルのほかにGTK 4が使用するDLLなども必要になります。配布に必要なファイルについては、第7章で詳しく扱います。
exeファイルは直接編集しない
プログラムの表示内容や処理を変更したい場合、通常はexeファイルを直接編集しません。
元のソースファイルを編集し、もう一度コンパイルとリンクを行います。
ソースファイルを編集
↓
コンパイル
↓
リンク
↓
新しいexeファイルこのため、プログラムを開発するときは、exeファイルだけでなくソースファイルも大切に管理する必要があります。
exeファイルが作られる流れ
ソースファイルからexeファイルが作られるまでを、もう一度詳しく整理します。
1. ソースファイルを読み込む
↓
2. 前処理を行う
↓
3. C言語をアセンブリ言語へ変換する
↓
4. アセンブリ言語を機械語へ変換する
↓
5. オブジェクトファイルを作る
↓
6. ライブラリやほかの部品とリンクする
↓
7. exe形式の実行ファイルを作る各段階の役割は次のとおりです。
| 段階 | 処理 | 作られるもの |
|---|---|---|
| 1 | ソースファイルを読み込む | C言語の内容を取得 |
| 2 | 前処理を行う | 前処理済みのソース |
| 3 | コンパイルする | アセンブリ言語 |
| 4 | アセンブルする | 機械語 |
| 5 | 機械語をファイルに保存する | オブジェクトファイル |
| 6 | 部品とライブラリを結合する | 実行に必要な内容を統合 |
| 7 | Windows向けにまとめる | exeファイル |
通常は、GCCがこれらの処理を順番に進めます。そのため、利用者からはひとつのまとまった処理に見えます。
処理の途中で作られるファイル
処理の内部では、複数の形式が使われます。
| 拡張子 | ファイルの種類 | 主な内容 |
|---|---|---|
| .c | ソースファイル | プログラマーが記述したC言語 |
| .i | 前処理済みファイル | 前処理が終わったソース |
| .s | アセンブリファイル | アセンブリ言語 |
| .o | オブジェクトファイル | 機械語に変換された部品 |
| .exe | 実行ファイル | Windowsで実行できる完成ファイル |
通常のコンパイルでは、.i、.s、.oなどの中間ファイルを意識しなくても、最終的なexeファイルを作れます。
しかし、この流れを知っておくと、コンパイルとリンクが別の処理であることや、エラーが発生する段階の違いを理解しやすくなります。
図3:exeファイルが完成する7段階

この図から分かること
exeファイルは、ソースファイルから一度に姿を変えるわけではありません。前処理、コンパイル、アセンブル、リンクという複数の段階を通って作られます。
途中で文法エラーが見つかったり、必要なライブラリが見つからなかったりすると、処理は完了せず、exeファイルも作られません。
どの段階で問題が起きたかを確認することが、エラーを解決するための重要な手がかりになります。
exeファイルが実行されるときの流れ
完成したexeファイルを起動すると、Windowsがファイルの内容を確認してメモリへ読み込みます。
おおまかな流れは次のとおりです。
exeファイルを起動する
↓
Windowsがファイルを読み込む
↓
必要なDLLを確認する
↓
プログラム用のメモリを準備する
↓
プログラムの処理を開始する
↓
CPUが機械語を順番に実行する
↓
プログラムを終了するソースファイルが実行されているのではなく、ソースファイルから作られたexeファイルが実行されています。
DLLと実行ファイルの関係
DLLは、Dynamic Link Libraryを短くした名前です。複数のプログラムから利用できる機能をまとめたファイルです。
実行ファイルが必要とする機能の一部は、exeファイルの外にあるDLLから提供される場合があります。
実行ファイル
+
必要なDLL
↓
プログラムを実行必要なDLLが見つからない場合、exeファイルが存在していてもプログラムを起動できません。
通常の小さなコンソールプログラムでは意識する場面が少ないかもしれませんが、GTK 4を使用するGUIアプリケーションでは、多くのGTK関連DLLが必要になります。
コンソールプログラムとGTK 4プログラムの流れ
通常のコンソールプログラムとGTK 4を使うGUIプログラムは、基本的に同じ流れでexeファイルになります。
ソースファイル
↓
コンパイル
↓
リンク
↓
exeファイル異なるのは、リンクするときに必要になるライブラリです。
| 種類 | 主にリンクするもの |
|---|---|
| 通常のコンソールプログラム | Cの標準ライブラリなど |
| GTK 4プログラム | Cの標準ライブラリ、GTK 4と関連ライブラリ |
GTK 4プログラムでは、ウィンドウ、ボタン、入力欄などの機能をGTK 4のライブラリから利用します。
そのため、GTK 4のヘッダファイルとライブラリをGCCが見つけられるようにする必要があります。この情報を取得するために、第4章ではpkg-configを使用します。
各用語の関係
| 用語 | 意味 |
|---|---|
| ソースファイル | C言語のソースコードを保存したファイル |
| コンパイラー | ソースコードを解析して変換するプログラム |
| コンパイル | C言語を機械語に近い形式へ変換する処理 |
| アセンブラー | アセンブリ言語を機械語へ変換するプログラム |
| アセンブル | アセンブリ言語を機械語へ変換する処理 |
| オブジェクトファイル | 機械語に変換された未完成の部品 |
| ライブラリ | 再利用できる機能をまとめた部品 |
| リンカー | オブジェクトファイルとライブラリを結合するプログラム |
| リンク | 必要な部品を結び付ける処理 |
| 実行ファイル | OSがプログラムとして実行できるファイル |
| exeファイル | Windowsで使われる代表的な実行ファイル |
次の記事へ進む前に確認すること
次の内容を確認できたら、C言語プログラムが動くまでの全体像を理解できています。
- ソースファイルはC言語のソースコードを保存したテキストファイル
- C言語のソースファイルには.cという拡張子を付ける
- CPUはC言語のソースファイルを直接実行しない
- GCCがソースコードをコンピューター向けの形式へ変換する
- コンパイルではソースコードの文法や型も確認される
- アセンブルによって機械語のオブジェクトファイルが作られる
- オブジェクトファイルは実行ファイルを構成する部品
- リンクではオブジェクトファイルとライブラリが結び付けられる
- Windowsの実行ファイルには.exeという拡張子が使われる
- ソースファイルを変更した場合はexeファイルを作り直す必要がある
- GTK 4プログラムでもコンパイルとリンクという基本的な流れは同じ
次の記事から、chap03ディレクトリを使って実際のファイルを準備し、C言語プログラムの作成へ進みます。
