工学第3章-程序设计初步课件_第1页
工学第3章-程序设计初步课件_第2页
工学第3章-程序设计初步课件_第3页
工学第3章-程序设计初步课件_第4页
工学第3章-程序设计初步课件_第5页
已阅读5页,还剩144页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第3章 程序设计初步3.1 面向过程的程序设计和算法 面向过程的程序设计方法不仅要求程序设计者考虑要“做什么”,还要解决“怎么做”的问题。3.1.1 算法的概念一个面向过程的程序应包括以下两方面内容:对数据的描述,即数据结构。在C+语言中,最基本的数据结构就是C+提供的基本数据类型。对数据处理的描述,即计算机算法。算法是为解决一个问题而采取的方法和步骤,是程序的灵魂。程序=算法+数据结构算法什么是算法?算法就是为解决某个问题而采取的一系列步骤。算法要解决什么问题?算法必须具体地指出在执行时每一步应当怎样做,例如程序中应该出现什么语句?语句的顺序如何安排?程序中的操作语句,就是算法的具体体现。广

2、义地说,为解决一个问题而采取的方法和步骤,就称为“算法”。如太极拳的算法、一首歌曲的乐谱。计算机算法可分为两大类别:数值算法:用于求数值解。如求方程的根。非数值算法:用于事务管理领域。如排序。把大象放冰箱里的算法,分几步?3.1.2 算法的表示自然语言例如,用自然语言表示“把大象放冰箱”的算法伪代码用介于自然语言和计算机语言之间的文字和符号来描述算法。详见P46的例子。特点没有固定、严格的语法规则不用图形符号,因此书写方便、容易修改便于向计算机语言算法过渡。广泛应用于国外的计算机教材和专业编程人员的实际编程中。用计算机语言表示算法:即程序。流程图:用图的形式表示算法,比较直观,但修改算法时很不

3、方便。流程图包括传统流程图和结构化流程图(N-S流程图)。传统流程图使用的符号:传统流程图的例子:理解它的含义开始从键盘输入数据a输出a结束a0?输出-aYN结构化流程图(N-S流程图):传统流程图由一些特定意义的图形、流程线及简要的文字说明构成,它能清晰明确地表示程序的运行过程。在使用过程中,人们发现流程线不一定是必需的,随着结构化程序设计方法的出现,1973年美国学者I.Nassi和B.Shneiderman提出了一种新的流程图形式,这种流程图完全去掉了流程线,算法的每一步都用一个矩形框来描述,把一个个矩形框按执行的次序连接起来就是一个完整的算法描述。这种流程图同两位学者名字的第一个字母来

4、命名,称为N-S流程图。只要求掌握一种流程图,传统流程图更好理解。3.2 C+程序和语句一个程序包含一个或多个程序单位(每个程序单位构成一个程序文件,如图3.1所示)。每一个程序单位由以下几个部分组成: 预处理命令。如#include命令和#define命令。声明部分。例如对数据类型和函数的声明,以及对变量的定义。函数。包括函数首部和函数体,在函数体中可以包含若干声明语句和执行语句。注意:每个程序(project)必须有一个(而且只能有一个)main函数,可以包含其他函数。C+程序结构#include /预处理命令using namespace std;/在函数之外的声明部分int a=3;/

5、在函数之外的声明部分int main( )/函数首部float b;/函数内的声明部分b=4.5;/执行语句couta0) cout x;else cout -x;函数和流对象调用语句:一次函数调用加上一个分号就构成了一个函数调用语句,如:sort(x,y,z); /假设已定义了sort函数,它有3个参数输入输出流的使用也构成一条语句,如:cout x endl;表达式语句任何一个表达式的最后加一个分号都可以成为一个语句,如:i=i+1/赋值表达式i=i+1;/赋值语句函数调用语句也可以认为是一个表达式语句空语句只有一个分号的语句,它什么也不做。有时用来做被转向点,或循环语句中的循环体。复合语

6、句用 把一些语句括起来成为复合语句注意:在复合语句中定义的局部变量的作用范围仅限于该复合语句。#include /预处理命令using namespace std;/在函数之外的声明部分int main( )/函数首部int a=5;cout 0 ) cout0 endl; 含义:先进行赋值运算(将b的值赋给a),然后判断a是否大于0,如大于0,执行cout 0 endl;3.4 C+的输入与输出C与C+的输入输出C和C+都没有专门的输入输出语句,分别是由函数和流对象来实现的。在C语言中,输入和输出是通过调用scanf和printf函数来实现的,C+中保留了这2个函数。在C+中,输入和输出是通

7、过调用输入输出流库中的流对象cin和cout实现的。也就是说输入输出不是C+本身定义的,而是在编译系统提供的I/O库中定义的。因此在使用到cin和cout的程序文件里,必须包含iostream头文件。输入输出流“流”是指来自设备或传给设备的一个数据流cout是输出流对象的名字,是流提取运算符,作用是从默认的输入设备(一般为键盘)的输入流中提取若干字节送到计算机内存中指定的变量。说明:有关流对象cin、cout和流运算符的定义等信息是存放在C+的输入输出流库中的,因此如果在程序中使用cin、cout和流运算符,就必须使用预处理命令把头文件iostream包含到本文件中:#include 为了叙述

8、方便,常常把由cin和流提取运算符“”实现输入的语句称为输入语句或cin语句,把由cout和流插入运算符“变量1变量2变量n;cout表达式1表达式2表达式n;cout语句的一般格式为cin语句的一般格式为理解流对象:在定义流对象时,系统会在内存中开辟一段缓冲区,用来暂存输入输出流的数据。在执行cout语句时,先把插入的数据顺序存放在输出缓冲区中,直到输出缓冲区满或遇到cout语句中的endl(或n,ends,flush)为止,此时将缓冲区中已有的数据一起输出,并清空缓冲区。输出流中的数据在系统默认的设备(一般为显示器)输出。一个不大贴切的比喻缓冲区、缓冲器在计算机软硬件里是一个很重要的概念。

9、使用cout进行输出的一个比喻:做生意,攒钱,不可能赚了100,就去银行存一次;要么攒够了10000,去银行存一次(对应于缓冲区满的情况);要么攒了一个月,去银行存一次(对应于cout语句中的遇到endl等就将缓冲区中已有的数据一起输出)。输出完,要清空缓冲区。(把攒的钱存入银行以后,又从0开始攒钱了)cout This is /末尾无分号 a simple C+ program.endl;/(2)最后有分号cout This is a simple C+ program. endl;/(1)一个cout语句可以分写成若干行。如:可以写成(以下各行是同一个C+语句),注意与P26比较 cout

10、cout This isa C+program.endl;功能上等效(不推荐使用)语法上等效(是同一个C+语句)cout This is a simple C+ program.endl;/(3)cout This is; /语句末尾有分号cout a simple C+ ;cout program.;coutendl;也可写成多个cout语句,以上3种情况的输出均为couta,b,c; /错误,不能一次插入多项couta+b+c; /正确,这是一个表达式,作为一项注意,不能用一个插入运算符“c1c2ab;在用cin输入时,系统也会根据变量的类型从输入流中提取相应长度的字节。如有:如果输入系统

11、会提取第一个字符1给字符变量c1,取第二个字符2给字符变量c2,再取34给整数变量a,最后取56.78给实型变量b。cin1234 56.783.4.2 在输入流与输出流中使用控制符在输入输出流中使用控制符,可以达到一些特殊的效果,如在输出实数时规定字段宽度,只保留两位小数,数据向左或向右对齐等。C+提供了在输入输出流中使用的控制符(有的书中称为操纵符),见表3.1。如果使用了控制符,在程序单位的开头除了要加iostream头文件外,还要加iomanip头文件。double a=123.456789012345;对a赋初值(1) couta;输出:123.457 (2) coutsetprec

12、ision(9)a;输出:123.456789 (3) coutsetprecision(6);恢复默认格式(精度为6)(4) cout setiosflags(ios:fixed) a;输出:123.456789(书上漏掉了)(5) coutsetiosflags(ios:fixed)setprecision(8)a;输出: 123.45678901(6) coutsetiosflags(ios:scientific)a;输出:1.234568e+02(7) coutsetiosflags(ios:scientific)setprecision(4)a; 输出: 1.2346e+02说明:第

13、(1)行按默认格式输出(以十进制小数形式输出,全部有效数字为6位)。第(2)行指定输出9位有效数字。第(3)行恢复默认格式,精度为6。第(4)行要求以固定小数位输出,默认输出6位小数。第(5)行指定输出8位小数。第(6)行指定按指数形式输出,默认给出6位小数(第7位四舍五入)。第(7)行以指数形式输出,指定4位小数。注意:在保留精度时要进行四舍五入。双精度数输出的例子:#include #include using namespace std;int main()double a=123.456789012345;/对a赋初值cout a endl; /输出:123.457(四舍五入)cout

14、 setprecision(9) a endl;/输出:123.456789cout setprecision(6);/恢复默认格式(精度为6)cout setiosflags(ios:fixed) a endl;/输出:123.456789cout setprecision(8) a endl;/输出:123.45678901cout resetiosflags(ios:fixed);/在按scientific输出之前如果使用了fixed,一定要先取消fixed,/否则无法按科学计数法形式输出。cout setiosflags(ios:scientific) a endl;/输出:1.234

15、568e+02(四舍五入)cout setiosflags(ios:scientific) setprecision(4) a endl;/输出:1.2346e+02(四舍五入)return 0;关于格式控制时有效数字的说明(在第13章还会详细讲述,初学者不必拘泥细节,这些细节也没有什么意义,只是初学者在对输出的有效数字位数感到困惑时,可以查阅这些说明)除表3.1列出的控制符外,还有一个特殊的控制符(P425,表13.3):resetiosflags(),用于终止已设置的输出格式状态,在括号中应指定要取消的格式控制符,比如:cout resetiosflags(ios:scientific);

16、 可以取消科学计数法显示浮点数。在使用setiosflags(ios:scientific)按科学计数法输出浮点数之前如果使用了setiosflags(ios:fixed),一定要先用resetioflags(ios:fixed)取消fixed,否则无法按科学计数法形式输出。对于6位有效数字,有小数点后6位有效数字与全部6位有效数字之分。那么到底在什么情况下是指小数点后的有效数字,在什么情况下是指全部有效数字呢?全部有效数字的情形:默认情况下(是指在此之前没有设置过fixed和scientific),输出6位有效数字,是指按固定小数形式输出全部6位有效数字,包括小数部分和整数部分,进行四舍五入

17、 (如果整数部分超过6位,则默认以科学计数法输出,也是全部6位有效数字) 。当然如果同时用setprecision(n)指定了有效数字的位数,则全部有效数字的位数为n。如果在输出前用resetiosflags()取消最近设置过的fixed或scientific格式,这时有效数字是指全部有效数字。如果没有用setprecision(n)指定有效数字的位数,则默认为6位,反之是n位。使用scientific输出完后,没有用resetiosflags()取消scientific,紧接着按fixed输出,也是指全部有效数字。但是在使用fixed输出完后,没有用resetiosflags()取消fixe

18、d,紧接着按scientific输出,无法按科学计数法形式输出,这时仍然是按固定小数点形式输出,而且也是指全部有效数字。小数点后有效数字的情形:第一次设置fixed格式,则按固定小数形式输出,这时有效数字是指小数点后的有效数字;如果没有用setprecision(n)指定有效数字的位数,则默认为6位,反之是n位。第一次设置scientific格式,则按科学计数法形式输出,这时有效数字是指小数点后的有效数字;如果没有用setprecision(n)指定有效数字的位数,则默认为6位,反之是n位。对比前面的第3)点,使用scientific输出完后,用resetiosflags()取消scienti

19、fic,紧接着用fixed输出,这时有效数字是指小数点后的有效数字。对比前面的第4)点,使用fixed输出完后,用resetiosflags()取消fixed,紧接着用scientific输出,这时有效数字是指小数点后的有效数字。int b=123456;对b赋初值(1) coutb;输出:123456(2) couthexb; 输出:1e240(3) coutsetiosflags(ios:uppercase)b;输出:1E240 (4) coutsetw(10)b, b; 输出: 123456,123456(5) coutsetfill(*)setw(10)b;输出:*123456(6)

20、coutsetiosflags(ios:showpos)b;输出:+123456说明:第(1)行按十进制整数形式输出。第(2)行按十六进制整数形式输出,其中字母e代表十进制中的14。第(3)行按十六进制形式输出,字母e改为大写。第(4)行指定字段宽为10,在123456前留4个空格。紧接着再输出一次b,但由于setw只对其后第一个数据起作用,因此在输出第二个b时setw(10)不起作用,按默认方式输出,前面不留空格。第(5)行在输出时用*代替空格。第(6)行在正数前面加一个+号。整数输出的例子:#include #include using namespace std;int main()in

21、t b=123456;/对b赋初值cout b endl;/输出:123456cout hex b endl;/输出:1e240 cout setiosflags(ios:uppercase) b endl;/输出:1E240 cout dec;/还原成10进制输出cout setw(10) b , b endl;/输出: 123456,123456cout setfill(*) setw(10) b endl;/输出:*123456cout setiosflags(ios:showpos) b endl;/输出:+123456return 0;#include #include using

22、namespace std;int main( ) double a=123.456,b=3.14159,c=-3214.67; coutsetiosflags(iosfixed)setiosflags(iosright)setprecision(2);coutsetw(10)aendl;coutsetw(10)bendl;coutsetw(10)cendl; return 0;如果在多个cout语句中使用相同的setw(n),并使用setiosflags(iosright),可以实现各行数据右对齐,如果指定相同的精度,可以实现上下小数点对齐。例3.1 各行小数点对齐。运行情况如下: 123.

23、46 3.14 -3214.673.4.3 用getchar和putchar函数进行字符的输入与输出除了可以用cin和cout语句输入和输出字符外,C+还保留了C语言中用于输入和输出单个字符的函数,使用很方便。其中最常用的有getchar函数和putchar函数。putchar函数(字符输出函数)putchar函数的作用是向终端输出一个字符。例如putchar(c);它输出字符变量的值。#include /或者包含头文件stdio.h: #include using namespace std;int main( )char a,b,c;a= B;b= O;c=Y;putchar(a);put

24、char(b);putchar(c);putchar(n);putchar(66);putchar(79);putchar(89);putchar(10);return 0;运行情况如下:BOYBOY用putchar可以输出转义字符putchar(n) 输出换行符putchar(66) 将66(字母B)作为ASCII码转换为字符输出putchar(10) 10是换行符的ASCII码,输出一个换行符putchar(101) 输出字符A,八进制的101是A的ASCII码putchar() 输出单引号字符putchar(015) 八进制的015是十进制的13,代表“回车”, 不换行,使输出的当前位置

25、移到本行开头getchar函数(字符输入函数) 此函数的作用是从终端(或系统隐含指定的输入设备)输入一个字符。getchar函数没有参数,其一般形式为getchar()函数的值就是从输入设备得到的字符。#include using namespace std;int main( )char c;c=getchar( ); putchar(c+32); putchar(n);return 0;运行情况如下:A a有关getchar函数的其他使用方法的描述见P5657。3.4.4 用scanf和printf函数进行输入与输出(自学)平时练习可以不用scanf和printf函数进行输入输出,但是二级

26、考试采用的是C语言,所以这两个函数还是要掌握的。在C语言中是用printf函数进行输出,用scanf函数进行输入的。C+保留了C语言的这一用法。scanf函数一般格式是:scanf(格式控制,输出表列)printf函数的一般格式是:printf(格式控制,输出表列)scanf、printf函数的缺点:必须指定输出和输入数据的类型和格式,烦琐复杂,而且容易出错。例3.4 用scanf和printf函数进行输入和输出。#include using namespace std;int main( )int a; float b; char c;/注意在变量名前要加地址运算符&scanf(%d %c

27、%f,&a,&c,&b); printf(a=%d,b=%f,c=%cn,a,b,c);/提问:请写出这两条语句的C+形式。return 0;运行情况如下:12 A 67.98(本行为输入,输入的3个数据间以空格相间)a=12,b=67.980003,c=A (本行为输出)结构化程序设计的3种基本结构(引入):1966年由Bohra和Jacopini提出顺序结构选择结构(分支结构)循环结构已经证明,由以上基本结构组成的程序能处理任何复杂的问题。3.5 顺序结构 顺序结构:从上到下顺序执行各语句,没有分支。例3.5 求一元二次方程式ax2+bx+c=0的根。a,b,c的值在运行时由键盘输入,假定

28、它们的值满足b2-4ac0。根据公式求x1,x2的算法。它可以编写出以下C+程序:/例3.5#include #include /由于程序要用到数学函数sqrt,故应包含头文件cmathusing namespace std;int main( )float a,b,c,x1,x2;cinabc;x1=(-b+sqrt(b*b-4*a*c)/(2*a);x2=(-b-sqrt(b*b-4*a*c)/(2*a);cout x1= x1endl;cout x2= x2endl;return 0;运行情况如下:4.5 8.8 2.4 x1=-0.327612x2=-1.62794开始输入a,b,c计

29、算x1,x2输出x1,x2结束把大象放冰箱里的算法也是顺序结构的,它没有判断能否把大象放进冰箱。(纯属搞笑)选择结构(分支结构)的引入例3.5是假设b2-4ac0,如果事先不知道b2-4ac是不是大于0,那么在程序中就必须判断b2-4ac是大于等于0,还是小于0,分别求出2个实根、输出“无实数解”信息。流程图如下:开始输入a,b,c计算x1,x2输出x1,x2结束b2-4ac0?输出“无实数解”YN选择结构中的条件判断要通过关系运算来实现,多个条件要通过逻辑运算来连接。3.6 关系运算与逻辑运算选择结构中的条件判断要通过关系运算来实现,多个条件要通过逻辑运算来连接。所以先看看关系运算和逻辑运算

30、C+提供if语句来实现这种条件选择。如if(amount1000) tax=0.95; else tax=0.9; pay=amount*tax; 流程可以用图3.4表示。3.6.1 关系运算和关系表达式关系运算实际上就是比较运算,将2个数据进行比较,得到判断的结果(真或假)。C+的关系运算符有(注意“=”与“=”的区别): (小于) (大于) = (大于或等于) = (等于) != (不等于) 优先级相同 (高)优先级相同 (低)关系运算符的优先级:前4种关系运算符(,)的优先级别相同,后两种也相同。前4种高于后两种。例如,“”优先于“”。而“”与“a+b等效于 c(a+b)ab=c等效于(

31、ab)=ca=bc等效于a=(bc等效于a=(bc)算术运算符 (高)关系运算符赋值运算符 (低)关系表达式用关系运算符将两个表达式连接起来的式子,称为关系表达式。关系表达式的一般形式可以表示为:表达式 关系运算符 表达式其中的“表达式”可以是算术表达式或关系表达式、逻辑表达式、赋值表达式、字符表达式。例如,下面都是合法的关系表达式:ab, a+bb+c,(a=3)(b=5), ab)(b=0”的值为“真”。在C和C+中都用数值1代表“真”,用0代表“假”。关系表达式的例子见P60。3.6.2 逻辑常量和逻辑变量C语言没有提供逻辑型数据,关系表达式的值(真或假)分别用数值1和0代表。C+增加了

32、逻辑型数据。逻辑型常量(或称布尔常量):只有两个,即false(假)和true(真)。逻辑型变量(或称布尔变量)要用类型标识符bool来定义,它的值只能是true和false之一,如:bool found, flag=false;found=true;注意:在编译系统处理逻辑型数据时,将false处理为0,将true处理为1,而不是将false和true这两个英文单词存放到内存单元中。逻辑型变量在内存中占1个字节。逻辑型数据与数值型数据逻辑型数值型与char型数据类似,既然在内存中是用一个字节来存储逻辑型数据,并且0表示false,1表示true,因此逻辑型数据可以与数值型数据进行算术运算。例

33、如假设变量btemp是逻辑型变量,它的值为false,那么:int a=2+btemp+false;/赋值后a的值为多少?总之:如果在同一个表达式中同时有逻辑型数据和数值型数据,则按如下方式进行处理(可以在图2.7中加上bool型数据,应该加在哪里?):例子: bool flag=true; int a=2+flag; int b=aflag;数值型逻辑型如果将一个非零的数值型数据(包括整型和浮点型的常量、变量)赋值给逻辑型变量,则按“真”处理。0按false处理。如:bool flag=25;另外,在条件判断中,只要表达式的值非0,就认为是true的,0认为是false的,如:int a=5

34、;int b=6;if(a-b) cout Hello endl;if(a) cout Hi endl;if(a=b-1) cout nice to meet u! b) & (xy)可写成 ab & xy(a=b) | (x=y)可写成 a=b | x=y(!a) | (ab)可写成 !a | ab! (高)算术运算符关系运算符&和|赋值运算符 (低)运算符优先级的把握原则C+提供了多达几十种运算符,各种运算符的优先级级别不一样,很繁琐,怎么把握运算符的优先级?掌握常见运算符的优先级大致顺序;如果不能确定运算符优先级的顺序,可以使用括号明确程序设计者的意图。例如:如果要表示“a5或者a5|b

35、3”时不能确定逻辑运算符“|”和关系运算符“”的优先级顺序,则可以加上括号,表示成“(a5)|(by) cout x y) cout x endl;else cout y endl;x+; /不属于if结构练习1:在例3.5的基础上,判断b2-4ac是大于等于0,还是小于0,分别求出2个实根、输出“无实数解”信息。开始输入a,b,c计算x1,x2输出x1,x2结束开始输入a,b,c计算x1,x2输出x1,x2结束b2-4ac0?输出“无实数解”YN/例3.5#include #include using namespace std;int main( )float a,b,c,x1,x2;ci

36、nabc;x1=(-b+sqrt(b*b-4*a*c)/(2*a);x2=(-b-sqrt(b*b-4*a*c)/(2*a);coutx1= x1endl;coutx2= x2endl;return 0;?/练习1#include #include using namespace std;int main( )float a,b,c,x1,x2;cinabc;float delta= b*b-4*a*c;?return 0;/练习1#include #include using namespace std;int main( )float a,b,c,x1,x2;cinabc;float de

37、lta= b*b-4*a*c;if(delta=0.0) x1=(-b+sqrt(delta)/(2*a); x2=(-b-sqrt(delta)/(2*a); cout x1= x1endl; cout x2= x2endl;else cout 无实数解 500) cost=0.15;else if(number300) cost=0.10;else if(number100) cost=0.075;else if(number50) cost=0.05;else cost=0;说明:3种形式的if语句都是由一个入口进来,经过对“表达式”的判断,分别执行相应的语句,最后归到一个共同的出口。这

38、种形式的程序结构称为选择结构。3种形式的if语句中在if后面都有一个用括号括起来的表达式,它是程序编写者要求程序判断的“条件”,一般是逻辑表达式或关系表达式(但实际上可以是任何合法的C+表达式,因为表达式都是有一个确定的值,只要它的值非0,就认为是true,否则认为是false)。第2、第3种形式的if语句中,在每个else前面有一分号,整个语句结束处有一分号。但是它们都属于同一个if语句,是在if语句中嵌套了其他语句(其中else是if语句中的子句,不能作为独立的语句单独使用,必须与if配对使用)。如:if(x0)cout x endl;elsecout -x 0)cout x endl;e

39、lsecout -x c & b+ca & c+ab) /复合语句开始s=(a+b+c)/2;area=sqrt(s*(s-a)*(s-b)*(s-c);cout area endl; /复合语句结束else cout it is not a trilateral! endl; /if语句结束/请问这个if语句实现什么功能?在复合语句中定义的变量,只在复合语句中有效。如例3.6例3.6 求三角形的面积#include #include /使用数学函数时要包含头文件cmath#include /使用I/O流控制符要包含头文件iomanipusing namespace std;int main(

40、 )double a,b,c;coutabc;if (a+bc & b+ca & c+ab) /复合语句开始double s,area; /在复合语句内定义变量s=(a+b+c)/2;area=sqrt(s*(s-a)*(s-b)*(s-c);/指定输出的数包含4位小数coutsetiosflags(ios:fixed)setprecision(4); cout area= areaendl; /复合语句结束else cout it is not a trilateral! year;if (year%4=0) if (year%100=0) if(year%400=0) cout year

41、is a leap year! endl; else cout year is not a leap year! endl; else cout year is a leap year! endl;else cout year is not a leap year! b) max=a;else max=b;max=(ab)?a:b;条件表达式。含义:如果(ab)为真,则条件表达式的值为a,否则条件表达式的值为b。条件运算符(?:):要求有3个操作数,称为三目运算符,是C+中唯一的一个三目运算符。条件的一般形式为表达式1 ? 表达式2 表达式3条件运算符的执行顺序是:先求解表达式1,若为非0(真

42、)则求解表达式2,此时表达式的值就作为整个条件表达式的值。若表达式1的值为0(假),则求解表达式3,表达式3的值就是整个条件表达式的值。例如:max=(ab)?a:b;的执行结果是将条件表达式的值赋给max。也就是将a和b二者中的大者赋给max。条件运算符优先于赋值运算符,因此上面赋值表达式的求解过程是先求解条件表达式,再将它的值赋给max。例3.7 输入一个字符,判别它是否为大写字母,如果是,将它转换成小写字母;如果不是,不转换。然后输出最后得到的字符。#include using namespace std;int main( )char ch;cinch; /判别ch是否大写字母,是则转

43、换ch=(ch= A & ch= Z)?(ch+32):ch;coutchendl;return 0;条件表达式在这个例子中要注意:1.表达字符型数据介于2个字母之间的表示方法;2.大小写字母在ASCII码表里的关系。问题二:这个条件表达式语句如果要用if语句来表达,该怎么写?3.9 多分支选择结构与switch语句if语句的第三种形式可以实现多分支,但要进行多次条件判断。switch语句是多分支选择语句,用来实现多分支选择结构。多分支选择结构的例子:学生成绩分类(90分以上为A等,8089分为B等,7079分为C等,等等)折扣的例子:购物5000元以上8折,20004999为8.5折,100

44、01999为9折,1000元以下为9.5折。switch结构的一般形式如下:switch(表达式) case 常量表达式1:语句1 case 常量表达式2:语句2 . case 常量表达式n:语句n default:语句n+1 例子:按照考试成绩的等级打印出百分制分数段switch(grade) case A : cout 85100n ; case B : cout 7084n ; case C : cout 6069n ; case D : cout 60n ; default : cout errorn ; grade是char型变量说明switch后面括号内的“表达式”,允许为任何类型

45、,但它的值必须是整型,不能是浮点型。当switch表达式的值与某一个case子句中的常量表达式的值相匹配时,就执行此case子句中的内嵌语句,若所有的case子句中的常量表达式的值都不能与switch表达式的值匹配,就执行default子句的内嵌语句。每一个case表达式的值必须互不相同,否则就会出现互相矛盾的现象(对表达式的同一个值,有两种或多种执行方案)。各个case和default的出现次序不影响执行结果。执行完一个case子句后,流程控制转移到下一个case子句继续执行。“case常量表达式”只是起语句标号作用,并不是在该处进行条件判断。在执行switch语句时,根据switch表达式

46、的值找到与之匹配的case子句,就从此case子句开始执行下去,不再进行判断。例子:按照考试成绩的等级打印出百分制分数段switch(grade) case A : cout 85100n ; case B : cout 7084n ; case C : cout 6069n ; case D : cout 60n ; default : cout errorn ; 若grade的值等于A ,则将连续输出:851007084606960error显然,这并不是程序员的意图。因此,应该在执行一个case子句后,使流程跳出switch结构,即终止switch语句的执行。可以用一个break语句来达

47、到此目的。将上面的switch结构改写如下:switch(grade) case A : cout 85100n ;break; case B : cout 7084n ;break; case C : cout 6069n ;break; case D : cout 60n ;break; default : cout errorn ;break; 加了break语句后switch结构的流程图:在case子句中虽然包含一个以上执行语句,但可以不必用花括号括起来,会自动顺序执行本case子句中所有的执行语句。多个case可以共用一组执行语句,如.case A : case B : case C

48、 : cout60n ;break;.当grade的值为A 、 B或C时都执行同一组语句。3.10 编写选择结构的程序例3.8编写程序,判断某一年是否为闰年。思路分析如下:年份从键盘输入,保存到变量year中,要用到cin语句。用布尔变量leap表示被测试的年份是否是闰年的信息。利用P63所学的方法判断年份是否是闰年,若是闰年,则令leap=ture(而不是马上输出“是闰年”的信息);若非闰年,则令leap=false。最后判断leap是否为真,若是,则输出“闰年”信息。不能被4整除能否被100整除能否被400整除能被100整除,但不能被400整除能被400整除能被4整除,但不能被100整除能

49、否被4整除#include using namespace std;int main( )int year;bool leap;coutyear;/输入年份if (year%4=0)/年份能被4整除if(year%100=0)/又能被100整除if (year%400=0) leap=true; /又能被400整除,是闰年else leap=false;/非闰年 else leap=true;/年份能被4整除但不能被100整除肯定是闰年else leap=false; /年份不能被4整除肯定不是闰年if (leap)coutyear is ;/若leap为真,就输出年份和“是”else cou

50、tyear is not ; /leap为假,输出年份和“不是”cout a leap year. endl; /闰年return 0;练习:将该if结构改成其他等效的if结构例3.9 运输公司对用户计算运费。路程(s)越远,每公里运费越低。标准如下:s250km没有折扣250s5002折扣500s1000 5折扣1000s20008折扣2000s300010折扣3000s15折扣分析:设每公里每吨货物的运费为p(price的缩写),货物重为w(weight的缩写),距离为s,折扣为d(discount的缩写),则总运费f(freight的缩写)的计算公式为 f = w * s * p * (

51、1 - d)折扣的规律如下图所示:折扣的“变化点”都是250的倍数(250,500,1000,2000,3000)。利用这一特点,可以在横轴上加一种坐标c,c的值是s/250。c代表250的倍数。当c1时,表示s250,无折扣;1=c2时,折扣d=2%,等等。#include using namespace std;int main( )int c,s;/s:路程float p,w,d,f; /p:每公里每吨货物的运费, w:货物重量, d:折扣, f:总运费coutpws;if(s=3000) c=12;else c=s/250;switch (c)case 0:d=0;break;case

52、 1:d=2;break;case 2:case 3:d=5;break;case 4:使用switch语句关键在于如何构造括号内的表达式case 5:case 6:case 7:d=8;break;case 8:case 9:case 10:case 11:d=10;break;case 12:d=15;break;f=p*w*s*(1-d/100.0);cout freight= fendl;return 0;运行情况如下:please enter p,w,s:100 20 300freight=588000如何构造switch语句中的表达式首先注意switch语句的格式。switch括号

53、后面的表达式的值必须是整数,case后面的常量表达式的值也必须是整数。假设输入的百分制成绩保存在变量score里。请问:能不能直接把score放到switch后面的括号里?例子:输入百分制的成绩(范围在0100之间,允许有1位小数,如72.5分),要求输出对应的五分制成绩,90.0100分为A,80.089.9为B, 70.079.9为C, 60.069.9为D,60分以下为E。switch结构的一般形式如下:switch(表达式)case 常量表达式1:语句1case 常量表达式2:语句2.case 常量表达式n:语句ndefault:语句n+1其次,要尽量减少switch语句中的case分

54、支。即使把score取整,符合switch语句的要求,如果直接对得到的整数进行判断:100分为A,99分为A,1分为E,0分为E。结果有101个case分支,这显然是不现实的。请问:该如何处理?请问:是否还能减少case分支,而不影响程序功能?switch( (int)score )case 100:cout A; break;case 99: cout A; break;.case 1: cout E; break;case 0: cout E; break;练习题:请完成该程序。3.11 循环结构与循环语句循环结构的引入当需要反复执行某一操作的情况,就需要用到循环控制。比如:判断一个自然数

55、N是不是素数,要依次判断从2到sqrt(N)中的每一个数能否整除N(只要找到一个能整除N的数,就不需要再判断下去了)。要判断100200之间素数的个数,就需要对100200之间的每个数做判断。比如求1+2+3+100,需要反复累加1100之间的每个数。C+提供了3种循环:while循环do-while循环for循环3.11.1 While循环while语句的一般形式如下:while (表达式) 语句其作用是: 当指定的条件为真(表达式为非0)时,执行while语句中的内嵌语句。其流程图见图3.9。其特点是:先判断表达式,当表达式的值为true时执行语句,执行完再判断,如此,直到表达式所表示的条

56、件不成立为止。while循环称为当型循环(当条件成立的时候执行循环)。注意:表达式可以是逻辑型常量、变量,关系表达式,逻辑表达式,实际上这个表达式可以是任何合法的C+表达式,只要表达式的值是非0的,就认为是真,表达式的值为0,则认为是假。例3.10 求1+2+3+100。#include using namespace std;int main( )int i=1,sum=0;while (i=100)sum=sum+i;i+;cout sum= sumendl;return 0;运行情况如下:sum=5050这个i通常称为循环变量通常在while条件里判断循环变量是否超过终值。在循环体内修改

57、循环变量。#include using namespace std;int main( )int i=1,sum=0;while (i=100)/sum=sum+i;/循环体语句i+;/循环体外的语句/cout sum= sumendl;return 0;注意:循环体如果包含一个以上的语句,应该用花括号括起来,以复合语句形式出现。如果不加花括号,则while语句的范围只到while后面第一个分号处。在循环体中应有使循环趋向于结束的语句。否则就会陷入死循环:循环永不停止地执行。比如:#include using namespace std;int main( )int i=1,sum=0;whi

58、le (i=100)sum=sum+i;cout sum= sumendl;return 0;这个条件永远满足,循环体永不停息地执行,进入死循环。练习2:求A!,用while循环实现(A由键盘输入)。A!=1 2 (A-2)(A-1)A 分析:循环变量i从1递增到A,用变量F来保存阶乘,只要在每次循环的时候乘以循环变量i,那么循环完毕,F的结果就是12 (A-2)(A-1)A= A!F=F*i;i=i+1;i=A?NYi=1F1从键盘输入A/练习2#include using namespace std;int main( )int A;int i=1,F=1;cin A;while (i=A

59、)F=F*i;i+;cout A!= Fendl;return 0;运行情况如下:5 (用户输入)A!=120问题三:在循环体内把循环变量累乘起来,得到A的阶乘。如果在循环体内把循环变量i的终值(也就是A)累乘起来,结果是什么?while (i=A)F=F*A;i+;Answer :得到的结果是AA,如果输入5,得到的结果是3125=55。(是乘以循环变量还是终值,这一点在多重循环里很容易弄混淆)do-while循环的引入假定开学初家里往你的帐号上存一定金额,每月花费800,每月只在月初取出钱,假定不可以透支。问可以取多少次?取钱的两种习惯:先查看余额,如果余额大于800,则当前可以取钱,重复

60、执行直到余额小于800为止。(while循环)先取出800,然后查看余额,如果余额大于800,则重复执行直到余额小于800为止。(do-while循环)3.11.2 do-while循环do-while语句的特点是先执行循环体,然后判断循环条件是否成立。其一般形式为:do 语句while (表达式); /注意这里要加分号它是这样执行的:先执行一次指定的语句(即循环体),然后判别表达式,当表达式的值为非零(“真”) 时,返回重新执行循环体语句,如此反复,直到表达式的值等于0为止,此时循环结束。例3.11 用do-while语句求1+2+3+100。#include using namespace

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论