【C言語】もうコンパイルエラーで悩まない!頻出エラー原因と対策法

2025年4月15日火曜日

C言語

プログラミングを始めたばかりの時、エラーメッセージの群れを見ると、心が折れそうになりますよね…。「わけがわからない!」「もうやだ!」って。わかります、その気持ち!

でも、実はコンパイルエラーって、プログラミング上達のための最高の相棒なんです。あなたのコードの「ここ、ちょっと変だよ!」って親切に教えてくれるサインなんですから。

この記事では、コンパイルエラーの正体から、エラーメッセージの読み方、C言語で誰もが一度は通る「あるある」なエラーの原因と直し方、そしてエラーを未然に防ぐコツまで、詳しく解説します。

この記事でわかること

  • コンパイルエラーってそもそも何?がスッキリわかる
  • 謎のエラーメッセージを解読できるようになる方法
  • よくやるミスとその解決法(実例つき!)
  • エラーを減らすためのちょっとしたプロ技(?)

C言語のコンパイルエラーとは?プログラム実行までの流れ

まず、コンパイルエラーって何者なのか、プログラムが完成するまでの流れと一緒に見ていきましょう。

あなたが書いたC言語のコードは、実はそのままではコンピューターには理解できません。人間語みたいなものなので、コンピューターがわかる言葉(機械語)に「翻訳」してあげる必要があるんです。

ざっくり言うと、こんな流れです。

[あなたが書いたコード (ソースコード)]
          ↓
[翻訳&チェック (コンパイル)] ← ここでエラーが出ることが!
          ↓
[実行できるファイル完成!]
          ↓
[プログラム実行!]

この「翻訳&チェック」のステップが「コンパイル」。そして、コンパイルの途中で「おっと、この書き方ルール違反だよ!」とストップがかかるのが「コンパイルエラー」なんです。

料理で例えるなら、レシピ(ソースコード)通りに下ごしらえ(コンパイル)してたら、「あれ?材料足りないじゃん!」「この手順、おかしくない?」って指摘される感じですね。早めに気づけてラッキー、みたいな。

コンパイルの仕組みを簡単に理解しよう

コンパイルを担当してくれるのが「コンパイラ」というプログラムです。

このコンパイラ君、めちゃくちゃ几帳面な文法チェッカー兼翻訳家なんです。あなたが書いたソースコードを一行一行じーっくり読んで、「C言語のルール(文法)に合ってるかな?」「変な書き方してないかな?」って厳しくチェックしてくれます。

もしルール違反が見つかれば、「はい、エラーね!」ってビシッと指摘して、翻訳作業を中断します。逆に、全部チェックして問題なければ、コンピューターが理解できる言葉(機械語とかオブジェクトコードとか言います)に翻訳してくれる、というわけです。

なぜコンパイルエラーが発生するのか?主な原因

じゃあ、なんでエラーが出ちゃうんでしょう?

理由はシンプルで、あなたが書いたコードが、C言語の厳格なルールにちょっとだけ違反しちゃってるからです。

よくある原因はこんな感じ。

  • うっかりタイプミス(セミコロン`;`を忘れた、とか)
  • 括弧 `()` や `{}` の対応がズレてる
  • 変数や関数を使う前に、名前を教えて(宣言)してなかった
  • データの種類(型)が合わないものを無理やり使おうとした

人間なら「あ、これ書き間違いだな」って空気読んでくれることも、コンピューターは1ミリも許してくれません。

だって、彼らはルールブック通りにしか動けないんですから!
だから、エラーが出るのは、あなたがダメなんじゃなくて、コンピューターが超マジメなだけ。そう思えば、少し気が楽になりませんか?

C言語コンパイルエラーの基本的な読み方と対処の心構え

さて、いよいよ本題。あの謎の呪文にしか見えないエラーメッセージをどう読み解くか、です。

最初は「うわっ…」ってなるかもしれませんが、大丈夫。エラーメッセージは、実は問題解決への「宝の地図」なんです。どこに問題があるか、ちゃんとヒントが書かれていますから!

心構えとしては、「焦らない、慌てない」。エラーが出たら、まず深呼吸。そして、これから説明する方法で、メッセージをじっくり読んでみましょう。

エラーメッセージの構造:どこを見ればいい?

コンパイラによって多少表示は違いますが、エラーメッセージにはだいたい次の情報が含まれています。

[ファイル名]:[行番号]:[列番号]: error: [エラー内容の説明]

注目すべきは、この3つ!

  • ファイル名 - エラーが起きたファイルの名前
  • 行番号 - エラーが起きた(と思われる)コードの行数
  • エラー内容の説明 - どんなエラーなのかの簡単な説明(英語が多いけど、キーワードを見ればだいたいわかります!)

例えば、`main.c:10:5: error: expected ';' before '}' token` ってメッセージが出たとしましょう。

これは、「`main.c` っていうファイルの 10行目の5文字目あたり でエラーだよ。内容は `}` の前に `;` が必要みたいだけど、ないよ!」って教えてくれてるんです。
ね、こうやって分解すれば、どこを見ればいいか分かってきませんか?

まずは最初のエラーから!複数エラーが出た時の対処法

コンパイルすると、ズラズラーッ!っと、たくさんのエラーメッセージが出ることがあります。「もうダメだ…」って思う瞬間ですよね。
でも、ここでパニックにならないで!

実は、最初のエラーを直したら、他のエラーもまとめて消えちゃうってことが、結構よくあるんです。一つの間違いが、他の部分にも影響して、連鎖的にエラーが出ちゃうパターンですね。

だから、エラーがたくさん出た時は、まず一番上に表示されているエラーメッセージに集中しましょう。それを読んで、該当箇所を修正して、もう一度コンパイル!

これを繰り返すのが、一番効率的なエラー退治の方法です。焦らず、一つずつ、上から順番にやっつけていきましょう!

【実例で学ぶ】よくあるC言語コンパイルエラーと具体的な対策

ここからは、C言語初心者が「あるある!」って頷いちゃうような、よく遭遇するコンパイルエラーとその対策を、具体的なコードと一緒に見ていきましょう!

自分のコードと見比べながら、「あ、これかも!」って発見があるかもしれませんよ。

構文エラー (Syntax Error):セミコロン忘れ、括弧の不一致など

これは、C言語の「書き方ルール」を守れていない時に出るエラー。一番よく見かける、うっかりミスの代表格です。

エラーメッセージ例

hello.c:5:1: error: expected ';' before '}' token
hello.c:4:19: error: expected ')' before ';' token

原因

  • 文の終わりにセミコロン `;` をつけ忘れている。
  • `()` や `{}` の数が合っていない(開きっぱなし、閉じすぎなど)。

コード例 (エラー)

#include <stdio.h>

int main(void { // ← ここ!閉じ括弧 ')' がない!
  printf("Hello World!") // ← ここ!セミコロン ';' がない!
  return 0;
}

対策 (修正後のコード)

#include <stdio.h>

int main(void) { // ← 閉じ括弧 ')' を追加
  printf("Hello World!"); // ← セミコロン ';' を追加
  return 0;
}

セミコロンは、日本語の句点「。」みたいなもの、括弧はペアで使うもの、と覚えておくと、忘れにくくなるかもしれませんね。コードを書いたら、最後にチェックする癖をつけましょう!

未定義・未宣言エラー (Undefined/Undeclared Reference):変数や関数が見つからない

これは、コンピューターに「君、誰だっけ?」って言われちゃうパターン。使う前に、ちゃんと「こういうものを使いますよ」と教えて(宣言・定義)あげないと出るエラーです。

エラーメッセージ例

calc.c:7:3: error: 'anser' undeclared (first use in this function)
/usr/bin/ld: /tmp/ccXXXXXX.o: in function `main':
calc.c:(.text+0x2a): undefined reference to `print_result' 

(`undefined reference` は、コンパイル後のリンクっていう段階で出るエラーですが、原因は似ています)

原因

  • 変数を使う前に、型と名前を宣言していない(例: `int answer;` みたいに)。
  • 関数を使う前に、関数の存在を教えていない(宣言や定義がない、または必要なヘッダファイルを `#include` していない)。
  • 単純なスペルミス(例: `answer` を `anser` と打ち間違えた)。

コード例 (エラー)

#include <stdio.h>

// print_result 関数の宣言がない!

int main(void) {
  int value1 = 10;
  int value2 = 5;
  
  anser = value1 + value2; // ← 'anser' なんて知らないよ! (answer のスペルミス)
  
  print_result(anser); // ← 'print_result' なんて知らないよ!
  
  return 0;
}

// 関数の定義はあるけど、main関数より後にあるので、事前に教えておく(宣言)が必要
void print_result(int num) {
  printf("結果は %d です。\n", num);
}

対策 (修正後のコード)

#include <stdio.h>

// print_result 関数のプロトタイプ宣言 (使う前に関数の存在を教える)
void print_result(int num); 

int main(void) {
  int value1 = 10;
  int value2 = 5;
  int answer; // ← 変数 'answer' を使う前に宣言!
  
  answer = value1 + value2; // ← 正しい変数名 'answer' を使う
  
  print_result(answer); // ← これで print_result 関数を使える
  
  return 0;
}

void print_result(int num) {
  printf("結果は %d です。\n", num);
}

変数も関数も、使う前にちゃんと「こういう名前で、こういう種類のものです」とコンピューターに自己紹介(宣言)してあげる、というルールを徹底しましょう。スペルミスも意外と多いので、よーく確認してみてくださいね。

型の不一致エラー (Type Mismatch):データ型に関する間違い

C言語では、データ(数値、文字など)には「型」があります。`int` (整数) や `float` (小数)、`char` (文字) などですね。このデータの種類、つまり「型」を間違って扱おうとすると、コンパイラが「それは無理だよ!」って怒ってきます。

エラーメッセージ例

types.c:6:10: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
types.c:7:17: error: invalid operands to binary + (have 'int' and 'char *')

(`warning` はエラーではないけど、「これ、大丈夫?意図通り?」という注意喚起です。無視しない方がいい!)

原因

  • 整数を入れるべき変数に、文字や文字列を入れようとした(またはその逆)。
  • 関数が期待している引数の型と、実際に渡したデータの型が違う。
  • 違う型のデータ同士で、計算などの操作をしようとした。

コード例 (エラー)

#include <stdio.h>

int main(void) {
  int number;
  char message[] = "Hello";
  
  number = message; // ← int 型の変数に、文字列(char*)を入れようとしてる (Warning/Error)
  
  int result = 10 + message; // ← int 型の数値と文字列(char*)を足そうとしてる (Error)
  
  printf("%d\n", number); 
  printf("%d\n", result);
  
  return 0;
}

対策
この場合、やろうとしている操作自体がC言語のルール上、無理なことが多いです。「何をしたいのか」をもう一度考え、適切な型の変数を使ったり、型を変換する処理(キャスト)を入れたり、あるいは処理の流れそのものを見直す必要があります。

例えば、上のコードで「文字列の長さ」を扱いたいなら、`strlen` 関数を使うなど、別の方法を考える必要があります。

C言語では、データの「型」を意識することがすごく大事です。変数を使うとき、関数を呼び出すとき、「このデータの型は何かな?」と常に考える癖をつけましょう。

C言語コンパイルエラーを防ぐための予防策・注意点

エラーが出てから直すのも勉強ですが、できればエラーは少ない方がいいですよね!
ここでは、コンパイルエラーを未然に防ぐための、ちょっとしたコツや習慣を紹介します。

こまめにコンパイルする!

全部書き終わってからコンパイルするのではなく、関数一つ書いたらコンパイル、ちょっと機能を追加したらコンパイル、という感じで、短いスパンでこまめにコンパイルする癖をつけましょう。どこでエラーが出たか特定しやすくなりますし、一度に大量のエラーを見てげんなりすることも減ります。

変数名・関数名は分かりやすく!

`a` とか `x` とか一文字の変数名じゃなくて、`count` とか `user_name` みたいに、パッと見て意味がわかる名前をつけるように心がけましょう。スペルミスも減りますし、後でコードを見返した時にも理解しやすくなります。

コードの見た目を整える(インデント)

コードの字下げ(インデント)をちゃんと揃えるだけで、`{}` の対応関係などが格段に見やすくなり、括弧の不一致のようなエラーを防ぎやすくなります。エディタの自動整形機能を使うのも良いですね。

コンパイラの警告 (Warning) も無視しない!

エラー(Error) ではないけど、「ここ、ちょっと怪しいかもよ?」とコンパイラが教えてくれるのが警告(Warning)です。警告が出ている箇所は、今は問題なくても将来的にバグの原因になる可能性が潜んでいます。警告もできるだけ潰しておくのが、良いコードを書く秘訣です。

これらの習慣を身につけるだけで、エラーの発生率はぐっと下がりますよ!

【まとめ】コンパイルエラーを乗り越えよう

C言語のコンパイルエラーについて、原因から対策、予防策まで見てきました。

最初はとっつきにくく感じるコンパイルエラーも、その正体とメッセージの読み方さえわかれば、決して怖いものではない、ってことが伝わったら嬉しいです。

むしろ、エラーは「君のコード、もっと良くなるよ!」というコンピューターからのアドバイス。一つ一つ乗り越えるたびに、あなたのプログラミングスキルは確実にアップしていきます。

今回学んだことを武器にして、

  • エラーが出ても、慌てずメッセージを読む!
  • よくあるエラーパターンを知っておく!
  • そもそもエラーを出しにくい書き方を心がける!

この3つを意識してみてください。

うまくいかないことがあっても、諦めずにコードを書いて、コンパイルして、エラーを直して…その繰り返しが、C言語マスターへの一番の近道です。


【関連記事】

>> C言語とは?特徴・できること・学ぶメリット

このブログを検索

  • ()

自己紹介

自分の写真
リモートワークでエンジニア兼Webディレクターとして活動しています。プログラミングやAIなど、日々の業務や学びの中で得た知識や気づきをわかりやすく発信し、これからITスキルを身につけたい人にも役立つ情報をお届けします。 note → https://note.com/yurufuri X → https://x.com/mnao111

QooQ