日本語ブログ

Cの面接対策|コンパイラとインタプリタの違い

2026年5月10日3 分で読める
Cの面接対策|コンパイラとインタプリタの違い

Cはコンパイル言語かを面接で聞かれたら、compile-link-runの流れで答えるのが正解。オブジェクトファイルやリンカまで整理して解説します。

面接官があなたを見て、こう尋ねます。「C はコンパイル言語ですか、それともインタプリタ言語ですか?」 簡単な質問ですし、答えも知っているはずです。ですが、いざ口を開くと、出てくるのは中身のない一語のラベルか、教科書の定義をそのまま並べただけの説明になってしまいがちです。C の面接でコンパイラ対インタプリタを問われたときの本当の難しさは、定義そのものではありません。定義は、実は入口にすぎないのです。その先にあるのは compile-link-run のパイプラインで、多くの候補者はそこを実際には通っていません。

人が固まるのは、C がコンパイルされる言語だと知らないからではなく、ラベルだけを学んでロジックを学んでいないからです。面接官が「では、compiled とは具体的にどういう意味ですか?」とか「.o ファイルの中には何がありますか?」と続けると、暗記した答えはすぐに尽きてしまいます。このガイドは、そのギャップを埋めるためのものです。まずは明快な一文で答え、そのうえで、メモを見なくても説明できるだけの裏付けを身につけましょう。

賢そうに聞こえようとする前に、答えを一文で言えるようにする

面接官が本当に求めている、1分で言える答え

C はコンパイル言語です。ソースコードは実行前に機械語へ変換され、その流れはプリプロセス、コンパイル、アセンブル、リンクを経て、最後に OS のローダーが結果を実行します。これが答えです。「C はコンパイラが変換するからコンパイル言語です」という循環的な説明でも、言語理論を 3 段落で語る説明でもありません。パイプラインを名指しした、すっきりした一文で十分です。

この言い方が有効なのは、単なる分類ではなく プロセス を理解していることが伝わるからです。大学の採用面接や新卒エンジニア向けの面接でこの質問をする人は、たいてい「compiled という単語を知っているか」を試しているわけではありません。C のプログラムが実際にどうやって CPU に届くのか、その単語が何を意味するのかを理解しているかを見ています。

なぜ短い答えは、フォローアップが来た瞬間に崩れるのか

失敗のパターンは決まっています。候補者が自信満々に「C はコンパイルされます」と答えると、面接官はうなずいて「いいですね。ではコンパイラは何を生成しますか?」と聞きます。そこで候補者が「……実行ファイルですか?」と答えてしまう。完全に間違いではありませんが、オブジェクトファイルを飛ばし、リンカを飛ばし、暗記した分類名しか覚えていなかったことが露呈します。

今の検索結果では、このギャップが十分に埋まっていません。コンパイラ対インタプリタを一般論として説明する記事は山ほどあります。足りないのは、C に特化して、定義を実際のツールチェーンに対応づけた説明です。コンパイラが実行ファイルではなくオブジェクトファイルを生成し、リンカが 1 つ以上のオブジェクトファイルをバイナリに変換することを理解できれば、フォローアップ質問は罠ではなくなります。

実際の受け答えはこんな感じです

強い候補者なら、最初のやり取りをこうさばけます。

面接官: C はコンパイル言語ですか、それともインタプリタ言語ですか?

候補者: C はコンパイル言語です。ソースファイルはまずプリプロセスされ、その後コンパイラがアセンブリに変換し、アセンブラがそれをオブジェクトファイルにし、リンカが複数のオブジェクトファイルをまとめて実行ファイルを生成します。実行時にはローダーがメモリに配置し、CPU がネイティブの機械語をそのまま実行します。

面接官: では、.o ファイルの中には何が入っていますか?

候補者: その翻訳単位内の関数に対応する機械語と、ほかのファイルで定義された関数や変数への参照を解決するためにリンカが使うシンボルテーブルです。

この 2 つ目の答えが、パイプラインを理解している人と、ラベルだけ覚えた人を分けます。1 つ目の答えは練習すればすぐ言えます。2 つ目は、各ステップが何を出力するのかを本当に考えたことがある場合にしか出てきません。

hello.c から実行中のプログラムまでを順にたどる

ちゃんと説明されないビルドパイプライン

C プログラムがどうビルドされるかの混乱は、ほとんどの場合、各ステップそのものではなく、ステップ間の 受け渡し にあります。学生は「コンパイラがコンパイルする」「リンカがリンクする」と習いますが、何がどこからどこへ渡されるのか、そもそもなぜ分かれているのかまでは誰も説明してくれません。

全体の流れはこうです。プリプロセッサがマクロと `#include` ディレクティブを展開し、1 つの展開済み `.c` ファイルを作ります。コンパイラはそれを受け取り、アセンブリコードを生成します。アセンブラはそのアセンブリからオブジェクトファイル、つまり `.o` ファイルを作ります。そこには機械語が含まれていますが、ほかのファイルで定義されたシンボルを参照している可能性があるため、まだそのままでは実行できません。リンカは 1 つ以上の `.o` ファイルを受け取り、それらの相互参照を解決して最終的な実行ファイルを生成します。ローダーは OS の一部で、実行ファイルをメモリに読み込み、実行を開始します。5 つの異なる役割。5 つの異なる出力です。

実際の hello.c では何が起きるのか

典型例を見てみましょう。`printf` を呼ぶ `main()` を持つ `hello.c` を書いたとします。`gcc hello.c -o hello` を実行すると、GCC は 5 つの段階を自動で実行します。ですが、それぞれを分解すると、受け渡しの様子が見えます。

3 つ目のコマンドの後で `hello.o` が生成されます。中には `main` 関数の機械語が入っていますが、まだ実行できません。そこにある `printf` 呼び出しは未解決シンボルです。4 つ目のステップでリンカがやる仕事は、C 標準ライブラリから `printf` を見つけて参照を結びつけ、OS が読み込めるバイナリを作ることです。

実際にはどう見えるのか

ターミナルで `file hello.o` を実行すると、`ELF 64-bit relocatable` のような結果が返ります。`relocatable` なのは、まだアドレスが確定していないからです。一方、`file hello` では `ELF 64-bit executable` と出ます。この `relocatable` と `executable` の 1 語の違いこそ、リンカが何をしているかの本質です。面接官が「リンカは具体的に何を変えるのですか?」と聞いたら、答えはこれです。シンボルを解決し、アドレスを固定して、既知の位置にメモリへロードできるようにするのです。

各ステージの詳細については、GCC のドキュメント を一度読んでおく価値があります。中間ファイルの正式名称を確認できます。

コンパイラ、アセンブラ、リンカ、ローダーを混同しない

それぞれが 1 つの仕事だけを担う、それがポイントです

ツールチェーンは意図的にモジュール化されています。面接でここを突かれるのは、ツールの出力だけ覚えてアーキテクチャを理解していない人を見分けやすいからです。コンパイラの役割は変換です。C の高水準コードを低水準のアセンブリへ変換します。アセンブラの役割は符号化です。アセンブリのニーモニックをバイナリの機械命令へ変換します。リンカの役割は解決です。オブジェクトファイルをまとめ、シンボル参照を解決します。ローダーの役割は配置です。実行ファイルをディスクから読み込み、プロセスの仮想アドレス空間にマップします。

これらのツールが、ほかのツールの仕事までやることはありません。コンパイラは他のオブジェクトファイルのことを知りません。リンカは C を解析しません。ローダーはシンボルを解決しません。ローダーが動くころには、シンボルはすでに解決済みです。回答でこの役割分担をきちんと分けて話せると、「実際にソフトウェアを作ったことがある人」のように聞こえます。章の要約を読んだだけの人にはなりません。

オブジェクトファイルと実行ファイルは同じではない

オブジェクトファイルと実行ファイルは、どちらも機械語を含んでいます。そこが混乱の原因です。違いは、オブジェクトファイルが モジュール だという点です。1 つのソースファイルをコンパイルした結果で、ほかの場所で定義されたものへの参照はプレースホルダーのまま残っています。実行ファイルは 完成したプログラム です。すべての参照が解決され、すべてのアドレスが割り当てられ、OS はどこから実行を始めればよいかを正確に知っています。

こう考えてみてください。`.o` ファイルは、「7 章を参照」と脚注が付いた本の 1 章です。実行ファイルは、その脚注がすべて本文中に解決済みで入った製本済みの本です。最後の仕上げをするのがリンカです。

実際にはどう見えるのか

実際のオブジェクトファイルで `nm hello.o` を実行すると、シンボルテーブルが見えます。`main` は定義済み (`T`、text section) として、`printf` は未定義 (`U`) として表示されるはずです。リンク後に `nm hello` を見ると、`printf` は C ライブラリ内のアドレスに解決されています。`U` から実アドレスへの移行こそが、リンカの仕事のすべてです。これは 2 つのコマンドで確認できます。ローダーは完成したバイナリを受け取り、それらのアドレスを仮想メモリにマップし、スタックを整え、エントリポイントへジャンプします。

これらのツールの相互作用を詳しく知りたいなら、Bryant と O'Hallaron の Computer Systems: A Programmer's Perspective が、リンカとローダーを学部向け資料の中でも特に深く扱っています。

速度の質問には、神話に寄り道せず答える

コンパイルされたコードが速いことが多い理由

理由は神秘的ではなく、構造的なものです。C のようなコンパイル言語では、ソースから機械語への変換はプログラムが実行される前にすべて終わっています。ユーザーがバイナリを起動する時点では、CPU はネイティブ命令を直接読んでいます。変換レイヤーによるオーバーヘッドも、解釈の負荷も、バックグラウンドで動く JIT コンパイルもありません。作業はビルド時に完了しているのです。

一方、インタプリタ言語では、インタプリタが実行時にソースやバイトコードを読み、その場で機械操作へ変換します。その変換コストはプログラムを実行するたびに支払うことになり、しかもそれは実行中に発生します。速度を最優先にしたいなら、余計な仕事をするには最悪のタイミングです。

見落とされがちなトレードオフ: 速さと便利さは同じではない

インタプリタ側にも、公平に見ておくべき利点があります。インタプリタ言語は開発サイクルが短く、移植性が高く、コンパイル言語では大きな実装コストがかかるような実行時の柔軟性を持っています。Python が実行時に任意のコードを `eval` できること、JavaScript がどのブラウザでも同じソースを動かせることは、実際に価値のある機能であり、インタプリタ型モデルから直接生まれるものです。

ただし、C の面接でコンパイル言語とインタプリタ言語を比較する文脈では、利便性よりも性能差のほうが重要です。C が OS や組み込みファームウェア、性能が重要なライブラリで使われるのは、実行時の翻訳レイヤーがないことで動作が予測しやすく、速いからです。これは神話ではありません。マイクロ秒単位が重要な場面で、今なお C が選ばれる理由です。

実際にはどう見えるのか

単純な比較をしましょう。C のプログラムが 10 億個の整数をタイトなループで合計すると、現代のハードウェアでは通常 1 秒未満で終わります。同等の Python プログラムは、NumPy の C バックエンド配列を使わない限り、インタプリタのバージョンにもよりますが 30〜100 倍ほど時間がかかります。違いはアルゴリズムではありません。Python のインタプリタがループの反復ごとに仕事をしている一方、コンパイル済みの C バイナリはその仕事をビルド時に終えているからです。Python のドキュメント 自体が CPython をインタプリタとして説明しています。したがって、この比較はソースに基づいて妥当です。

「でも C もインタプリタで動かせますよね?」という罠をうまくさばく

教科書的なラベルが、それでも面接で正しい答えである理由

はい、C のインタプリタは存在します。CINT、Ch、そしていくつかのソース・ツー・ソース型ツールは、従来のコンパイル手順なしで C コードを実行できます。これは秘密ではありませんし、面接官がそれを知っていたら、あなたがパニックになるか、それとも筋道立てて考えるかを試している可能性があります。正しい反応は、「C のインタプリタなんて存在しない」と言い張ることではありません。なぜそれでも C がコンパイル言語に分類されるのかを説明することです。

その分類は、標準的で、定義上の、実運用のワークフローに基づいています。GCC、Clang、MSVC といった主要な C 実装はすべて機械語へコンパイルします。言語仕様そのものも、コンパイルを前提とした書き方になっています。未定義動作、翻訳単位、リンケージといった概念は、コンパイルモデルでしか意味を持ちません。C のインタプリタは、学術的な興味の対象かデバッグ用ツールであって、定義的な本番ケースではありません。

面接で本当に重要な違い

コンパイル言語かインタプリタ言語かを問う面接官は、「C を理論上インタプリタで解釈できるか」を聞いているわけではありません。通常のツールチェーンを理解していて、C がなぜその分類なのかを説明できるかを見ています。例外について意味論の議論に勝つことが目的ではありません。一般的なケースを理解し、例外と区別できることを示すのが目的です。

実用的な言い方をすると、言語がコンパイル言語かインタプリタ言語かは、研究環境で 可能か ではなく、本番で 通常どう実行されるか で決まります。Java が「コンパイル後にインタプリタされる」あるいは「JIT コンパイルされる」と呼ばれるのは、JVM モデルが標準の展開形だからです。C がコンパイル言語と呼ばれるのは、GCC と Clang が標準の展開形だからです。例外の存在は分類を変えません。

実際にはどう見えるのか

面接官: では、C は常にコンパイルされるのですか?

候補者: 実務上はそうです。標準的な本番向けツールチェーンはすべて、C を機械語へコンパイルします。C のインタプリタもありますが、通常の使い方ではありません。言語は翻訳単位やリンケージといったコンパイルを前提とした概念の上に成り立っています。なので、C をコンパイル言語と呼ぶときは、解釈が物理的に不可能だと言っているのではなく、それが定義的なワークフローだと言っているのです。

この答えは、自信があり、正確で、しかも防御的に聞こえません。例外の存在を知っていて、それでも分類が変わらない理由を説明できることが伝わります。

フォローアップ質問で、本当に理解していることを示す

あなたがごまかしていると思われたときに来る質問

コンパイラ対インタプリタの最初の答えのあと、フォローアップはほぼ確実にツールチェーンへ向かいます。想定しておきたいのは、「コンパイラは何を生成しますか?」(オブジェクトファイルです)、 「リンカは何をしますか?」(シンボルを解決して実行ファイルを作ります)、 「なぜ別のリンク工程が必要なのですか?」(コンパイルはファイル単位ですが、プログラムは複数ファイルにまたがるからです)といった質問です。パイプラインを内在化していれば難しくありません。ラベルだけ覚えていても、説得力を持って答えるのは不可能です。

オブジェクトファイルと実行ファイルの違いは、最もよくあるフォローアップの罠です。「コンパイラが実行ファイルを生成する」と答える候補者は、`gcc hello.c -o hello` が最終的に実行ファイルを作るという点では間違っていません。ですが、オブジェクトファイルとリンカを飛ばしてしまっているので、面接官には中間ステップを知らないと伝わります。

エラー処理とデバッグについてのフォローアップ

面接官はまた、コンパイル時エラーと実行時エラーを使って、いつミスが検出されるのかを確認しようとします。C の型不一致はコンパイル時に検出されます。コンパイラがプログラムの実行前に拒否するからです。ヌルポインタ参照は実行時エラーです。プログラム自体はコンパイルできても、実行中にクラッシュします。C ではこの違いが特に重要です。というのも、C のコンパイラは、通してしまうものに比べて、検出するものが比較的少ないからです。

実務上の意味は、コンパイル言語は開発サイクルの早い段階で特定の種類のバグを表面化できるということです。そのため C のコードベースでは、コンパイラに加えて静的解析ツールを使うのが一般的です。一方、インタプリタ言語では、関連コードの経路が実際に実行されたときにしかエラーは表面化しません。

実際にはどう見えるのか

面接官: リンカは具体的に何をしているのですか?

候補者: 各コンパイル済み翻訳単位からオブジェクトファイルを受け取り、別のファイルで定義された関数の呼び出しのような外部シンボル参照をすべて解決して、アドレスが確定した 1 つの実行ファイルを生成します。

面接官: では、なぜこのヌルポインタのバグをコンパイラは見逃したのですか?

候補者: コンパイラが見ているのは型と構文であって、実行時の値ではないからです。プログラム実行時にそのポインタがどんな値を持つかまでは分かりません。分かるのは、ポインタの型が正しいということだけです。ヌル参照が起きるのは特定の実行経路上であって、コンパイラにはそこまで予測できません。

どちらの答えも短く、具体的で、語彙だけでなく 仕組み を理解していることが伝わります。

相手が実際に使えるアナロジーを出す

ほとんどのたとえ話が、面接官の追及ですぐ崩れる理由

「コンパイラは本全体を先に翻訳してから読むのに対し、インタプリタは行ごとに読んでくれる翻訳者のようなもの」という定番のたとえは、最初の説明としては悪くありません。ただ、面接官が「では、そのたとえだとオブジェクトファイルはどこに入るの?」と聞いた瞬間に崩れます。本の翻訳モデルにはオブジェクトファイルもなければ、リンカもローダーもありません。このアナロジーはコンパイラとインタプリタの違いは説明しても、C の compile-link-run パイプラインには何も対応づけていません。面接で本当に問われているのはそこです。

C に特化して、きれいに対応づくアナロジー

C プログラムを作ることを、プレハブ部材で建物を建てることだと思ってください。コンパイラは設計図(ソースコード)を受け取り、コンクリートの部材(オブジェクトファイル)を工場で作る役目です。各部材はそれ自体で完結していますが、まだ接続されていない接合部があります。リンカは現場の施工チームで、それらの部材をボルトでつなぎ、配線を通し、完成した建物を作り上げます。ローダーは、その建物の正面玄関を開けて、現実世界で使える空間にする瞬間です。つまり、メモリという環境に配置され、CPU という人が実際に使えるようになるわけです。

このたとえでは、プリプロセッサは、工場が設計図を見る前に、すべての略記を展開しておく設計士にあたります。各ステップにははっきりした対応物があり、受け渡しの意味も明確です。

実際にはどう見えるのか

面接で口に出すなら、こうなります。「私はプレハブ建築のように考えています。コンパイラが部材を作り、リンカがそれらを組み立てて完成形にし、ローダーがその構造物を CPU が歩ける実際の土地に配置します。大事なのは、各ステップが次のステップに渡す“実体”を作っているという点で、魔法の箱が 1 つあるわけではない、ということです。」

この答えは覚えやすく、実際のパイプラインに対応していて、突っ込まれても崩れません。しかも、スライド資料を丸暗記したようには聞こえません。

Verve AI が、C におけるコンパイラ対インタプリタの面接準備をどう助けるか

パイプラインを知っていることと、面接のプレッシャーの中でそれを明快に話せることは別です。オブジェクトファイルについてのフォローアップに詰まらずに答えること、そして練習した感を出さずにアナロジーを決めること。これらはすべて実演スキルであり、練習しないと鈍ります。問題は内容そのものではありません。多くの候補者が頭の中でしか内容を練習していないことです。これは、実際に相手へ口頭で答えるスキルとはまったく別物です。

Verve AI Interview Copilot は、まさにこのギャップのために作られています。あなたが実際に話した内容をリアルタイムで 聞き取り 、決まり文句のプロンプトではなく、あなたの発言そのものに応じて反応します。たとえば、compile-link-run のパイプラインを説明していて、オブジェクトファイルについてのフォローアップが来た場合でも、Verve AI Interview Copilot はすでにあなたの答えがどこで終わったかを追跡しています。ごまかした部分を突き、`executable` と言うべきところで `object file` と言ってしまった箇所を拾い、暗記した台本ではなく実際の仕組みから答えを立て直す手助けをします。Verve AI Interview Copilot はこの間 見えないまま 動作するので、練習セッションはコーチ付きではなく、本番の面接のように感じられます。C のコンパイラ対インタプリタのように、一文の答えは入口にすぎず、本当の勝負はその後の受け答えで決まるテーマでは、こうしたライブ応答の練習こそが実際に成果につながります。

FAQ

Q: C はコンパイル言語ですか、それともインタプリタ言語ですか? 面接ではどう答えるべきですか?

C はコンパイル言語です。ソースコードは、実行前に compile-link-run パイプラインを通って機械語へ変換されます。面接ではそのまま、「C はコンパイル言語です。ソースはプリプロセス、アセンブリへのコンパイル、オブジェクトファイルへのアセンブル、実行ファイルへのリンクを経て、最後にローダーが実行します」と答えれば十分です。抽象的な長い定義より、パイプラインを名指しした一文のほうが有用です。

Q: .c ファイルから実行可能なプログラムになるまで、具体的には何が起きるのですか?

プリプロセッサがマクロと `#include` を展開し、コンパイラが展開済みソースをアセンブリへ変換し、アセンブラがそれをオブジェクトファイル内の機械語に符号化し、リンカがオブジェクトファイルをまとめてシンボル参照を解決して実行ファイルを作り、ローダーがそれをメモリにマップして実行を開始します。各ステップは、次のステップが受け取る別個の成果物を生成します。

Q: C のビルドプロセスで、コンパイラ、アセンブラ、リンカ、ローダーはどう違うのですか?

コンパイラは C をアセンブリへ変換します。アセンブラはアセンブリを、リロケータブルなオブジェクトファイル内のバイナリ機械語へ符号化します。リンカはオブジェクトファイル間のシンボル参照を解決し、アドレスが確定した実行ファイルを生成します。ローダーは実行ファイルをディスクから読み込み、仮想メモリへマップして、エントリポイントへ制御を渡します。各ツールは 1 つの仕事だけを担い、次のツールに特定の成果物を受け渡します。

Q: コンパイラとインタプリタの違いを、1 文で最も簡単に説明すると何ですか?

コンパイラはソース全体を実行前に機械語へ変換し、インタプリタは実行時に命令ごとにソースを変換しながら実行します。核心の違いは、変換がいつ起こるかです。コンパイラは実行前、インタプリタは実行中です。

Q: なぜコンパイルされたプログラムのほうが、通常はインタプリタのものより速いのですか?

変換作業がすべてビルド時に終わっているからです。コンパイル済みの C プログラムが動くとき、CPU はネイティブな機械命令をそのまま読みます。実行中に変換レイヤーがサイクルを消費することはありません。インタプリタは実行時にその変換コストを毎回支払うため、コンパイル済みプログラムにはないオーバーヘッドが生じます。

Q: C はインタプリタで動かせることがありますか? それでもなぜコンパイル言語と呼ばれるのですか?

CINT のような C インタプリタは存在しますが、標準的な本番ワークフローではありません。C がコンパイル言語に分類されるのは、GCC、Clang、MSVC といった主要ツールチェーンがすべて機械語へコンパイルすること、そして言語仕様自体が翻訳単位やリンケージといったコンパイルモデルでしか意味を持たない概念の上に構築されているからです。分類は理論上の例外ではなく、通常のケースに従います。

Q: 違いを説明したあと、面接官はどんなフォローアップをしてくる可能性がありますか?

よくあるのは、「コンパイラは何を生成しますか?」(実行ファイルではなくオブジェクトファイルです)、「リンカは何をしますか?」(シンボルを解決して実行ファイルを作ります)、「なぜ別のリンク工程が必要なのですか?」(コンパイルはファイル単位ですが、プログラムは複数ファイルにまたがるからです)、「コンパイル時エラーと実行時エラーの違いは何ですか?」(コンパイル時エラーは実行前にコンパイラが検出し、実行時エラーは特定のコードパスが実行されたときにだけ表面化します)といった質問です。これらをそれぞれ 1 文で答えられるようにしておけば、この面接質問は罠ではなくなります。

結論

あなたは、面接官から C がコンパイル言語かインタプリタ言語かを問われるところから始まりました。今では、その一文の答え、その裏にある 5 段階のパイプライン、突っ込まれても崩れないアナロジー、そしてオブジェクトファイル、実行ファイル、リンカ、コンパイル時エラーと実行時エラーに対するフォローアップまで手に入れています。内容はそろいました。

残るのは伝え方です。このテーマは、書いた内容ではなく、口に出した内容で勝負が決まります。だから次の模擬面接や採用面接の前に、パイプラインを声に出して 1 回言ってみてください。頭の中ではなく、声に出して、です。そして時間を測ってください。「C はコンパイル言語です」から「ローダーがメモリに配置し、CPU がネイティブの機械語を実行します」までを 60 秒以内で言え、なおかつオブジェクトファイルについてのフォローアップにも途切れず答えられるなら、準備はできています。面接官が見ているのは教科書ではありません。実際に何かを作ったことがある人の話し方です。

VA

Verve AI

コンテンツ