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 = 1因为while循环将被跳过,因此您将返回一个未初始化的变量.

于 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 回答