第十课 调试技术-进入函数内部去【项目1-2】

项目十 调试技术-进入函数内部去





项目一【sin泰勒展式中的错误】

下面是sin函数的泰勒展式:
(注:x取弧度值,而非角度值)
编写了double mysin(double x)用于求sin值,却“死”在了123°上。剧透一下,循环没有问题(当然问题会表现在循环中)。试着用调试工具找出问题出现在哪里,然后给出解决问题的方案。

[cpp]  view plain  copy
 print ?
  1. #include<stdio.h>  
  2. #define pi 3.1415926  
  3. double mysin(double x);  
  4. double myabs(double x);  
  5. int main( )  
  6. {  
  7.     double angle;  
  8.     for(angle=0; angle<=180; angle++)  
  9.         printf("sin(%.0f°) = %.3f\n", angle, mysin((angle/180)*pi));  
  10.     return 0;  
  11. }  
  12.   
  13. //下面定义mysin函数,求sin值  
  14. double mysin(double x)  
  15. {  
  16.     double sum=x,x_pow=x,item;  
  17.     int n=1,fact=1, sign=1;     //定义变量时赋初值,已经将第一项考虑到累加和sum中  
  18.     do  
  19.     {  
  20.         fact=fact*(n+1)*(n+2);  //fact用于表示阶乘,在公式中作分母  
  21.         x_pow*=x*x;             //x_pow是分子中用于表示阶乘,在公式中作分母  
  22.         sign=-sign;             //确定即将要累加的这一项的符号  
  23.         item =x_pow/fact*sign; //计算出要累加的项  
  24.         sum+=item;              //将该项累加上去  
  25.         n+=2;  
  26.     }while(myabs(item)>1e-5);  
  27.     return sum;  
  28. }  
  29.   
  30. //下面定义myabs函数  
  31. double myabs(double x)  
  32. {  
  33.     return ((x>=0)?x:-x);  
  34. }  
提示:请进入到mysin中后,注意各变量的变化,看通项是否会收敛,从而使循环能够结束。

代码:
#include<stdio.h>
#define pi 3.1415926
double mysin(double x);
double myabs(double x);
int main()
{
    double angle;
    for(angle=0;angle<=180;angle++)
        printf("sin(%.0f°)=%.3f\n",angle,mysin((angle/180)*pi));
    return 0;
}
double mysin(double x)
{
    double sum=x,x_pow=x,item,fact=1;
    int n=1,sign=1;
    do
    {
        fact=fact*(n+1)*(n+2);
        x_pow*=x*x;
        sign=-sign;
        item=x_pow/fact*sign;
        sum+=item;
        n+=2;
    }while(myabs(item)>1e-5);
    return sum;
}
double myabs(double x)
{
    return ((x>=0)?x:-x);
}





项目二【总是多一次】
先阅读下面的程序。这样的结构,经常用于重复性工作。执行一次程序要完成的工作后,由操作人员选择,决定是否还来一遍。
[cpp]  view plain  copy
 print ?
  1. #include<stdio.h>  
  2. void dosomething(int *p);  
  3. int main( )  
  4. {  
  5.     char choice='y';  
  6.     int n=0;  
  7.     while(choice!='N' && choice!='n')  
  8.     {  
  9.         dosomething(&n);  
  10.         printf("按 N 退出,其他键继续....");  
  11.         scanf("%c", &choice); //用choice=getchar();也一样  
  12.     }  
  13.     return 0;  
  14. }  
  15.   
  16.   
  17. void dosomething(int *p) //完成特定的业务  
  18. {  
  19.     *p+=1;  //本例中传地址, *p即n  
  20.     printf("第%d次完成业务!\n", *p);  
  21. }  
阅读程序,发现在不退出时,想继续一次业务,却……,如图:
通过单步的方式,找出问题的原因,并自行查找资料,找出解决的办法。

代码:
#include<stdio.h>
void dosomething(int *p);
int main( )
{
    char choice='y';
    int n=0;
    while(choice!='N' && choice!='n')
    {
        dosomething(&n);
        printf("按 N 退出,其他键继续....");
        fflush(stdin);
        scanf("%c", &choice); //用choice=getchar();也一样
    }
    return 0;
}


void dosomething(int *p) //完成特定的业务
{
    *p+=1;  //本例中传地址, *p即n
    printf("第%d次完成业务!\n", *p);
}

运行结果:




单步查看代码的进行确实效率慢,用好断点能减少很多不必要的事情
还有例二出现的多次循环或者可能死循环的情况,在循环里加入清除键盘缓存区代码一般是可以解决的





你可能感兴趣的:(第十课 调试技术-进入函数内部去【项目1-2】)