【初心者向け】C/C++で発生する5種類のエラーの原因と対処法を解説
CやC++でプログラムを作成していると、さまざまな種類のエラーに直面します。これらのエラーは、発生するタイミングや原因によって大きく5つのタイプに分類できます。
- 構文エラー(Syntax Error)
- 実行時エラー(Run-Time Error)
- リンカーエラー(Linker Error)
- 論理エラー(Logical Error)
- 意味エラー(Semantic Error)
以下、それぞれのエラーについて詳しく見ていきましょう。
構文エラー(Syntax Error)
C++の記述ルールや構文に違反した場合に発生するエラーです。このエラーはコンパイル前にコンパイラによって検出されるため、「コンパイル時エラー」と呼ばれることもあります。
次の例では、行末にセミコロン(;)を付け忘れたことで構文エラーが発生します。
コード例
#include<stdio.h>
main() {
printf("Hello World")
}
出力結果
[Error] expected ';' before '}' token
「'}' の前に ';' が必要」というエラーメッセージが表示され、コンパイルが中断されます。
実行時エラー(Runtime Error)
プログラムの実行中に発生するエラーです。コンパイル自体は正常に完了するため、ビルド段階では気づきにくいのが特徴です。典型的な例として、数値を0で除算しようとしたケースが挙げられます。
コード例
#include<stdio.h>
main() {
int x = 52;
int y = 0;
printf("Div : %f", x/y);
}
出力結果
実行時にプログラムがクラッシュする
0による除算は数学的に定義されていないため、プログラムは異常終了します。
リンカーエラー(Linker Error)
コンパイルが成功した後、複数のオブジェクトファイルを実行ファイルとして結合(リンク)する段階で発生するエラーです。このエラーが発生すると、実行ファイルは生成されません。
主な原因としては、関数プロトタイプの宣言ミス、ヘッダーファイルの指定間違いなどが挙げられます。また、エントリーポイントである main() を誤って Main() と記述した場合も、リンカーエラーが発生します。
コード例
#include<stdio.h>
Main() {
int x = 52;
int y = 0;
printf("Div : %f", x/y);
}
出力結果
undefined reference to `WinMain'
C言語では大文字と小文字が区別されるため、Main という名前の関数は main とは認識されず、リンカーがエントリーポイントを見つけられずにエラーとなります。
論理エラー(Logical Error)
構文やその他の記述が正しいにもかかわらず、期待どおりの出力が得られない場合に発生するエラーです。プログラム自体は問題なく動作するため、発見が最も難しいエラーと言われています。
典型的な例として、for文などのループの直後にセミコロンを付けてしまうケースがあります。これは構文的には正しいためコンパイルは通りますが、空のループが生成され、意図した処理が正しく実行されません。
コード例
#include<stdio.h>
main() {
int i;
for(i = 0; i<5; i++); {
printf("Hello World");
}
}
出力結果
Hello World
本来なら「Hello World」が5回表示されるはずですが、for文の直後のセミコロンにより空のループが5回実行されるだけで、printf文を含むブロックは1回しか実行されません。
意味エラー(Semantic Error)
構文的には正しいものの、コードとして意味をなさない場合に発生するエラーです。人間の言葉における「文法的には合っているが意味が通らない」といった状態に似ています。
典型的な例として、代入演算子(=)の左辺に式を記述したケースがあります。左辺には値を格納できる変数など(lvalue:左辺値)が必要なため、式を置くとエラーになります。
コード例
#include<stdio.h>
main() {
int x, y, z;
x = 10;
y = 20;
x + y = z;
}
出力結果
[Error] lvalue required as left operand of assignment
「代入の左辺にはlvalue(左辺値)が必要」というエラーが表示されます。x + y = z; ではなく z = x + y; と記述するのが正しい形です。
まとめ
C/C++のエラーは、発生する段階によって適切な対処法が異なります。構文エラーや意味エラーはコンパイラが教えてくれるため比較的修正しやすい一方、実行時エラーや論理エラーはデバッガやテストを通じて発見する必要があります。エラーの種類を理解しておくことで、トラブルシューティングの効率が大幅に向上するでしょう。
-
C/C++のmemcpy()関数の使い方と実例解説
この記事では、C++ STLにおけるmemcpy()関数の動作、構文、および具体的な使用例について詳しく解説します。 memcpy()とは? memcpy()関数は、C++ STLに組み込まれた標準関数の一つで、<cstring>ヘッダーファイルで定義されています。この関数はメモリブロックをコピーするために使用され、あるメモリ位置から別のメモリ位置へ、指定されたバイト数分のデータを転送します。 関数の実行結果は、データのバイナリコピーとなります。重要な点として、memcpy()は終端のNULL文字やその他の終端記号をチェックしません。単純にソースから指定されたバイト数(num)をそ
-
C/C++で学ぶAA木(AA Tree)とは?基本概念と平衡化操作を徹底解説
AA木(AA Tree)とはコンピュータサイエンスにおいて、AA木(AA Tree)とは、順序付きデータを効率的に格納・検索するために実装された平衡木(バランスドツリー)の一種です。AA木は、赤黒木(Red-Black Tree)の変種として扱われます。赤黒木は二分探索木の一形態であり、要素の追加や削除を効率的にサポートします。赤黒木と大きく異なる点は、AA木では赤いノードを右の子としてのみ追加でき、左の子としては配置できないという制約があることです。この制約により、2-3-4木ではなく2-3木をシミュレートすることになり、その結果、木の保守操作が大幅に簡素化されます。赤黒木の平衡化アルゴリズ