课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,实践要求见http://blog.csdn.net/sxhelijian/article/details/39493833。
课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。
【项目3:多分段函数求值】
从键盘输入x的值(要求为实型),根据下面的公式计算并输出y的值。
(1)请用if~else~语句的嵌套,实现这个多分支的程序;
参考解答:
//解法1 #include<iostream> #include<cmath> using namespace std; int main( ) { double x, y; cin>>x; if (x<2) y=x; else if(x<6) //此处已经自然满足x>=2的条件 y=x*x+1; else if(x<10) y=sqrt(x+1); else //自然是x>=10的时候执行下一语句 y=1/(x+1); cout<<y<<endl; return 0; }
//解法2 #include<iostream> #include<cmath> using namespace std; int main( ) { double x, y; cin>>x; if (x<2) y=x; if(x>=2 && x<6) y=x*x+1; if(x>=6 && x<10) y=sqrt(x+1); if(x>=10) y=1/(x+1); cout<<y<<endl; return 0; }
这个解法不能算错,但是不好,它会让计算机多“做”一些事情。例如,当输入x的值为1时,解法1只需要进行一次判断,直接求值即可,而当输入x的值为8时,解法1也只需要进行3次判断。但对于解法2,无论输入是多少,4次判断都少不了。
这是涉及“效率”的问题,可能在此处无关大碍,但专业人员对程序评价是,正确是底线,接下来就要关注效率。
充分用好else分支,显然程序更易懂一些,要习惯于用这种写法。
再一个需要强调并于条件的写法。以(x>=2 && x<6)为例,有人会写成(2=<x<6),这时,编译器会提示错误,由此改正尚不至于造成严重后果。而将同样的条件,有人写成(6>x>=2)时,不会有编译错误,但更大的风险却隐藏其中。例如x=4时,
- (x>=2 && x<6)的值为真(1):(x>=2)和(x<6)同时为真,故为真;
- (6>x>=2)的值为假(0):为假为原因是,6>4为真(1),故表达式相当于(1>=2);
- 事实上,由于(6>x)的取值只能是0或1,无论x取值多少,(6>x>=2)永远为假。
将表示判断的表达式写好,事关正确性与效率。
//解法3
#include<iostream> #include<cmath> using namespace std; int main( ) { double x, y; cin>>x; if (x<2) y=x; if(x>=2 && x<6) y=x*x+1; if(x>=6 && x<10) y=sqrt(x+1); else y=1/(x+1); cout<<y<<endl; return 0; }
这个写法中,终于在第15行用了一个else。看似用上了双分支是好事,这个程序却是完全错误的。输入0或4运行一下,就会发现错误了。而分析程序,确实只要(x>=6 && x<10)为假,即使x<6已经在前面给y赋过值,else分支仍然要执行,y将被重新赋值,由此产生错误!
(2)请用switch语句构造多分支结构,完成求解。
解法1:各分段的标准都为2的倍数,所以,构造表达式 t= x/2,根据t的取值决定switch分支;
#include<iostream> #include<cmath> using namespace std; int main( ) { int x, y, a; cin>>x; a = x/2; //注意是整数相除 if (a<0) a=0; //这样,x<0时,a值也是0 switch(a) { case 0: //即x<2时 y=x; break; case 1: case 2://a为1、2,对应x>=2 && x<6时 y=x*x+1; break; case 3: case 4://a为3、4,对应x>=6 && x<10时 y=-x; break; default://如果走到这一分支,对应的是x>=10的所有情况 y=-x*x-1; } cout<<y<<endl; return 0; }
解法2:构造表达式 t=(x<2) + (x<6) + (x<10)。由于关系表达式(x<a)的值为0或1(真为1,假为0),所以t能表示x究竟满足了几个条件。t值为3时,相加的三个关系表达式全为真,对应x<2;而t值为0时,相加的三个关系表达式全为假,对应x≥10,其他类似。根据t的取值,可以决定switch分支。
#include<iostream> #include<cmath> using namespace std; int main( ) { int x, y, t; cin>>x; t = (x<2) + (x<6) + (x<10); //括号中的关系表达式有几个为真(1),确定了t的值,实则反映的是x的范围 switch(t) { case 3: //(x<2) 、 (x<6) 、 (x<10) 全部为真,自然x<2 y=x; break; case 2: //(x<2) 、 (x<6) 、 (x<10) 为真有2,自然x>=2,且x<6 y=x*x+1; break; case 1: //(x<2) 、 (x<6) 、 (x<10) 为真有1,自然…… y=-x; break; case 0://只有(x<2) 、 (x<6) 、 (x<10) 全0了.也可写作default: y=-x*x-1; } cout<<y<<endl; return 0; }
=================== 迂者 贺利坚 CSDN博客专栏================= |== IT学子成长指导专栏 专栏文章的分类目录(不定期更新) ==| |== C++ 课堂在线专栏 贺利坚课程教学链接(分课程年级) ==| |== 我写的书——《逆袭大学——传给IT学子的正能量》 ==| ===== 为IT菜鸟起飞铺跑道,和学生一起享受快乐和激情的大学 ===== |