• ベストアンサー

C言語でのエラーの直し方について?

C言語でのエラーが発生したとします。その時、どのようにして、エラーを見つけ直していくのですか? 私はprintfを用いて値を見ることでエラーを見つけています。 ステップインで実行して変数にどのような値が入っているか見つけようともしているのですが、変数にa値が16進数で格納されていたり、アドレスがあったりと見方が複雑でうまく発見できていません。 正しい、エラーの見つけ方、直し方とはどういったやり方なのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
noname#131551
noname#131551
回答No.1

アナタのデバッグの範囲がよくわかりませんが ●関数の単体検証なら、引数の入出力で解りますよね。 例えば、2つの入力引数を与えると、1つの関数値を返すとか。即ち、ians = func_apb ( ia , ib ); とかで、引数に最大値とか最小値を設定し、戻り値を確認すれば機能どおりでの動作かバグかわかりますよね。ここで、最小値、最小値+1、最小値+2、-1、0、+1、最大値-2、最大値-1、最大値の変化点を検証します。これは、値の極性が正常であることの確認です。 できれば、単体検証では、最大~最小までの値のテストケースを自動投入し、結果の挙動まで検証することが望ましいですね。理由は、上限挙動、下限挙動、極性変化が確実に証明できるからです。Cの良いところは、符号計算を適当にごまかすことです。・・・となると最大値になった瞬間にマイナスにトランジェントするから、バグがわかるわけですよ。 ●関数の結合検証では、関数自体の最大~最小までは検証済みなので、複数のサンプリング値を投入するか、本番データで動作させます。 ●総合検証では、テストケースの準備が複雑なので本番データだけでよいでしょう。 ・・・で、1行ごとのデバッグならエミュレータで変数のダンプを見れば済みますよね。そこのエミュレータ部分はprintf()で抽出しているなら、マクロで記述しておいて、本番コンパイルのとき空行にリプレースすれば、printf()を書いたり消したりせずに、済みます。即ち、テストのソースコードと本番のソースコードは同一で、コンパイル条件が違うだけです。 (組込み系では、printf()などの標準関数は使用しないので、ひたすら変数のダンプです。)

yakyuuoh
質問者

お礼

ありがとうございます。

その他の回答 (3)

回答No.4

> ステップインで実行して変数にどのような値が入っているか見つけようともしているのですが、変数にa値が16進数で格納されていたり、アドレスがあったりと見方が複雑でうまく発見できていません。 デバッガ使ってステップインで確認できるのですよね。 それなら、わざわざprintfで固定の値確認する必要なさそうに感じました。 コンパイラが最適化でデバックで確認しずらいコードに変えている場合があるので、最適化レベルをデバックに支障のない程度に落としてコンパイルしてデバッグすると良い気がします。 デバッガ内で値の確認はアドレスでも値でも10進でも16進でも自由に確認できると思いますので、確認できない場合にはデバッガの使い方をお調べになればよろしいかと。 監視したい変数をウォッチリストに入れておけばその値は常に表示されたり変更時に表示されたりなどデバッガに依っては色々な便利機能がありますので使うと楽になりますよ。 自分で作ったプログラムなのかなあ。他人が作ったプログラムなのかな。他人が作ったプログラムを効率良くデバッグって難しい気もしますが、読解力を付ける(高める)と良さそうですね。 色々なソースを読み色々なやり方を知っておきましょう。

yakyuuoh
質問者

お礼

ありがとうございます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

とりあえず 「変数にa値が16進数で格納されていたり、アドレスがあったり」 の意味が分からん. 「a値」って何? 究極的には「ダンプを見て『こけた原因』を探る」しかないような気がする. 「printfデバッグ」は手軽なんだけど, それでも原因が分からないことはあるので.

yakyuuoh
質問者

お礼

ありがとうございます。

回答No.2

・関数に渡された時の引数の値(入力値) ・関数から返却するときの引数の値(出力値) ・関数内で分岐する直前の値 を調べれば良いです。 アドレス値が分かっても意味がないので、アドレス値が参照している実の値をprintfに出力させてください。

yakyuuoh
質問者

お礼

ありがとうございます。

関連するQ&A

  • C言語 どこがコンパイルエラーか解りません。

    いつも大変お世話になっております。 標記の件。 どこがエラーなのか解りません。 2時間くらい、にらめっこが続いています。 どこがエラーなのか教えて下さい。 ご回答のほどよろしくお願い申し上げます。 コード #include <stdio.h> int a = 0; void func(void) { int c = 2; printf("func関数では変数aとcが使えます。¥n”); printf("変数aの値は%dです。\n",a); /*printf("変数bの値は%dです。\n",b);*/ printf("変数cの値は%dです。\n",c); } int main(void) { int b = 1; printf("main関数では変数aとbが使えます。\n"); printf("変数aの値は%dです。\n", a); printf("変数bの値は%dです。\n", b); /*printf("変数cの値は%dです。\n", c); */ func(); return 0; } コンパイルエラー printf("func関数では変数aとcが使えます。¥n”); ^ text10.c:9:8: error: missing terminating " character printf("func関数では変数aとcが使えます。¥n”); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ text10.c:10:34: error: expected ')' before ';' token printf("変数aの値は%dです。\n",a); ^ text10.c:10:1: warning: passing argument 1 of 'printf' makes pointer from integer without a cast [-Wint-conversion] printf("変数aの値は%dです。\n",a); ^~~~~~ In file included from text10.c:1:0: c:\mingw\include\stdio.h:454:38: note: expected 'const char *' but argument is of type 'int' _CRTIMP __cdecl __MINGW_NOTHROW int printf (const char *, ...); ^~~~~~ text10.c:13:1: error: expected ';' before '}' token } どうかよろしくお願いいたします。

  • c言語で定義する変数のアドレス

    c言語の超初心者です。追いえてください。 c言語で2つの変数を定義しています。 char *a; char *b; この2つの変数に値をいれた際の動作で以下のようなことって発生しますか? a="1111" b="2222" aをprintfするとbにいれた値"2222"が表示される。

  • C言語です。

    C言語について…配列を使うときにa[]を使いますが、例えば要素数を10個とすればa[10]ですよね? ではa[n]としてprintf("n=");scanf("%d",&n);でその度に要素数を変えることはできないのですか?エラーが出てきてしまいます。

  • C言語でのプログラミング

    C言語でのプログラミング プログラミングの勉強中で少し疑問が出てきたので、教えていただけるとありがたいです。 1から10までの数を足していくという次のプログラミングについてです。 #include <stdio.h> void main(void) {    int a = 0, i;    for (i=1; i<=10; i++) {      a = a + i;    }    printf("1から10の合計は%dです¥n", a); } 変数として、aとiを定め、aには0が代入されています。 つぎにforループが発動する際に、iに1が代入されiが10以下であるため、a = a + iが実行されます。 このとき、右辺が先に実行されa = 1となるはずです。 ここで疑問なのですが、aには1だけ入っているのでしょうか? それとも0と1が入っているのでしょうか? そしてa = a + iが実行されたのち、i++によりiには2も入ることになると思います。 ここでも同じ疑問として、iには1と2が入っているのか? それとも2だけが入っているのか良く分かりません。 もし仮にaにもiにも数字がどんどん格納されていくのなら、なぜ足し算の式において一つの値だけを取り出して足し算を実行できるのか分かりません。 長くなりましたが、ご解答よろしくお願いします。

  • 【C言語】 コンパイルエラーが解決できません

    参考書でC言語学習中の初心者です。 参考書記載のサンプルコードをコンパイルするとエラーになります。 誤字脱字は何度も確認しています。google等でも調べましたがわかりませんでした。。。 どなたか、どこが間違っているのかご教示いただけませんでしょうか。 また、何か的外れな記載があればご指摘いただけますでしょうか。 【環境】 OS: Mac OS X 10.9.3 コンパイラ:Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) 【サンプルコード】  ------------------------------------------------- #include<stdio.h> int main(void){ int data; data = 10; printf("変数dataの値 = %d\n", data); printf("変数dataのアドレス = %08X", &data); return 0; } ------------------------------------------------- 【エラー】 破線内 ------------------------------------------------- sample12-1.c:9:45: warning: format specifies type 'unsigned int' but the argument has type 'int *' [-Wformat] printf("変数dataのアドレス = %08X", &data);                     ~~~~ ^~~~~ 1 warning generated. ------------------------------------------------- 宜しくお願い申し上げます。

  • C言語の参考書について

    大学の後期の授業でC言語の参考書を買ってくるように言われました。 でもどの参考書がいいのかわからないので教えてください!! 前期の授業では ・C言語で作成したプログラムのコンパイルと実行の 流れ ・コンパイルエラーのエラーメッセージの見方 ・実行時のエラーとプログラムの修正 ・C言語のプログラムの基本形 ・printf()と定数 ・変数 ・数値型 ・文字型 ・文字列 ・printf()の書式指定 ・プログラム記述時の約束、予約語 ・算術演算子 ・代入演算子 ・インクリメント、デクリメント演算子 ・比較演算子(関係演算子) ・式が持っている値 ・論理演算子 ・条件付き代入 を勉強しました。 その範囲は、まだちゃんとに覚えてないけど授業でもらったプリントを見れば一応できます。 それで先生いわく、参考書は入門編でもいいらしいんですけど、さらに実践編も買い足さなければいけないらしいんです。 今の状態で実践編でも大丈夫ですかねぇ??

  • コンパイルエラーについて

    #include <stdio.h> int main(void){ char a[8],b[7],c[6]; printf("a[8]のアドレスは%pです。\n",&a[8]); //a[8]のメモリアドレスを表示 printf("\n"); printf("b[7]のアドレスは%pです。\n",&b[7]); //b[7]のメモリアドレスを表示 printf("\n"); printf("c[6]のアドレスは%pです。\n",&c[6]); //c[6]のメモリアドレスを表示 printf("\n"); char *c1 ="abcde"; printf("c1=%s\n",c1); //abcdeを表示 printf("c1[2]=%c\n",*(c1+2)); //先頭アドレスの2つ先のアドレスに格納されている値(c)を表示 char c2[] ="abcde"; char *pc2; printf("c2=%s\n",c2); //abcdeを表示 pc2=&c2[2]; //変数c2[2]のアドレスを格納 printf("c2[2]=%c\n",*pc2); //c2[2]アドレスに格納されている値(c)を表示 char *c="abcdefghijklmn"; char cc[]="opqrstuvwxyz"; printf("%c\n", *(c+7)); printf("%c\n", *(cc+2)); return 0; } としてコンパイルした所、 test.c: In function ‘main’: test.c:31: error: conflicting types for ‘c’ test.c:4: note: previous declaration of ‘c’ was here と出てしまいました。原因が良く分からないのですが教えて頂けますでしょうか?

  • C言語について

    C言語のじゃんけんゲームを作成したいのですが、 仕様は 1.利用者とコンピュータによる対戦形式とします。 2.利用者がキーボードから入力した手(グー・チョキ・パー)と、擬似乱数を用いて生成したコンピュータの手を比較し、利用者の勝ち・あいこ・負けの結果を表示しなさい。 3.利用者の入力が不正の場合には再度入力を促すなど、適切な処理をしなさい。 4.これまでの累積勝利数・引き分け数・敗北数をそれぞれ、user_win・user_draw・user_loseの3つの変数(int型)に格納しなさい。 5.連勝中の場合は「5連勝中!」などと表示させるようにしなさい。 6.あいこである限りは自動的にじゃんけんを反復しなさい。 7.勝敗がついた場合、利用者にまだ継続するか質問した上で、じゃんけんを反復させなさい。 8.じゃんけんを終了した場合、これまでの通算成績として、累積勝利数・引き分け数・敗北数のほか、勝利=累積勝利数÷(累積勝利数+累積敗北数)×100、および、最大勝利数を計算して表示しなさい。 という仕様のじゃんけんゲームを作成したいのですが、下記に書いているまでしかできません。誰か教えていただけないでしょうか。分からなくて困っています。 #include <stdio.h> #include <stdlib.h> #include <time.h> int main(){ int a,c; srand(time(NULL)); c = rand()%3+1; printf("手を入力してください [1:グー 2:チョキ 3:パー] "); scanf("%d",&a); if(a==1 && c==1) printf("あなたはグーで、私もグーでした。アイコです。\n"); else if(a==1 && c==2) printf("あなたはグーで、私はチョキでした。あなたの勝ちです。\n"); else if(a==1 && c==3) printf("あなたはグーで、私はパーでした。あなたの負けです。\n"); else if(a==2 && c==1) printf("あなたはチョキで、私はグーでした。あなたの負けです。\n"); else if(a==2 && c==2) printf("あなたはチョキで、私もチョキでした。アイコです。\n"); else if(a==2 && c==3) printf("あなたはチョキで、私はパーでした。あなたの勝ちです。\n"); else if(a==3 && c==1) printf("あなたはパーで、私はグーでした。あなたの勝ちです。\n"); else if(a==3 && c==2) printf("あなたはパーで、私はチョキでした。あなたの負けです。\n"); else if(a==3 && c==3) printf("あなたはパーで、私もパーでした。アイコです。\n"); else printf("正しい手を入れてください。\n"); return 0; }

  • C言語、実行でエラー。

    いつも大変お世話になり誠にありがとうございます。 標記の件。 shift jifでコンパイルしているのですが コンパイルはお陰様で成功したのですが、 実行でエラーが発生します。 下記にコードとエラーメッセージを書きます。        記 コード #include <stdio.h> int main(void) { printf("8進数101の文字コードをもつ文字は%cです。\n", '\101'); printf("16進数61の文字コードをもつ文字は%cです。\n", '\x61'); return 0; } 実行 C:\MinGW>gcc text4.c -o test4 C:\MinGW>text4.exe 'text4.exe' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 ご多忙のところ 度々申し訳ございません。 ご回答の程宜しくお願い申し上げます。

  • C言語での実行時エラーの場所を特定するには?

    こんにちは。 C言語あるいはC++言語において、プログラム(exeファイル)を実行した時にエラーが発生した場合、 どこでエラーが出ているのかをすぐに特定できる手段はあるのでしょうか? 例えば、printf関数などで、文字を出力していれば、どこでエラーが起きたのかが分かる場合もありますが、文字が出力されないでエラーが起こる場合もあります。 ですので、実行時エラーが起きている場所を特定するのに、いつも苦労します。 何か便利なツールなどは存在しないのでしょうか? ちなみにコンパイラは、Borand C++ Compiler 5.5 を使っています。 何かいい方法を知っておられる方がいらっしゃれば、是非アドバイスを頂きたいと思います。 では、よろしくお願い致します。

専門家に質問してみよう