Download presentation
Presentation is loading. Please wait.
1
第三章 C++的语句和简单的程序设计 主要内容:
程序结构——顺序、选择、重复三大结构; C++的各种语句(语法、语义、用例); 程序设计风格、方法与技巧。
2
重点: 程序结构 if语句 各种循环语句 注意:本章的内容重在程序设计实践。 课堂时数:10—12学时 上机时数:4学时
课外上机时数:4学时
3
3.1 程序结构 程序结构与程序设计方法有关,这里先讨论结构化方法的三种结构,即顺序结构、选择结构和重复结构(循环结构)。在本课程的后半部分,我们再讨论面向对象结构。 有必要说明的是,即使是采用面向对象方法,类的各个操作的方法代码也离不开上述三种基本结构。因此结构化程序的三种基本结构十分重要,而且贯穿始终。
4
n条语句自上而下排列,并按排列的顺序自上往下逐条执行。其结构示意图如下:
1.顺序结构 n条语句自上而下排列,并按排列的顺序自上往下逐条执行。其结构示意图如下: 结构图: 执行顺序 : 下面程序块就是 一个典型的顺序结 构: int a; cin >> a; cout <<a; Statement1; Statement2; …… statement n; 2.选择结构 结构中包含多个不同的执行部分(分支),结构控制能够根据特定条件的判断来选择程序所要执行的分支。
5
通常用if语句或swith语句来实现选择结构,请看下面的例子。
例3-1 编写一个程序,计算: x<0 y= 1 x>=0 #include <iostream.h> #include <iomanip.h> void main() main() { int x,y; cin >> x; if (x<0) y=0; else y=1; cout <<”y=”<<y<<endl; } 由if语句实现的选择结构。
6
3. 重复结构 结构图(N-S图) t f S1,S2:语句集(包含一至多个语句), S1 S2 当条件为真选择并执行s1,否则选择并
Exp:选择分支的条件(表达式) Exp t f S S2 S1,S2:语句集(包含一至多个语句), 当条件为真选择并执行s1,否则选择并 执行s2。 3. 重复结构 在许多应用中,经常会出现动作或运算的重复执行,例如: (1)计算 s= …….100,这是一个重复执行 99次加法的算术问题。 (2)比较两个字符串的大小,重复地进行字符比较。
7
几乎所有的程序语言都提供循环语句,用以构造重复结构,从而可以避免大量语句或表达式的的重复书写。C++也不例外,请看下面的例子:
例3-2 编写一个程序计算s= …….100。 程序如下: main() { int i=1,s=0; while(i<100) s=s+i; i=i+1; } 控制括号内的两个语句重复执行100次 重复执行部分,也称为循环体。 这是一种用“当型”循环语句来构造的重复结构,此外也可以 用“直到型”循环语句来构造重复结构。
8
C++的语句十分精简,只设置9个语句,以及由多个语句构成的复合语句。
结构图: “ 当型”循环 “ 直到型”循环 exp s s exp 语句集,也即程序的重复执行部分,也称为循环体。 表达式:用来作为循环条件 3.2 C++的语句概述 C++的语句十分精简,只设置9个语句,以及由多个语句构成的复合语句。 9个语句中,以控制语句为主。目的在于实现上述的三种程序结构。下面按类别概要地介绍主要的语句。
9
1. C++的控制语句 C++的控制语句包括:if语句 、swich语句、各种循环语句 ,其它控制语句等。 选择结构类语句 if语句
Switch语句 for语句 C++的控制语句 循环语句 while语句 do while语句 goto语句 其它控制语句 break语句 continue语句
10
一般用在if语句的分支中,表示该分支为空。
2. 空语句 一般用在if语句的分支中,表示该分支为空。 ; 3.复合语句 由多个语句组成,必须用花括号({})包围。一般构成if语句的分支或循环语句的循环体。 例如: while(i<100) { s=s+i; i=i+1; } //构成循环体的复合语句
11
返回函数(return)调用——返回语句
4.表达式语句 C和C++有一个显著特点是有些表达式可以独立地出现在语句行上,当作语句使用,故称为表达式语句。 下面给出一些表达式语句的例子: 例3-3 下面表达式或函数调用是作为语句使用的: cin >> b >> c; a = b*c; return(); 输入流控制表达式——输入语句; 赋值表达式——赋值表达式语句; 返回函数(return)调用——返回语句
12
if语句也称为条件语句,属于控制类语句,是程序设计中经常使用的语句。可以说几乎每种高级语言都提供if语句,可见其重要性和应用的广泛性。
1. 示例 我们通过下面一个有关if语句的实际应用来初步认识if语句。 例3-4 设以60分作为考试的合格线,如果考试成绩60及 60分以上为合格,否则不合格。这个极为简单的问题实际 包含着逻辑运算、判断和选择。用if语句可以准确地予以 描述:
13
2. if语句的作用 3. if语句的语法 if (grade>=60) cout << "考试合格\n"; else
//成绩大于等于60分 //成绩小于60分 2. if语句的作用 构造选择结构,用来实现程序分支的选择与执行。 3. if语句的语法 (1) if (exp) statement;
14
(2) if (exp) statement1; else statement2; 表达式,作为条件 语句,作为执行分支 if语句语法的解释: (1)exp:表达式,通常是关系表达式或逻辑表达式,偶而也可以用算术表达式,或其它表达式。其运算结果(0或非0)作为分支的选择条件。 例如:if (grade>=60) 其中的grade>=60是关系表达式。 可以描述比较简单的条件。 (2) statement:语句,可以是C++的任何语句,构成if语句的执行分支。statement1是条件成立时应选择的分支,statement2是条件不成立时应选择的分支。
15
注意: (1) 语法(1)不包含条件不成立时的分支,可以看出它是语 法(2)的特例。如果将语法(2)改为如下格式 ,即可涵盖语 法(1)。
if (exp) statement1; [else statement2; ]; else子句为任选部分! (2) 单个if语句(不含嵌套)最多只能设置两个分支,并且 每次执行时,二者只能选其一; (3) 分支可以仅为单个语句,也可以由多个语句构成。如 果一个分支包含多个语句,必须表示为复合语句。
16
下面给出两个if语句的应用实例: 例3-4:从a,b两个数中挑选值最大者。 if (a>b) max = a; else
max = b; 注意:该if语句的两个分支 都是简单语句。 //a大于b //a小于等于b 例3-5:如果a比b大则a,b互相交换。 if (a>b) { temp=a; a=b; b=temp }; 注意:该if语句的分支是复 合语句。 问题:为什么要使用temp 变量?
17
我们通过分析if语句的执行过程来阐述语句的语义。语义描述可以是文字形式,也可以是框图形式(流程图)。
4. 语义 我们通过分析if语句的执行过程来阐述语句的语义。语义描述可以是文字形式,也可以是框图形式(流程图)。 if语句的语义用文字形式描述如下: 当表达式的值等于0则条件不成立,反之成立。 (1)计算exp; (2)如果exp的值为真(≠0),也即条件成立,则执行 statement1,否则执行statement2。 我们都知道用文字来描述语义或算法尤其是复杂算法,不但烦琐而且可能会显得不够清晰、不够准确,甚至会出现歧义性。所以通常用流程图或N-S图来描述较为复杂的语义和算法。
18
if语句的语义用流程图和N-S图 描述如下:
exp statement1 statement2 exp t f statement1 statement2 N-S图是一种改进的流程图。 例3-5 输入一个字符,判断该字符是否为小写字母,若是 则将其转换为大写字母然后输出,否则原样输出。 分析: (1)小写字母:‘a’<=ch<=‘z’ (2)小写字母转换成大写:ch-32
19
#include <iostream.h> void main() { char ch;
程序: #include <iostream.h> void main() { char ch; cout << "请输入字符:\n"; cin >> ch1; if (ch1>='a' && ch1<='z') cout << ch-32 << endl; else cout << ch << endl; } //输入要转换的字符 //判断是否为小写字母 //将小写字母转换成大写字母 并输出
20
if语句中的statement1或statement2部分出现另一个或另一些if语句。这就构成if语句的嵌套,也称为多重if语句。
if语句的的statement2中出现新的if语句称为后嵌套 。 后嵌套多重if语句应用十分广泛,请看下面的例子:
21
例3-6 男性并且年龄45岁以下视为合格,女性并且年龄40
岁以下视为合格。 if (sex='m' && age <=45) cout << "合格——男性!\n"; else if (sex='f' && age <=40) cout << "合格——女性!\n"; 该if语句出现在另一个if语句的else子句中。 问题:如果此处少掉if语句,会出现什么样的结果? 后嵌套多重if语句的一般形式: if s1 else if s21 else s22。 S2
22
(1)s21和s22仍可以包含if语句,依此类推,形成三重、四重乃至n重嵌套。
注意: (1)s21和s22仍可以包含if语句,依此类推,形成三重、四重乃至n重嵌套。 (2)就if语句的后嵌套结构而言,每一个if总是可以唯一地配对一个else,所以不存在配对的歧义性问题,因此是一种“好的结构”。 2) 前嵌套多重if语句及嵌套的歧义性问题 if语句的的statement1中出现新的if语句称为前嵌套 。 前嵌套多重if语句的一般形式: if if s11 else s12 else s2。 S1
23
(1)if 部分(statement1)包含着另一个if语句,属于前嵌套形。
例3-7 我们把例3-6的挑选条件改为,男性且45岁以下, 女性不限制年龄。试问以下的程序段正确否? if (sex=='m') if (age <=45) cout << "合格——男性!\n"; else cout << "合格——女性!\n"; 分析: (1)if 部分(statement1)包含着另一个if语句,属于前嵌套形。 (2)进一步观察可以看出:语句中,当if和else的个数不等时,if和else有下面两种匹配方式:
24
显然前嵌套多重if语句存在着if与else配对上的不确定性(歧义性)。也即语句中的else可能与第一个if配对,也可能与第二个 if配对。
方式1: if if s11 else s12; if (age <=45) cout << "合格——男性!\n"; else cout << "合格——女性!\n"; s1 方式2: if if s11 else s2; if (age <=45) cout << "合格——男性!\n"; s1 显然前嵌套多重if语句存在着if与else配对上的不确定性(歧义性)。也即语句中的else可能与第一个if配对,也可能与第二个 if配对。 如果是第二种配对方式,则结果是 正确的,为什么? 如果是第一种配对方式,则结果是 错误的,为什么? 请自己画出两种配对法对应的流程图,并加以分析 。
25
3)解决嵌套if语句的二义性 方法1. 采用“最近匹配”原则
方法1. 采用“最近匹配”原则 所谓“最近匹配原则”是指,在前嵌套的if语句中,尚未配对的else子句总是与其左端距离最近的一个if配对。 例3-8 请按“最近匹配原则”给下面的前嵌套if语句进行if和 else的配对: if exp1 if exp2 if exp3 s1 else if exp4 s2 else s3 else s4。 1 2 3 可见:匹配顺序是由里向外,自左向右的。
26
用分层“锯齿”格式来表达将会使多重嵌套层次结构更
为清晰: if exp1 if exp2 if exp3 s1; else if exp4 s2 s3; s4;
27
如同圆括号可以强制改变算符优先级,花括号则可以改变多重嵌套if语句的缺省的“最近匹配”规则。
方法2. 用花括号来强制配对 如同圆括号可以强制改变算符优先级,花括号则可以改变多重嵌套if语句的缺省的“最近匹配”规则。 例3-9 我们在例3-7所给的程序的第一个if中插入一对花括 号,则程序改为: if (sex='m') if (age <=45) cout << "合格——男性!\n"; else cout << "合格——女性!\n"; 因为加了一对花括 号,等于限制了括 号中的if语句是没有 else的,所以仅有的 一个else就必须与第 一个if配对。这就取 代了“最近匹配”规则 { }
28
注意:if语句的前嵌套存在着if与else配对的二义性问题,所以不是“好结构”,建议尽量少用前嵌套,多用后嵌套。养成良好的程序设计风格。
例3-10 输入一个百分制成绩(1——100分),将其转换成 五级记分制成绩。 (1)问题分析:百分制与五分制存在如下的对应关系:
29
解决方法也就是所谓算法,有多种算法描述工具,例如自然语言、流程图、类程序语言等等。这里我们使用流程图来描述:
百分制成绩 五级记分制成绩 < E D C B A (2)问题的解决方法 解决方法也就是所谓算法,有多种算法描述工具,例如自然语言、流程图、类程序语言等等。这里我们使用流程图来描述:
31
(3)程序 #include <iostream.h> void main() { int grade;
cout << "请输入百分制成绩:\n"; cin >> grade; if (grade<60) cout << "五分制成绩为:E" << endl; else if (grade>=60 && grade <=69) cout << "五分制成绩为: D" << endl;
32
事实上本例所涉及的问题属于多分支问题,用下面将要讨论的Switch语句来实现会更方便、更直观。也即程序结构更为合理。
if (grade>=70 && grade <=79) cout << "五分制成绩为: C" << endl; else if (grade>=80 && grade <=89) cout << "五分制成绩为: B" << endl; else cout << "五分制成绩为: A" << endl; } 问题:if语句嵌套过深,导致程序结构不够清晰,易读性较差。 事实上本例所涉及的问题属于多分支问题,用下面将要讨论的Switch语句来实现会更方便、更直观。也即程序结构更为合理。
33
3.3 switch语句 1.问题的提出 例3-10所涉及的问题是一个多分支程序设计问题,如何使得多分支结构更为清晰、程序设计语言提供什么样的支持了?请看下面的例子: 例3-11 用switch语句来实现例3-10所给的问题。 分析 例3-10提出的问题属于多分支问题,如果我们将百分 制成绩除以10,在60——100这一分数段内,我们可以每十 分一段,得到五个顺序的整数值:6,7,8,9,10,也称为开关 值,它们代表五个分支。而成绩小于60分则笼统地视为E 等,是开关的一种例外。因此百分制和五分制的关系如下:
34
(2)程序 我们用switch语句来实现之: 百分制成绩 五级记分制成绩 成绩/10 <60 E 1-5 60-69 D 6
百分制成绩 五级记分制成绩 成绩/10 < E D C B A A 显然,表达式“成绩/10”把一个数值范围转换成 单个值——开关点,这是问题的关键所在。 (2)程序 我们用switch语句来实现之:
35
#include <iostream.h>
void main() { int grade,s; cout << "请输入百分制成绩:\n"; cin >> grade; s=grade/10; if (s<6) cout << "五分制成绩为:E" << endl; else //grade<60
36
switch (s) { case 6: cout << "五分制成绩为: D" << endl; break; case 7: cout << "五分制成绩为: C" << endl; break; case 8: cout << "五分制成绩为: B" << endl; break; case 9: case 10: cout << "五分制成绩为: A" << endl; break; default cout << "输入的百分制成绩有误!" << endl; } // 60<=grade<70 // 70<=grade<80 //80<=grade<90 //90<=grade<=100
37
关于程序的解释: 2. switch语句的作用 3. Switch语句的语法
(1) case 6:— case 10:分别代表分数段为60~100内的5个分支。Default表示预想之外的分支,此处即为成绩输入错误所引发。 (2)Break是一个语句,用来跳过switch语句中该语句所在的分支以下的所有分支,转入switch语句的下一语句,也即结束Switch语句的执行。 2. switch语句的作用 用来构造多分支的选择结构,以实现多分支的选择与执行。 3. Switch语句的语法 其格式如下所示:
38
switch (exp) 解释: { case constant-exp1: statements1;
…… case constant-expn: statementsn; [default: statementn+1;] } 解释: Exp:表达式,也称为开关表达式,其运算结果为:整型、字符型和枚举类型。这样方可作为开关值。 Constant-exp:常量表达式(通常为单个常量)。Switch语句中包含n个常量表达式,与Case一起作为n组分支的标号。 Statements:语句组,实际上就是switch语句的具体的分支部分,可以由一个到多个语句组成,这些语句可以是if语句、switch语句等。当语句组中出现新的switch语句,称为switch的嵌套。 Default:代表缺省分支(第n+1个分支),是对开关表达式取值超出正常取值范围的一种特殊处理。
39
常量表达式的值必须在开关表达式的取值范围内,并且同一个switch语句中的n个常量表达式的值不能相同。
注意: 常量表达式的值必须在开关表达式的取值范围内,并且同一个switch语句中的n个常量表达式的值不能相同。 例如:例3-11所给程序中的Switch语句的各个常量表达式 分别为6,7,8,9,10均在开关表达式gread/10的取值范 围内。 switch语句中最多包含n+1个语句组,作为n+1个可执行分支。允许一个语句组对应多个分支标号(常量表达式),也即多个分支执行相同的处理。 语句组如果包含多个语句,其前后不用加花括号。 default是任选项。
40
4. Switch语句的语义 (1)计算开关表达式exp ;
(2)根据exp的值选择对应的case constant-exp并执行其所代表的语句组。 (3)若语句组中带有break语句,当执行到该语句时跳转至switch语句的下一语句,否则顺序执行该语句组以下的各个语句组,直至最后一个语句组,或遇到break语句,跳出switch。 可以看出case constant-exp:和default:只作为语句的入口标号,本身并不能改变控制流程,也即无法控制跳过switch语句的其它分支。这一控制交由break语句实现。
41
请比较下面的两个程序段:它们有助于你了解break在switch语句中作用:
程序段1: switch (color) { case Red: cout << "红色" << endl; case Blue: cout << “蓝色" << endl; case Green: cout << "绿色" << endl; } 执行结果:? 如果color的值是Blue,则输出:蓝色 、 绿色。 为什么?
42
程序段2: switch (color) { case Red: cout << "红色" << endl; break; case Blue: cout << “蓝色" << endl; case Green: cout << "绿色" << endl; } 执行结果:? 如果color的值是Blue,则仅输出 蓝色。这是因每个分支中所包含的Break语句在起作用,所以case通常与break联用,以保证多路分支的正确实现。
43
我们通过两个例子来进一步阐述Switch的用法:
(1)以所选中的菜单项MenuItem作为识别子(switch的开关表达式); (2)在switch语句中设置与菜单选项相对应的多个分支(case),在每个分支中调用相应的函数或程序。
44
emun MENU={File,Edit,View,Windows,Help}; MENU MenuItem; //菜单选择部分(略)
下面是程序示意: emun MENU={File,Edit,View,Windows,Help}; MENU MenuItem; //菜单选择部分(略) //菜单命令执行控制部分 switch (MenuItem) { case File: File(); Break; case Edit: Edit(); 定义表示菜单选项的枚举类型 //调用文件处理函数 //调用编辑处理函数
45
case View: View(); Break; case Windows: Windows(); case Help: Help(); } //调用视图处理函数 //调用窗口处理函数 // 调用帮助函数 例3-13 输入两个整型数和一个算术运算符,输出对应的 表达式及计算结果。
46
(1)输入的两个数按其输入顺序分别作为第一操作数(Value1)和第二操作数(Value2);
(1)分析 (1)输入的两个数按其输入顺序分别作为第一操作数(Value1)和第二操作数(Value2); (2)输入的算术运算符op限制为+、-、*、/,四种; (3)表达式表示为:Value1 <算术运算符> Value2。 通过上面的分析,我们知道可以用Switch语句来区分op的四种取值,以决定如何构造并计算对应的表达式。 (2)源程序 #include <iostream.h> void main() {
47
int value1,value2; char op; cout << "请输入两个操作数:\n"; cin >> value1 >> value2; cout << "请输入操作符:\n"; cin >> op; switch (op) { case '+': cout << value1 << op << value2 << "=" <<value1+ value2 <<endl; break; case '-': cout << value1 << op << value2 << "=" <<value1- value2 <<endl; break; //输入操作数1和操作数2 //输入操作符到op变量中 //输入操作符op为“+” //输入操作符op为“-”
48
case '*': cout << value1 << op << value2 << "=" <<value1* value2 <<endl; break; case '/': cout << value1 << op << value2 << "=" <<value1/ value2 <<endl; default: cout << "输入的操作符有误!" << endl; } //输入操作符op为“*” //输入操作符op为“/”
49
这两个语句都可以用来改变程序的控制流程。
3.3 break语句和continue语句 这两个语句都可以用来改变程序的控制流程。 1. Break语句 1)用途 可以出现在switch语句的分支语句组和各种循环语句的循环体中,用来终止switch语句、循环语句的执行,转入下一语句。 2)语法 break;
50
3)语义 2. continue语句 1)用途 使程序从循环体或switch语句内跳出,继续执行逻辑 上的下一条语句。
可以出现在循环语句的循环体中,用来终止本次循环。
51
2)语法 continue; 3)语义 结束本次循环,也即跳过循环体中尚未执行的语 句,进入是否执行下一次循环的判断。
注意:continue语句只能出现在循环结构中,而且必须与if语句或switch语句联合使用,否则会导致循环无效。 我们会在下面将要提出的循环问题中看到该语句的用法。
52
3.4 while语句 1. 循环问题的提出 分析例3-13所给的程序可以看出,该程序每运行一次只能出一个算术题并求值,如果希望程序运行过程中能不断地重复出题、计算,如何做到这一点了?答案是惟一的: 只能用循环语句构造循环结构,以控制出题、计算等 动作或处理的重复执行。请看下面的例子: 例3-14 在例3-13所给程序的基础增加循环出题、计算功 能。 假定我们用操作符等于'e'来作为循环的终了条件,对应的程序如下:
53
//输入操作符op为“-” #include <iostream.h> void main() {
int value1,value2; char op=‘ ‘; while (op!='e') { cout << "请输入两个操作数:\n"; cin >> value1 >> value2; cout << "请输入操作符:\n"; cin >> op; if (op==‘e’) continue; switch (op) case '+': cout << value1 << op << value2 << "=" <<value1+ value2 <<endl; break; case '-': //循环语句,控制循环体的重复执行 //输入操作数1和操作数2 //输入操作符到op变量中 循环体 //输入操作符op为“+” //输入操作符op为“-”
54
cout << value1 << op << value2 << "=" <<
value1- value2 <<endl; break; case '*': value1*value2 <<endl; break; case '/': value1/value2 <<endl; break; default: cout << "输入的操作符有误!" << endl; } //输入操作符op为“*” 循 环 体 //输入操作符op为“/” //switch语句结束 //循环语句结束 //程序结束
55
(1)我们对例3-13的程序增加一个while语句,该循环语句可以重复执行到输入的操作符等于'e',这样就保证该程序能重复出题、计算。
分析: (1)我们对例3-13的程序增加一个while语句,该循环语句可以重复执行到输入的操作符等于'e',这样就保证该程序能重复出题、计算。 (2)试问循环体中的if (op=='e' )continue 语句起到什么作用? 2.循环语句概述 重复结构(循环结构)是十分重要的程序结构,分为“当型”和“直到型”两种控制形式。 c++提供三种循环语句用来实现循环结构,其中while语句和for语句用来实现“当型”循环,do while语句则用来实现“直到型”循环。
56
3. while语句的语法 while (exp) statement; 解释:
因此通常被称为循环条件表达式, (2)statement:语句,可以是简单语句,也可以是复合语句。这些语句能被重复执行,所以通常称为“循环体”。
57
例3-13的op起到这种关键作用,它就是循环控制变量。
注意: (1) 通常把参与循环条件表达式运算的一些关键数据对象(变量)称为循环变量或循环控制变量。 例3-13的op起到这种关键作用,它就是循环控制变量。 例3-14就是通过输入op来改变op!=‘e’的值: while (op!=‘e’) { cin >> op; …… }
58
(2)循环体中必须含有改变循环控制变量的运算,否则会导致“死循环”。
4.while语句的语义 while语句的语义为:当循环条件表达式的值为真,则执行循环体,直至exp的值为假。故称为“当型”循环。 While语句的执行步骤如下: (1)设置循环控制变量初值; (2) 计算exp;
59
(3)如果exp的值为真(!=0),则转(4),否则转(6);
(4) 执行statement,也即执行循环体; (5) 转(2);//进入下一轮循环 (6) 结束循环语句的执行,转下一语句。 用上面的方法来描述这种逻辑结构较为复杂的语句的语义,显然不够清晰,我们也可以改用用流程图或N-S结构图来描述其语义。
60
用流程图和N-S图描述while语句的语义
设置循环变量初值 计算exp 执行statement Next Statement statement exp N-S图 流程图
61
下面我们通过一个有关字符串处理的实际问题来讲述while语句的实际应用。
例3-14 求指定字符串的长度(字符串所包含的字符数, 不含结束符)。 1)分析 s[0] s[1] s[2] s[3] s[4] 数组元素 数组 (1)将字符序列存放在字符数组中,该数组的每一元素存放一个字符。 a b c d \0 例如:字符串“abcd”存放在s数组中,可以用右图形象地表示: (2)我们对字符串的n个字符逐个比较,直至找到结束符,即可判定该串结束,比较次数-1就是该串的长度。
62
(3)n次比较过程可以用while语句来控制。
2) 程序 #include <iostream.h> void main() { char s[30]; int i; cout << "请输入字符串:\n"; cin >> s; i=0; cout << "所输入的字符串长度为:" << i << endl; } while (s[i]!='\0') i++;
63
3.5 do while语句 1.为什么要引入do while语句
修改 后的程序如下:
64
#include <iostream.h>
void main() { int value1,value2; char op,finish; do { cout << "请输入两个操作数:\n"; cin >> value1 >> value2; cout << "请输入操作符:\n"; cin >> op; switch (op) …… } cout << "结束否(y/n):\n"; cin >> finish; } while(finish! = 'y'); 新增设的变量,其作用? 循环语句 循环体至少执行一次。
65
2.Do while语句的语法 statement:语句,可以是简单语句,也可以是复合语句。同while语句一样,也称为“循环体”。 do
while (exp); statement:语句,可以是简单语句,也可以是复合语句。同while语句一样,也称为“循环体”。 exp:表达式,可以是算术表达式、关系表达式和逻辑表达式。通常称为称为循环条件表达式,其计算结果用来决定是否执行下一次循环。 注意: (1)循环体中必须含有改变循环控制变量取值的运算,否则会导致“死循环”。 例3-15是通过cin >>finish(输入finish),来改变finish!=‘y’ 的值。
66
( 2) 通常把参与循环条件表达式运算的一些关键数据对象(变量)称为循环变量或循环控制变量。
( 2) 通常把参与循环条件表达式运算的一些关键数据对象(变量)称为循环变量或循环控制变量。 3.Do while语句的语义 该语句的语义简述为:重复执行循环体直至循环条件表达式(exp)的值为假。故称为“直到型”循环。 其具体步骤描述如下: (1)执行statement,也即执行循环体; (2)计算exp; (3)如果exp的值为真(!=0),则转(1),否则转(4); (4)结束循环语句的执行,转下一语句。
67
表示Do while语句语义的流程图和N-S图如下:
计算exp 执行statement Next Statement statement exp do while语句和while语句在许多应用上是一致的,但并不完全等价。例如例3-14的问题显然不能直接用do while语句去替换while语句,为什么?
68
因为循环体至少执行一次,所以当s是空串时,输出1。
我们将例3-14所给的程序作如下修改: #include <iostream.h> void main() { char s[30]; int i; cout << "请输入字符串:\n"; cin >> s; i=0; cout << "所输入的字符串长度为:" << i << endl; } 用do while语句代替原来的 while语句 do i++; while (s[i]!='\0'); 因为循环体至少执行一次,所以当s是空串时,输出1。
69
下面的程序用一个do while来控制性别数据的输入和校验,其工作原理是:输入后即进行校验,如不符合要求,再行输入、校验,直到符合要求为止。
例3-16 在数据处理程序中,通常需要通过键盘输入数据, 有些数据其合法性的判定是十分很重要的,例如对于性别 这一数据,如果用单个字母来表示,则要求输入的字符必 须是M或F。 下面的程序用一个do while来控制性别数据的输入和校验,其工作原理是:输入后即进行校验,如不符合要求,再行输入、校验,直到符合要求为止。 #include <iostream.h> void main() { char sex;
70
do { cout << "请输入性别(M/F: )\n"; cin >> sex; if (sex !='F' && sex !='M' ) cout << "性别必须是M或F,输入有误,请重输!"; } while (sex !='F' && sex !='M'); }
71
3.6 for语句 1. for语句应用实例 前面讨论的while语句和do while语句一般都应用在处理循环次数未知的循环问题。但实际上有很多的重复处理其重复次数是事先可以确定的。例如: 例3-17 计算s=1+2+3+……+100 前面已提到这是一个重复99次加法运算的问题。也即赋值表达式s=s+i须重复执行99次。 对于重复次数已知的问题改用for语句来描述,将更为简洁、直观。
72
我们下面将看到for语句不但适用于循环次数确定的循环问题,同样也适用于循环次数不确定的问题。它比while和do while语句更为灵活。
程序: #include <iostream.h> void main() { int sum,i; sum=1; for (i=2,i<=100;i++) sum = sum+i; cout << "sum=:\n" << sum <<emdl; } //循环执行99次 我们下面将看到for语句不但适用于循环次数确定的循环问题,同样也适用于循环次数不确定的问题。它比while和do while语句更为灵活。
73
(1)exp1:表达式1,用来设置循环控制变量初值,一般是赋值表达式;
2.for语句的语法 for ([exp1];[exp2];[exp3]) statement; 解释: (1)exp1:表达式1,用来设置循环控制变量初值,一般是赋值表达式; (2)exp2: 表达式2、其计算结果可以用来作为循环条件,一般是关系表达式或逻辑表达式; (3)exp3:表达式3、用来修改循环控制变量的值。一般是算术表达式或增、减量表达式; (4)statement:语句,可以是简单语句,也可以是复合语句,是for语句的“循环体”。
74
注意: (1)for语句将所有的循环控制(exp1,exp2,exp3)均放在循环顶部统一表示,显得更为直观、更为一体化,保证不会因为程序中疏忽某些循环控制而出现程序的潜在错误。 (2)exp1,exp2,exp3三个表达式之间必须用分号分隔。即使在某个表达式省略的情况下,分号也不能少。 (3)三个表达式都是任选项,也即都可以省略。 省略exp1:表示无须设置循环控制变量初值,这种情 况下,应在循环语句之前进行初值设置。例如,例3-17的 for语句部分可以改为: i=2; sum=1; for (; i<=100; i++) sum=sum+i;
75
此,必须在循环体内设置能够终止循环的语句,否则会导 致死循环。例如:
省略exp2:意味着循环将可能无条件地进行下去,因 此,必须在循环体内设置能够终止循环的语句,否则会导 致死循环。例如: for (i=2; ;i++) { sum=sum+i; if (i>=100) break; }; 省略exp3:如果在循环体内存在着修改循环控制变量 的操作,那么exp3就可以省略,否则同样会导致“死循环”。 例如:
76
如果exp1、exp2、exp3均省略,则for语句变为: for (; ;)
for (i=2;i<=100 ;) { sum+=i++; }; 如果exp1、exp2、exp3均省略,则for语句变为: for (; ;) 上面的结构应该说语法上也是正确的,但语义上就变成无限循环,如果循环体内没有相应的终止循环的语句,势必构成死循环。 3.for语句的语义 for语句其执行过程如下:
77
(1)计算exp1,通常用来设置循环变量的初值;
执行statement exp3 for(exp1;exp2;exp3) statement (1)计算exp1,通常用来设置循环变量的初值; (2)计算exp2,如果其值为真则转(3),否则转(5); (3)执行statement,也即执行循环体; (4)计算exp3,转(2); (5)结束for语句的执行。
78
注意:exp1虽然包含在for语句中,但仅执行一次,而exp2、exp3却必须循环执行n次。
while(exp2) { statement; exp3; } 相比之下,似乎while结构更易于理解, 但for结构则显得更为简洁、更为严谨。 例3-18 找出n1到n2之间不能被3整除的数并输出之。n1 和n2都是整数,并且n2>=n1。
79
1)分析 (1)假定n1=100,n2=200,则这一问题就是找出100到200这101个连续整数中不能被3整除的数。因为循环次数已知,所以我们可以用for语句来处理这一问题。 (2)可以用for语句的exp1和exp3两个表达式来生成n1到n2之间的n2-n1+1个连续整数。 exp1:i=n1; exp3:i++ 2)程序 #include <iostream.h> void main() { int n1,n2,i,j=0;
80
cout << "请输入n1和n2:\n"; cin >> n1 >> n2;
for (i=n1;i<=n2;i++) { if (i%3 != 0) { j=j+1; if (j>10) { cout <<endl; j=0; } else cout << " " << i; } // for结束 cout << endl << " \n"; 问题: (1)if (j>10){ }语句起 什么作用? //换行 (2)如何在每一输出行 下面增加一条表格横线? (3)如果 n2<n1,程序应 如何处理?
81
3.7 多重循环 1.多重循环的概念 2.循环语句的几种嵌套形式
所谓多重循环是指某一循环语句的循环体内包含其它的循环语句,这些内嵌的循环语句的循环体内又可以包含循环语句,依此类推,形成循环语句的嵌套结构,也称为多重循环。 while、do while、for可以互相嵌套,例如while的循环体内嵌套while、do while、for语句。 2.循环语句的几种嵌套形式 程序中经常出现的是直接多重嵌套和并列多重嵌套两种形式。
82
(1)直接多重嵌套 循环语句的循环体内包含另一循环语句,内嵌的循环语句的循环体内又可以包含循环语句,依次类推,直至n重嵌套。如图所示:
…… for ( ) { for ( ) …… while ( ) } 第1层 第2层 第n层
83
循环语句的循环体内包含一些循环语句,内嵌的循环语句的循环体内又可以包含循环语句。依次类推,直至n重嵌套,如下图所示:
(2)并列多重循环 循环语句的循环体内包含一些循环语句,内嵌的循环语句的循环体内又可以包含循环语句。依次类推,直至n重嵌套,如下图所示: …… while ( ) { while () …… } …… for ( ) 外层 内层1 内层2 内层n
84
下面我们给出两个多重循环的应用实例,主要为了加深对多重循环结构的理解。
3.多重循环应用实例 下面我们给出两个多重循环的应用实例,主要为了加深对多重循环结构的理解。 例3-19 找出1到100之间的100个连续整数中的所有素数。 1)分析 (1)只能被1和自身整除的数是素数,实际上程序的判断条件应改为:如果整数m不能被2,3,4,…,m-1整除,则m是素数。可以看出这是重复判断问题,也即对任何一个整数m,必须保证m%i为0(i=2—m-1)。
85
(4)该程序包含一个二重循环结构,外循环用来生成1,3,5,……,99总共50个奇数,内循环用来确定某一奇数是否为素数。
(2)我们对上述算法稍作改进,可以减少运算量,假定m不是素数,则可以表示为:m=i*j,i<=j,i<=sqrt(m),j>=sqrt(m)。也即i=2—sqrt(m)。 (3)素数一定是奇数,而n1到n2之间只有(n2-n1+1)/2个奇数,这意味着从1到100的循环其步长是2,而不是1。当循环语句描述为:for (m=1;m<=100;m+=2),则m的取值为:1,3,5,7,9,……,99。 (4)该程序包含一个二重循环结构,外循环用来生成1,3,5,……,99总共50个奇数,内循环用来确定某一奇数是否为素数。
86
2)程序 #include <iostream.h> #include <iomanip.h> #include <math.h> void main() { int i,m,sqrtm; int l=0;
87
for (m=1;m<=100;m+=2) { sqrtm=sqrt(m); for (i=2;i<=sqrtm;i++) if(m%i==0) break; } if(i>sqrtm) if (l++%10==0) cout <<endl; cout <<setw(5) << m; //m能被i整除 //该数为素数
88
(1)设所求的三位数,其百位数是i,十位数是j,个位数是k ,显然我们所要查找的数应满足:
例3-20找出所有的三位数,其值等于三个数字的立方和。 例如,153是一个三位整数,该数满足:153= 。 1)分析 (1)设所求的三位数,其百位数是i,十位数是j,个位数是k ,显然我们所要查找的数应满足: i*i*i+j*j*j+k*k*k=100*i+10*j+k。 (2)i: 1—9;j: 0—9;k:0—9。 2)程序 显然该程序应该包含一个三重循环,用来生成9*10*10=900个三位数,并找出其中符合条件的数。
89
#include <iostream.h>
void main() { int i,j,k; for (i=1;i<=9;i++) for (j=0;j<=9;j++) for (k=0;k<=9;k++) if (i*i*i+j*j*j+k*k*k==100*i+10*j+k) cout <<100*i+10*j+k<< " "; } 输出:
Similar presentations