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可見,進入斷點前,程序運行正常;下面查看變量num一、num2的值。
圖4.變量賦值狀況
由圖4可見,變量num一、num2的值正常讀入。下面將斷點設置在(2)處,全速運行。
圖5.進入斷點2前程序運行狀況
由圖4可見,進入while循環以前,程序正常運行。查看變量a、b賦值狀況發現此時變量a、b均按照程序預期賦值。
圖6.變量a、b賦值狀況
下面開始單步運行。由圖7可見,第一次循環結束變量a的值爲4,b的值
圖7.第一次循環執行狀況
爲2,temp的值爲0;繼續單步運行。從圖8能夠看出,在第二次進入循環執行測試
圖8.第二次循環執行狀況spa
語句「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值,咱們在編寫程序的時候需當心謹慎,注意程序的邏輯,避免之中錯誤的發生。問題代碼系網上引用,其中展轉相除法的邏輯錯誤,此處不加討論。3d