1.问题发现 有这样一段代码: #include <stdio.h> int main() { int a, b, num1, num2, temp; printf("please input two numbers:\n"); scanf("%d,%d", &num1, &num2); if(num1 > 0 && num2 > 0) (1) { a = num1; b = num2; temp = a%b; } while(b != 0) (2) { a = b; b = temp; temp = a%b; } printf("gong yue shu : %d\n", a); printf("gong bei shu : %d\n", num1*num2/a); return 0; } 该代码输入任何数字的执行结果(如图1)都是“浮点数异常(核心已转储)”,刚刚见到这个问题让人感觉摸不着头绪,程序根本没有用到浮点数,怎么会报告浮点数异常; 图1.程序运行结果 2.问题分析 下面我们通过Linux自带调试工具Gdb来进行调试,观察程序的运行状况。在编译的是个加上“-g”选项,方便利用Gdb调试。
图2.编译和调试指令 程序编译没有错误,下面使用Gdb工具调试;在不知道问题产生根源的情况下,先在(1)处设置断点,全速运行; 图3.断点之前运行情况 从图3可见,进入断点前,程序运行正常;下面查看变量num1、num2的值。 图4.变量赋值情况 由图4可见,变量num1、num2的值正常读入。下面将断点设置在(2)处,全速运行。 图5.进入断点2前程序运行情况 由图4可见,进入while循环之前,程序正常运行。查看变量a、b赋值情况发现此时变量a、b均按照程序预期赋值。 图6.变量a、b赋值情况 下面开始单步运行。由图7可见,第一次循环结束变量a的值为4,b的值 图7.第一次循环执行情况 为2,temp的值为0;继续单步运行。从图8可以看出,在第二次进入循环执行
图8.第二次循环执行情况
语句“temp = a%b;”的时候出现了错误。分析变量值发现此时变量a的值为2,b的值为0,对0求余是没有意义的,语法不允许。到此,问题水落石出。 现在,我们编写测试代码对问题产生原因进行验证,代码如下: #include <stdio.h> int main(int argc , char *argv[]) { int a=5,b=0; printf("%d\n",a%b); return 0; } 图9.测试代码运行情况 由图9可见,该错误系求余运算符右边操作数为0值所致。如果把测试代码的“a%b”改为“a/b”,运行结果仍然是浮点数例外。求余运算和除法运算不允许右边的操作数为0值,我们在编写程序的时候需小心谨慎,注意程序的逻辑,避免之中错误的发生。问题代码系网上引用,其中辗转相除法的逻辑错误,此处不加讨论。 |