2

このコードをコンパイルしましたが、実行時に浮動小数点例外が発生します

#include<stdio.h>
int fibonacci(int n)
{
  int a=0,b=1,c;
  while((n-1)>0)
  {
    c=a+b;
    a=b;
    b=c;
    n--;
  }
  return c;
}
int main()
{
  int t,a,b,c;
  scanf("%d",&t);
  while(t--)
  {
    scanf("%d%d",&a,&b);
    while(a--)
    {
      b=fibonacci(b);
    }
    printf("%d",(b%c));
   }
  return 0;
 }

この問題を解決するにはどうすればよいですか?

4

4 に答える 4

8

この問題を解決するにはどうすればよいですか?

この問題に対処する最初のことは、コンパイラが提供できるヒントを確認することです。つまり、警告 ( -Wall) とデバッグ シンボル ( ) を有効にします-g

$ gcc test.c -Wall -g
test.c: In function ‘main’:
test.c:25:11: warning: ‘c’ may be used uninitialized in this function [-Wuninitialized]

25 行目の変数に何か問題がある可能性がありますc。これはまさに print ステートメントです。

printf("%d",(b%c));

実行するとどうなるか見てみましょう。

$ ./a.out
1
2
3
Floating point exception (core dumped)

うーん、失敗です。しかし、どうやってクラッシュしたのですか?これはgdbの使用例です:

$ gdb ./a.out
GNU gdb (GDB) Fedora (7.5.1-37.fc18)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/moooeeeep/a.out...done.
(gdb) run
Starting program: /home/moooeeeep/a.out 
1
2
3

Program received signal SIGFPE, Arithmetic exception.
0x0000000000400640 in main () at test.c:25
25      printf("%d",(b%c));
Missing separate debuginfos, use: debuginfo-install glibc-2.16-30.fc18.x86_64

ちょうど 25 行目です。疑わしいです。変数の内容を調べてみましょう。

(gdb) print b
$1 = 1
(gdb) print c
$2 = 0

その変数cは確かにゼロです。しかし、整数しかないときに浮動小数点例外が発生するのはなぜですか? (他の人はあなたの前にこれを観察しました。)デバッガーで見ることができるように、それは算術例外 (cf)と呼ばれます:

SIGFPE シグナルは、致命的な算術エラーを報告します。名前は「浮動小数点例外」に由来しますが、この信号は実際にはゼロ除算やオーバーフローを含むすべての算術エラーをカバーします。

valgrindが教えてくれることを見てみましょう:

$ valgrind ./a.out
==3113== Memcheck, a memory error detector
==3113== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==3113== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==3113== Command: ./a.out
==3113== 
1
2
3
==3113== 
==3113== Process terminating with default action of signal 8 (SIGFPE)
==3113==  Integer divide by zero at address 0x403E58A5B
==3113==    at 0x400640: main (test.c:25)
==3113== 
==3113== HEAP SUMMARY:
==3113==     in use at exit: 0 bytes in 0 blocks
==3113==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==3113== 
==3113== All heap blocks were freed -- no leaks are possible
==3113== 
==3113== For counts of detected and suppressed errors, rerun with: -v
==3113== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Floating point exception (core dumped)

valgrind は、正確に 25 行目でゼロによる整数除算を識別しました。その行 (および関連する変数) に注目する必要があります。


ほとんどの IDE (Eclipse など) にはこれらのツール (の一部) が直接統合されているため、デバッグが非常に魅力的であることに注意してください。

于 2013-05-08T18:32:33.110 に答える
3

を初期化しなかったcため、おそらく未定義の数値を法として実行しています0:

printf("%d",(b%c));
于 2013-05-08T18:03:51.783 に答える
2

Shafik によって述べられた問題に加えて、ループで設定されているため、初期化されていないままにしfibonacci(0)ても問題fibonacci(1)ないという仮定は、ループがスキップされるため、初期化されていない変数を返すため、失敗します。 .cint fibonacci(int)n = 0n = 1while

于 2013-05-08T18:06:03.590 に答える
1

メソッドに渡す1fibonacci(int n)、初期化せずに c が返されます。

これを試して:

int fibonacci(int n)
{
  if(n==0 || n==1)
    return n;

  int a=0,b=1,c;
  while((n-1)>0)
  {
    c=a+b;
    a=b;
    b=c;
    n--;
  }
  return c;
}
于 2013-05-08T18:08:12.317 に答える