第十课 调试技术-进入函数内部去【项目1-2】
2016-04-09 03:26
459 查看
项目十 调试技术-进入函数内部去
项目一【sin泰勒展式中的错误】
下面是sin函数的泰勒展式:
![](https://img-blog.csdn.net/20141102090839601)
(注:x取弧度值,而非角度值)
编写了double mysin(double x)用于求sin值,却“死”在了123°上。剧透一下,循环没有问题(当然问题会表现在循环中)。试着用调试工具找出问题出现在哪里,然后给出解决问题的方案。
[cpp] view
plain copy
print?
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
#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;
}
//下面定义mysin函数,求sin值
double mysin(double x)
{
double sum=x,x_pow=x,item;
int n=1,fact=1, sign=1; //定义变量时赋初值,已经将第一项考虑到累加和sum中
do
{
fact=fact*(n+1)*(n+2); //fact用于表示阶乘,在公式中作分母
x_pow*=x*x; //x_pow是分子中用于表示阶乘,在公式中作分母
sign=-sign; //确定即将要累加的这一项的符号
item =x_pow/fact*sign; //计算出要累加的项
sum+=item; //将该项累加上去
n+=2;
}while(myabs(item)>1e-5);
return sum;
}
//下面定义myabs函数
double myabs(double x)
{
return ((x>=0)?x:-x);
}
提示:请进入到mysin中后,注意各变量的变化,看通项是否会收敛,从而使循环能够结束。
代码:
项目二【总是多一次】
先阅读下面的程序。这样的结构,经常用于重复性工作。执行一次程序要完成的工作后,由操作人员选择,决定是否还来一遍。
[cpp] view
plain copy
print?
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
#include<stdio.h>
void dosomething(int *p);
int main( )
{
char choice='y';
int n=0;
while(choice!='N' && choice!='n')
{
dosomething(&n);
printf("按 N 退出,其他键继续....");
scanf("%c", &choice); //用choice=getchar();也一样
}
return 0;
}
void dosomething(int *p) //完成特定的业务
{
*p+=1; //本例中传地址, *p即n
printf("第%d次完成业务!\n", *p);
}
阅读程序,发现在不退出时,想继续一次业务,却……,如图:
通过单步的方式,找出问题的原因,并自行查找资料,找出解决的办法。
代码:
运行结果:
![](https://img-blog.csdn.net/20160305103531759)
单步查看代码的进行确实效率慢,用好断点能减少很多不必要的事情
还有例二出现的多次循环或者可能死循环的情况,在循环里加入清除键盘缓存区代码一般是可以解决的
项目一【sin泰勒展式中的错误】
下面是sin函数的泰勒展式:
(注:x取弧度值,而非角度值)
编写了double mysin(double x)用于求sin值,却“死”在了123°上。剧透一下,循环没有问题(当然问题会表现在循环中)。试着用调试工具找出问题出现在哪里,然后给出解决问题的方案。
[cpp] view
plain copy
print?
![](https://code.csdn.net/assets/CODE_ico.png)
#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;
}
//下面定义mysin函数,求sin值
double mysin(double x)
{
double sum=x,x_pow=x,item;
int n=1,fact=1, sign=1; //定义变量时赋初值,已经将第一项考虑到累加和sum中
do
{
fact=fact*(n+1)*(n+2); //fact用于表示阶乘,在公式中作分母
x_pow*=x*x; //x_pow是分子中用于表示阶乘,在公式中作分母
sign=-sign; //确定即将要累加的这一项的符号
item =x_pow/fact*sign; //计算出要累加的项
sum+=item; //将该项累加上去
n+=2;
}while(myabs(item)>1e-5);
return sum;
}
//下面定义myabs函数
double myabs(double x)
{
return ((x>=0)?x:-x);
}
提示:请进入到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?
![](https://code.csdn.net/assets/CODE_ico.png)
#include<stdio.h>
void dosomething(int *p);
int main( )
{
char choice='y';
int n=0;
while(choice!='N' && choice!='n')
{
dosomething(&n);
printf("按 N 退出,其他键继续....");
scanf("%c", &choice); //用choice=getchar();也一样
}
return 0;
}
void dosomething(int *p) //完成特定的业务
{
*p+=1; //本例中传地址, *p即n
printf("第%d次完成业务!\n", *p);
}
阅读程序,发现在不退出时,想继续一次业务,却……,如图:
通过单步的方式,找出问题的原因,并自行查找资料,找出解决的办法。
代码:
#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); }
运行结果:
单步查看代码的进行确实效率慢,用好断点能减少很多不必要的事情
还有例二出现的多次循环或者可能死循环的情况,在循环里加入清除键盘缓存区代码一般是可以解决的
相关文章推荐
- java中把对象、对象bean、list集合、对象数组、Map和Set以及字符串转换成Json
- 第七课 函数的嵌套调用【项目1-4】
- ##c提高篇## 第二课 体验函数【项目1-7】
- (2012-04-03 老物搬运)初识Robotlegs
- 【JQuery】右键菜单插件——contextmenu
- python多线程之Queue
- 推荐系统之矩阵分解
- 几种常见的排序算法
- yacc和lex的林林总总
- JavaScript 中的undefined and null 学习
- 求任意大小矩阵两点之间的最短路径(回溯)
- (2012-02-03 老物搬运)去除图片热区焦点框
- (2012-01-14 老物搬运)N1真题 错题汇总2
- 一些教训,或者叫做收获
- (2012-01-08 旧博文搬运)[EssentialActionScript3.0中文版]无责任翻译-23章屏幕更新(2)
- (2012-01-08 旧博文搬运)[EssentialActionScript3.0中文版]无责任翻译-22章交互性(4)
- (2012-01-08 旧博文搬运)[EssentialActionScript3.0中文版]无责任翻译-22章交互性(3)
- 给定两个有序数组,找出合并之后的数组中位数
- (2012-01-08 旧博文搬运)[EssentialActionScript3.0中文版]无责任翻译-22章交互性(1)
- (2012-01-08 旧博文搬运)[EssentialActionScript3.0中文版]无责任翻译-21章事件与显示层级(5)