C++
 Computer >> コンピューター >  >> プログラミング >> C++

【初心者向け】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++のエラーは、発生する段階によって適切な対処法が異なります。構文エラーや意味エラーはコンパイラが教えてくれるため比較的修正しやすい一方、実行時エラーや論理エラーはデバッガやテストを通じて発見する必要があります。エラーの種類を理解しておくことで、トラブルシューティングの効率が大幅に向上するでしょう。

  1. C/C++のmemcpy()関数の使い方と実例解説

    この記事では、C++ STLにおけるmemcpy()関数の動作、構文、および具体的な使用例について詳しく解説します。 memcpy()とは? memcpy()関数は、C++ STLに組み込まれた標準関数の一つで、<cstring>ヘッダーファイルで定義されています。この関数はメモリブロックをコピーするために使用され、あるメモリ位置から別のメモリ位置へ、指定されたバイト数分のデータを転送します。 関数の実行結果は、データのバイナリコピーとなります。重要な点として、memcpy()は終端のNULL文字やその他の終端記号をチェックしません。単純にソースから指定されたバイト数(num)をそ

  2. C/C++で学ぶAA木(AA Tree)とは?基本概念と平衡化操作を徹底解説

    AA木(AA Tree)とはコンピュータサイエンスにおいて、AA木(AA Tree)とは、順序付きデータを効率的に格納・検索するために実装された平衡木(バランスドツリー)の一種です。AA木は、赤黒木(Red-Black Tree)の変種として扱われます。赤黒木は二分探索木の一形態であり、要素の追加や削除を効率的にサポートします。赤黒木と大きく異なる点は、AA木では赤いノードを右の子としてのみ追加でき、左の子としては配置できないという制約があることです。この制約により、2-3-4木ではなく2-3木をシミュレートすることになり、その結果、木の保守操作が大幅に簡素化されます。赤黒木の平衡化アルゴリズ