1.2.4  调试技巧

本节演示了一个常用的调试技巧。

1.实例说明

本示例演示当程序出错时,如何排除错误。GetSum函数的功能是求iBeginiEnd之间所有整数的倒数之和。

2.实现

具体的排错过程如下:

1)新建一个基于对话框的程序Ex010204

2)增加一个按钮,IDIDC_GETSUB,标题为“求和”。

3)增加一个全局函数GetSum,为新加的按钮增加一个响应函数,相关代码如下:

double GetSum(unsigned int iBegin, unsigned int  iEnd )

{

         double dSum = 0 ;

         for(unsigned short  i = iBegin ; i <= iEnd ; i++ )

         {

                  dSum += 1.0/i ;         

         }      

        

         return dSum ;

}

 

void CEx010204Dlg::OnGetsub()

{

         double dSub = GetSum(1,100000);

        

         CString strMess ;

         strMess.Format("总和是%lf",dSub);

         AfxMessageBox(strMess);        

}

4)按F5键调试程序,单击“求和”按钮后,会发现程序死了。

5GetSum函数中循环10万次,显然无法调试。

6)为了找到出错的大致位置,在“dSum += 1.0/i ;”后面添加如下代码:

         if( 0 == i % 1000)

                   {

                            CString str ;

                            str.Format("%d\n",i);

                            TRACE(str);

                   }        

F5键调试程序,等一小段时间后停止调试,查看OutPut区,发现如下可疑情况:

63000

64000

65000

0

1000

2000

3000

4000

5000

可以断定,在65000后面的某个位置出错了。

7)将if( 0 == i % 1000)改成if(i > 65000 || 0 == i % 1000),使用步骤(6)的方法查看OutPut区,发现如下可疑情况:

65534

65535

0

1000

2000

i作了除数,显然不能为零,为了避免犯这种错误,增加如下代码:

if(0 == i)

{

         ASSERT(false); //断言便于发现错误

         continue ;//0作除数忽略

}

8)在“dSum += 1.0/i;”前加一个断点,条件设置为“65535 == i”,按F5键调试程序,当i65535时断点会起作用,再单步运行会发现65535+1的值为0,这是因为iunsigned short改成unsigned long就行了,除掉调试信息后的代码如下:

double GetSum(unsigned int iBegin, unsigned int  iEnd )

{

         double dSum = 0 ;

         for(unsigned int i = iBegin ; i <= iEnd ; i++ )

         {

                  if(0 == i)

                   {

                            ASSERT(false);//断言便于发现错误

                            continue ;//0作除数忽略

                   }

                  dSum += 1.0/i ;                  

         }      

 

         return dSum ;

}



回目录