1清华大学计算中心
计
算
机
程
序
设
计
基
础
乔 林
计算机程序设计基础
Email: qiaolin@: qiaolin@
Tel: 62792961Tel: 62792961
2清华大学计算中心
计
算
机
程
序
设
计
基
础
第三章 程序控制结构
• 学习目标
– 了解结构化程序设计的一般概念了解结构化程序设计的一般概念
– 熟悉顺序结构、分支结构与循环结构等三种程序熟悉顺序结构、分支结构与循环结构等三种程序
流程控制结构流程控制结构
– 掌握掌握 C C 语言实现分支结构的语言实现分支结构的 if if 语句与语句与 switch switch 语语
句,能熟练应用句,能熟练应用 if if 语句与语句与 switch switch 语句编写程序语句编写程序
– 掌握掌握 C C 语言实现循环结构的语言实现循环结构的 while while 语句、语句、for for 语语
句与句与 do-while do-while 语句,能熟练应用这三种循环控制语句,能熟练应用这三种循环控制
结构编写程序结构编写程序
– 了解三种循环结构的关系,掌握在循环结构中控了解三种循环结构的关系,掌握在循环结构中控
制程序流程转移的方法制程序流程转移的方法
3清华大学计算中心
计
算
机
程
序
设
计
基
础
C 语言结构化程序设计基础
• 程序的控制结构(黑箱)程序的控制结构(黑箱)
–– 单入口单出口的控制结构易于理解单入口单出口的控制结构易于理解
–– 三种基本控制结构:顺序、分支、循环三种基本控制结构:顺序、分支、循环
–– 控制结构可以嵌套,以构成更复杂的控制结构控制结构可以嵌套,以构成更复杂的控制结构
• 程序的结构化程序的结构化
–– 三种基本控制结构可以构造任何复杂的结构化算法三种基本控制结构可以构造任何复杂的结构化算法
–– 结构化程序设计原则:结构化程序设计原则:自顶向下自顶向下,,逐步求精逐步求精
–– 结构化程序设计过程:首先对任务进行功能分解,然后结构化程序设计过程:首先对任务进行功能分解,然后
使用结构化程序设计思想逐一解决各个子问题,最后构使用结构化程序设计思想逐一解决各个子问题,最后构
造原始问题的解造原始问题的解
–– 好处:逻辑性强,可读性好,维护方便好处:逻辑性强,可读性好,维护方便
4清华大学计算中心
计
算
机
程
序
设
计
基
础
顺序结构
• 顺序结构的含义顺序结构的含义
–– 由一组顺序执行的处理块组成,每个处理块可能包含一由一组顺序执行的处理块组成,每个处理块可能包含一
条或一组语句,完成一项任务条或一组语句,完成一项任务
–– 顺序结构是最基本的算法结构顺序结构是最基本的算法结构
• 语句与复合语句(语句块)语句与复合语句(语句块)
–– 三种语句结构:单语句(三种语句结构:单语句(表达式表达式;;)、空语句()、空语句(;;)、复)、复
合语句(合语句({{语句序列语句序列}}))
5清华大学计算中心
计
算
机
程
序
设
计
基
础
顺序结构程序示例
• 分别输入两个复数的实部与虚部,计算两个复数的分别输入两个复数的实部与虚部,计算两个复数的
和、差、积、商并输出结果和、差、积、商并输出结果
##include <>include <>
int int mainmain()()
{{
float float aa, , bb, , cc, , dd, , realreal, , imaginaryimaginary;;
printf printf(“Input reals and imaginaries of two complexes\(“Input reals and imaginaries of two complexes\nn”);”);
scanfscanf(“%(“%ff,%,%ff,%,%ff,%,%ff”, &”, &aa, &, &bb, &, &cc, &, &dd););
printf printf(“Sum: %(“Sum: %ff + % + %ffi\i\nn”, ”, aa + + cc, , bb + + dd););
printf printf(“Difference: %(“Difference: %ff + % + %ffi\i\nn”, ”, aa – – cc, , bb – – dd); );
realreal = = aa * * cc – – bb * * dd; ; imaginaryimaginary = = aa * * dd + + bb * * cc;;
printf printf(“Product: %(“Product: %ff + % + %ffi\i\nn”, ”, realreal, , imaginaryimaginary); );
realreal = ( = (aa**cc + + bb**d)d) / ( / (cc**cc + + dd**dd); ); imaginaryimaginary = ( = (bb**cc – – aa**d)d) / ( / (cc**cc + + dd**dd););
printf printf(“Quotient: %(“Quotient: %ff + % + %ffi\i\nn”, ”, realreal, , imaginaryimaginary); );
return 0; return 0;
}}
实际需要输入实际需要输入44个实数个实数
6清华大学计算中心
计
算
机
程
序
设
计
基
础
分支结构
• 分支结构(选择结构)的含义分支结构(选择结构)的含义
–– 根据某一条件的判断结果,确定程序的流程,即选择哪根据某一条件的判断结果,确定程序的流程,即选择哪
一个程序分支中的处理块去执行一个程序分支中的处理块去执行
–– 最基本的分支结构是二路分支结构最基本的分支结构是二路分支结构
–– 以条件判断为起点,如果判断结果为真,则执行以条件判断为起点,如果判断结果为真,则执行AA处理块处理块
的操作,否则执行的操作,否则执行BB处理块的操作处理块的操作
7清华大学计算中心
计
算
机
程
序
设
计
基
础
if-else 语句
• 语句格式:语句格式:if(if(表达式表达式) ) 语句语句1 1 else else 语句语句22
• 表达式必须位于括号内,一般为关系或逻辑表达式表达式必须位于括号内,一般为关系或逻辑表达式
• 先计算表达式值,若为真则执行语句先计算表达式值,若为真则执行语句11,否则执行,否则执行
语句语句22
• 语句语句11与语句与语句22可以为复合语句可以为复合语句
• 语句语句11与语句与语句22只能有一个被执行只能有一个被执行
• 如果仅仅用于确定某条语句是否执行,如果仅仅用于确定某条语句是否执行,elseelse分支可分支可
以省略以省略
8清华大学计算中心
计
算
机
程
序
设
计
基
础
if-else 语句示例一
• 输入一个字符,判断它是否为输入一个字符,判断它是否为0~90~9之间的数字之间的数字
##include <>include <>
int int mainmain()()
{{
char char cc;;
printf printf(“Input a character: ”);(“Input a character: ”);
cc = = getchargetchar();();
ifif((cc >= 48 && >= 48 && cc <= 57) <= 57)
printf printf(“It is a number.\(“It is a number.\nn”); ”);
elseelse
printf printf(“No, it is not a number.\(“No, it is not a number.\nn”); ”);
return 0; return 0;
}}
因:字符以因:字符以ASCIIASCII码值存储码值存储
且数字的且数字的ASCIIASCII码值码值48~5748~57
故:比较故:比较ASCIIASCII码值码值
9清华大学计算中心
计
算
机
程
序
设
计
基
础
if-else 语句示例二
• 输入一个整数,输出其绝对值输入一个整数,输出其绝对值
##include <>include <>
int int mainmain()()
{{
int int nn, , absabs;;
printf printf(“Enter integer: ”);(“Enter integer: ”);
scanfscanf(“%(“%dd”, &”, &nn););
absabs = = nn;;
ifif((absabs < 0) < 0)
abs abs = – = –absabs; ;
printf printf(“Original integer: %(“Original integer: %dd, absolute value: %, absolute value: %dd\\nn”, ”, nn, ,
absabs););
return 0; return 0;
}}
10清华大学计算中心
计
算
机
程
序
设
计
基
础
if-else if-else 语句
• 语句格式
–– if(if(表达式表达式1) 1) 语句语句1 1 else if(else if(表达式表达式2) 2) 语句语句2 … 2 … else else 语句语句nn
11清华大学计算中心
计
算
机
程
序
设
计
基
础
if-else if-else 示例
• 根据百分制成绩给出优秀、通过或不通过成绩根据百分制成绩给出优秀、通过或不通过成绩
#include <>#include <>
int int mainmain()()
{{
float float scorescore;;
printfprintf(“Input score: “);(“Input score: “);
scanfscanf(“%(“%ff“, &“, &scorescore););
ifif((scorescore >= 85 && >= 85 && scorescore <= 100) <= 100) printfprintf(“Excellent.\(“Excellent.\nn“);“);
else ifelse if((scorescore >= 60 && >= 60 && scorescore < 85) < 85) printfprintf(“Pass.\(“Pass.\nn“);“);
else ifelse if((scorescore >= 0 && >= 0 && scorescore < 60) < 60) printfprintf(“No pass.\(“No pass.\nn“);“);
elseelse printfprintf(“Error score.\(“Error score.\nn“);“);
return 0; return 0;
}}
12清华大学计算中心
计
算
机
程
序
设
计
基
础
条件分支的嵌套
• 条件语句的嵌套格式
– 当年龄大于当年龄大于5050岁时,若工资小于岁时,若工资小于500500,则长,则长200200
,否则长,否则长300300
if(if(ageage > 50) > 50)
if(if(salsal < 500) < 500)
salsal += 200; += 200;
else else
salsal += 300; += 300;
– 若年龄大于若年龄大于5050岁且工岁且工
资小于资小于500500,长,长200200;;
若年龄不大于若年龄不大于5050岁,岁,
则长则长300300
• 语法规定:else与离它最近的if配对
• 嵌套的条件语句可以实现复杂的逻辑判断
if(if(ageage > 50) > 50)
if(if(salsal < 500) < 500)
salsal += 200; += 200;
elseelse
salsal += 300; += 300;
if(if(ageage > 50) > 50)
{{
if(if(salsal < 500) < 500)
salsal += 200; += 200;
}}
elseelse
salsal += 300; += 300;
13清华大学计算中心
计
算
机
程
序
设
计
基
础
条件分支嵌套示例
• 求方程 ax2 + bx + c = 0 的根
#include <>#include <>
#include <> #include <> // // 由于用到平方根函数,要用此头文件由于用到平方根函数,要用此头文件
int int mainmain()()
{{
float float aa, , bb, , cc, , x1x1, , x2x2, , pp, , qq, , mm; ; // // 定义实型变量定义实型变量
printfprintf(“Enter 3 coefficients: “) ;(“Enter 3 coefficients: “) ;
scanfscanf(“%(“%ff,%,%ff,%,%ff“, &“, &aa, &, &bb, &, &cc); ); // // 从键盘读入方程的三个系数从键盘读入方程的三个系数
ifif( ( a a == && == && b b == 0 && == 0 && c c == 0 ) == 0 ) // // 分支分支11:三个系数全为:三个系数全为00
printfprintf(“any value\(“any value\nn“);“);
elseelse ifif( a == 0 && b != 0 ) ( a == 0 && b != 0 ) // // 分支分支22:系数:系数aa为为00,解一元一次方程,解一元一次方程
printfprintf(“x1 = x2 = %(“x1 = x2 = %ff\\nn", – ", – cc / / bb););
elseelse // // 分支分支33:解一元二次方程的两个根:解一元二次方程的两个根
{ {
mm = = bb * * bb – * – * aa * * cc;;
……
14清华大学计算中心
计
算
机
程
序
设
计
基
础
条件分支嵌套示例
ifif( ( mm >= 0 ) >= 0 )
{ { // // 解实根解实根
x1x1 = ( – = ( –bb + + sqrtsqrt((mm) ) / ( * ) ) / ( * aa ); );
x2x2 = ( – = ( –bb – – sqrtsqrt((mm) ) / ( * ) ) / ( * aa ); );
printfprintf(“x1 = %(“x1 = %ff\\nn“, “, x1x1 ); ); // // 输出两个实根输出两个实根
printfprintf(“x2 = %(“x2 = %ff\\nn“, “, x2x2 ); );
} }
elseelse
{ { // // 解虚根解虚根
pp = – = –b b / ( * / ( * aa ); );
qq = = sqrtsqrt(–(–mm) / ( * ) / ( * a a ););
printfprintf(“x1 = %(“x1 = %f f + %+ %ffi\i\nn“, “, pp, , qq););
printfprintf(“x2 = %(“x2 = %ff – % – %ffi\i\nn“, “, pp, , qq););
} }
} }
return 0; return 0;
}}
15清华大学计算中心
计
算
机
程
序
设
计
基
础
switch 分支语法
• 计算过程计算过程
–– 先计算表达式的值先计算表达式的值
–– 依次与一组常量比较依次与一组常量比较
–– 若相同则执行该分支若相同则执行该分支
–– 否则转向否则转向defaultdefault分支分支
–– 退出退出switchswitch语句语句
• 说明说明
–– switchswitch后面的表达式必须为整型、字符型或枚举型后面的表达式必须为整型、字符型或枚举型
–– casecase后面必须为常量表达式,则各个后面必须为常量表达式,则各个casecase值必须不同值必须不同
–– 如果没有如果没有defaultdefault子句,且没有子句,且没有casecase子句匹配,则不执行子句匹配,则不执行
–– casecase分支中的语句可以有多条,不需要花括号分支中的语句可以有多条,不需要花括号
switch( switch( 表达式表达式 ) )
{{
case case 常量表达式常量表达式1: 1: 语句组语句组11
case case 常量表达式常量表达式2: 2: 语句组语句组22
┇┇
case case 常量表达式常量表达式nn: : 语句组语句组nn
default: default: 语句组语句组
}}
16清华大学计算中心
计
算
机
程
序
设
计
基
础
switch 分支流程图
17清华大学计算中心
计
算
机
程
序
设
计
基
础
switch 分支示例一
• 根据输入的成绩等级,打印相应分数段
#include <>#include <>
int int mainmain()()
{{
char char gradegrade;; printfprintf(“Input the grade(A,B,C,D,E):“); (“Input the grade(A,B,C,D,E):“); scanfscanf(“%(“%cc“, &“, &gradegrade); );
switch( switch( grade grade ))
{ {
case ‘A‘: case ‘A‘: printfprintf(“90-100\(“90-100\nn“); “); breakbreak;;
case ‘B‘: case ‘B‘: printfprintf(“80-89\(“80-89\nn“); “); breakbreak;;
case ‘C‘: case ‘C‘: printfprintf(“70-79\(“70-79\nn“); “); breakbreak;;
case ‘D‘: case ‘D‘: printfprintf(“60-69\(“60-69\nn“); “); breakbreak;;
case ‘E‘: case ‘E‘: printfprintf(“0-59\(“0-59\nn“); “); breakbreak;;
default: default: printfprintf(“Error\(“Error\nn“); “);
} }
return 0; return 0;
}}
18清华大学计算中心
计
算
机
程
序
设
计
基
础
switch 分支示例一
• 根据输入的成绩等级,打印相应分数段
#include <>#include <>
int int mainmain()()
{{
char char gradegrade;; printfprintf(“Input the grade(A,B,C,D,E):“); (“Input the grade(A,B,C,D,E):“); scanfscanf(“%(“%cc“, &“, &gradegrade); );
switch( switch( grade grade ))
{ {
case ‘A‘: case ‘A‘: printfprintf(“90-100\(“90-100\nn“);“);
case ‘B‘: case ‘B‘: printfprintf(“80-89\(“80-89\nn“);“);
case ‘C‘: case ‘C‘: printfprintf(“70-79\(“70-79\nn“);“);
case ‘D‘: case ‘D‘: printfprintf(“60-69\(“60-69\nn“);“);
case ‘E‘: case ‘E‘: printfprintf(“0-59\(“0-59\nn“);“);
default: default: printfprintf(“Error\(“Error\nn“); “);
} }
return 0; return 0;
}}
breakbreak的目的是终止的目的是终止switchswitch语句的语句的
执行。如果没有执行。如果没有breakbreak语句,则程语句,则程
序会从指定的序会从指定的casecase分支开始,并在分支开始,并在
该分支结束后继续执行下去。除非该分支结束后继续执行下去。除非
switchswitch语句结束,后面的其他语句结束,后面的其他casecase
分支或分支或defaultdefault分支中的语句都会得分支中的语句都会得
到执行到执行
19清华大学计算中心
计
算
机
程
序
设
计
基
础
switch 分支示例二
• 根据输入的成绩等级,打印是否通过信息
#include <>#include <>
int int mainmain()()
{{
char char gradegrade;; printfprintf(“Input the grade(A,B,C,D,E):“); (“Input the grade(A,B,C,D,E):“); scanfscanf(“%(“%cc“, &“, &gradegrade); );
switch( switch( grade grade ))
{ {
case ‘A‘: case ‘A‘:
case ‘B‘: case ‘B‘:
case ‘C‘: case ‘C‘:
case ‘D‘: case ‘D‘: printfprintf(“Pass\(“Pass\nn“); break;“); break;
case ‘E‘: case ‘E‘: printfprintf(“Fail\(“Fail\nn“); break;“); break;
default: default: printfprintf(“Error\(“Error\nn“); “);
} }
return 0; return 0;
}}
如果逻辑上确实如此,则不如果逻辑上确实如此,则不
同的同的casecase分支可以使用同一分支可以使用同一
个语句组,这也许是特意不个语句组,这也许是特意不
在某些在某些casecase分支中使用分支中使用breakbreak
的唯一正当理由的唯一正当理由
20清华大学计算中心
计
算
机
程
序
设
计
基
础
循环结构
• 循环结构的含义循环结构的含义
–– 根据某一条件的判断结果,反复执行某一处理块的过程根据某一条件的判断结果,反复执行某一处理块的过程
–– 最基本的循环结构是当循环最基本的循环结构是当循环
–– 进入循环结构,判断循环条件,如果循环条件的结果为进入循环结构,判断循环条件,如果循环条件的结果为
真,则执行真,则执行AA处理块的操作,即循环一次,然后再次判断处理块的操作,即循环一次,然后再次判断
循环条件,当循环条件为假时,循环结束循环条件,当循环条件为假时,循环结束
21清华大学计算中心
计
算
机
程
序
设
计
基
础
while 循环
• while while 循环格式:循环格式:while(while(表达式表达式) ) 循环体循环体
• while while 循环流程循环流程
–– 先判断后执行:表达式为真时,执行一遍循环体(一次先判断后执行:表达式为真时,执行一遍循环体(一次
迭代),返回重新计算表达式的值以确定是否重复执行迭代),返回重新计算表达式的值以确定是否重复执行
循环体;若表达式为假,则终止循环循环体;若表达式为假,则终止循环
–– 为保证循环终止,循环体内应有能改变表达式值的语句为保证循环终止,循环体内应有能改变表达式值的语句
22清华大学计算中心
计
算
机
程
序
设
计
基
础
while 循环示例
• 使用 while 循环求两个正整数的最小公倍数
#include <>#include <>
int int mainmain()()
{{
int int mm, , nn, , resultresult;;
printfprintf(“Input two positive integers m, n:“);(“Input two positive integers m, n:“);
scanfscanf(“%(“%dd,%,%dd“, &“, &mm, &, &nn););
if( if(m m > 0 && > 0 && n n > 0)> 0)
{ {
resultresult = = mm < < nn ? ? nn : : mm;;
while(while(resultresult % % mm != 0 || != 0 || resultresult % % nn != 0) != 0) resultresult++;++;
printfprintf(“The least common multiple of m and n is %(“The least common multiple of m and n is %dd.\.\nn“, “, resultresult););
} }
else else printfprintf(“the number m or n is not a positive integer.\(“the number m or n is not a positive integer.\nn“);“);
return 0; return 0;
}}
23清华大学计算中心
计
算
机
程
序
设
计
基
础
do-while 循环
• do-while do-while 循环格式:循环格式:do{ do{ 循环体循环体 } }while(while(表达式表达式));;
• do-while do-while 循环流程循环流程
–– 先执行后判断:先执行一遍循环体(一次迭代),计算先执行后判断:先执行一遍循环体(一次迭代),计算
表达式的值,表达式为真时重复执行循环体,否则终止表达式的值,表达式为真时重复执行循环体,否则终止
循环(循环体至少执行一次,这与循环(循环体至少执行一次,这与whilewhile循环不同)循环不同)
–– 为保证循环终止,循环体内应有能改变表达式值的语句为保证循环终止,循环体内应有能改变表达式值的语句
24清华大学计算中心
计
算
机
程
序
设
计
基
础
do-while 循环示例
• 反复求两个正整数的最小公倍数,直到输入的两个反复求两个正整数的最小公倍数,直到输入的两个
数均为数均为11时结束时结束
#include <>#include <>
int int mainmain(){(){
int int mm, , nn, , resultresult;;
do{do{
printfprintf(“Input two positive integers m, n:“); (“Input two positive integers m, n:“); scanfscanf(“%(“%dd,%,%dd“, &“, &mm, &, &nn););
if( if(m m > 0 && > 0 && n n > 0){ > 0){
resultresult = = mm < < nn ? ? nn : : mm; ;
while( while(resultresult%%mm != 0 || != 0 || resultresult%%nn != 0) != 0) resultresult++;++;
printfprintf(“The least common multiple of m and n is %(“The least common multiple of m and n is %dd.\.\nn“, “, resultresult););
} }
else else printfprintf(“the number m or n is not a positive integer.\(“the number m or n is not a positive integer.\nn“);“);
}while(}while(mm != 1 || != 1 || nn != 1); != 1);
return 0; return 0;
}}
25清华大学计算中心
计
算
机
程
序
设
计
基
础
for 循环
• for for 循环格式循环格式
–– for(for(表达式表达式11; ; 表达式表达式22; ; 表达式表达式33) ) 循环体循环体
• for for 循环流程循环流程
–– 先判断后执行:先执行表达式先判断后执行:先执行表达式11(循环初始化),再计算(循环初始化),再计算
表达式表达式22以根据其结果决定是否执行一遍循环体(为真时以根据其结果决定是否执行一遍循环体(为真时
执行),计算表达式执行),计算表达式33的值(循环再次的值(循环再次““初始化初始化””),返),返
回重新计算表达式回重新计算表达式22的值以确定循环是否终止的值以确定循环是否终止
26清华大学计算中心
计
算
机
程
序
设
计
基
础
for 循环示例一
• 计算
#include <>#include <>
int int mainmain()()
{{
int int resultresult, , kk;;
resultresult = 0; = 0; // // 累加器变量,设置初始值(本例设为累加器变量,设置初始值(本例设为
00))
for( for( kk = 1; = 1; k k <= 100; <= 100; kk++ )++ ) // // 循环计算循环计算
resultresult += += k k * * kk; // ; // 累加累加
printfprintf(“The result: %(“The result: %dd\\nn“, “, resultresult););
return 0;return 0;
}}
27清华大学计算中心
计
算
机
程
序
设
计
基
础
三种循环结构的比较
• 三种循环结构可以互换使用三种循环结构可以互换使用
• for for 循环与循环与 while while 循环常见,循环常见,do-while do-while 循环少见循环少见
• while while 循环常用于不需要或很少需要初始化的场合循环常用于不需要或很少需要初始化的场合
• for for 循环常用于需要简单初始化和通过递增递减运算循环常用于需要简单初始化和通过递增递减运算
控制循环体执行的场合控制循环体执行的场合
• for for 循环将所有循环控制因素都放在循环头部,循环循环将所有循环控制因素都放在循环头部,循环
结构最清晰结构最清晰
• 通过省略循环头部的一个或多个表达式,通过省略循环头部的一个或多个表达式,for for 循环也循环也
可能非常复杂可能非常复杂
28清华大学计算中心
计
算
机
程
序
设
计
基
础
for 循环示例二
• 程序读入一个字符串,然后反向打印输出程序读入一个字符串,然后反向打印输出
#include <>#include <>
#include <>#include <>
int int mainmain( )( )
{ {
char char ss[50], [50], cc;;
int int ii, , jj;;
printfprintf(“Input a string: “); (“Input a string: “); scanfscanf(“%(“%ss“, “, ss); );
for( for( ii = 0, = 0, j j = = strlenstrlen((ss) – 1; ) – 1; i i < < jj; ; ii++, ++, jj– –){– –){
cc = = ss[[ii]; ]; ss[[ii] = ] = ss[[jj]; ]; ss[[jj] = ] = cc;;
} }
printfprintf(“%(“%ss\\nn“, “, ss););
return 0; return 0;
}}
29清华大学计算中心
计
算
机
程
序
设
计
基
础
for 循环示例三
• 打印九九乘法表打印九九乘法表
#include <>#include <>
int int mainmain(){(){
int int ii, , jj, , kk;;
for( for( ii = 1; = 1; i i <= 9; <= 9; ii++ ){ ++ ){
for( for( j j = = ii; ; j j <= 9; <= 9; jj++ ){++ ){
kk = = ii * * jj;;
printfprintf(“%(“%dd×%×%d d = %= %dd\\tt“, “, ii, , jj, , kk););
} }
printfprintf(“\(“\nn“) ;“) ;
} }
return 0; return 0;
}}
如果一个循环体内包含另一个循环则如果一个循环体内包含另一个循环则
称循环嵌套或多重循环称循环嵌套或多重循环
三种循环都可以嵌套,但嵌套时内外三种循环都可以嵌套,但嵌套时内外
层循环不能发生交叉层循环不能发生交叉
发生嵌套时,内层循环经常需要使用发生嵌套时,内层循环经常需要使用
外层循环的某些值作为控制条件外层循环的某些值作为控制条件
30清华大学计算中心
计
算
机
程
序
设
计
基
础
循环控制转移: break 语句
• 输出输出55行、每行行、每行1010个随机数,若随机数大于个随机数,若随机数大于20,00020,000
,本行输出结束,本行输出结束
#include <>#include <>
#include <>#include <>
#include <>#include <>
int int mainmain(){(){
int int ii, , jj, , rr;;
srandsrand( ( timetime((NULLNULL) );) );
for( for( i i = 1; = 1; ii <= 5; <= 5; ii++ ){++ ){
forfor( ( j j = 1; = 1; jj <= 10; <= 10; jj++ ){++ ){
rr = = randrand(); (); printfprintf(“%(“%6d6d\\tt“, “, rr); if(); if(rr > 20000) > 20000) break;break; } }
printfprintf(“\(“\nn“); }“); }
return 0; return 0;
}}
srandsrand()()::设置随机数种子的函数设置随机数种子的函数
timetime()()::获取时间的函数获取时间的函数
randrand()()::产生随机数的函数产生随机数的函数
breakbreak终止当前循环的执行,在存在终止当前循环的执行,在存在
循环嵌套的场合,它并不能终止外层循环嵌套的场合,它并不能终止外层
循环的执行循环的执行
31清华大学计算中心
计
算
机
程
序
设
计
基
础
循环控制转移: continue 语句
• 输入一串字符,以回车结束输入,程序统计并输出输入一串字符,以回车结束输入,程序统计并输出
其中小写字母的个数其中小写字母的个数
#include <>#include <>
int int mainmain(){ (){
char char cc;;
int int num num = 0;= 0;
printfprintf(“Enter a string: \(“Enter a string: \nn“);“);
whilewhile( (( (c c = = getchargetchar()) != ‘\()) != ‘\nn‘ ){‘ ){
if( if(c c < 97 || < 97 || c c > 122) > 122) continue;continue; // // 非小写字母,本次循环结束非小写字母,本次循环结束
numnum++;++;
} }
printfprintf(“%(“%dd\\nn“, “, numnum););
return 0; return 0;
}}
continuecontinue终止的是当前循环的当前一终止的是当前循环的当前一
次迭代,而不是整个循环,当前循环次迭代,而不是整个循环,当前循环
的下一次迭代仍会执行的下一次迭代仍会执行
32清华大学计算中心
计
算
机
程
序
设
计
基
础
结构化程序设计注意事项
• 要保证结构的完整性要保证结构的完整性
–– 不允许结构层次间的交叉!不允许结构层次间的交叉!
• 要保证操作的完整性要保证操作的完整性
–– 一个基本结构就是一个完整的操作单元,程序只能从入一个基本结构就是一个完整的操作单元,程序只能从入
口进出口出口进出口出
–– 程序最好不要有多入口多出口,尤其不能从外部进入循程序最好不要有多入口多出口,尤其不能从外部进入循
环或条件分支内部环或条件分支内部
33清华大学计算中心
计
算
机
程
序
设
计
基
础
结构化程序设计应用示例一
• 打印小于打印小于nn的所有个位不等于的所有个位不等于99的素数,的素数,nn的具体值的具体值
由用户输入,要求分行输出,每行输出由用户输入,要求分行输出,每行输出1010个数个数
#include <>#include <>
int int mainmain(){(){
int int ii, , jj, , nn, , lineline = 0; = 0;
printfprintf(“Please input n:“); (“Please input n:“); scanfscanf(“%(“%dd“, &“, &nn););
if( if(n n <= 1){ <= 1){ printfprintf(“No number to output!\(“No number to output!\nn“); return 1; }“); return 1; }
for( for(i i = 2; = 2; i i <= <= nn; ; ii++){ ++){ // // 逐一取出待查数据逐一取出待查数据
for( for( j j = 2; = 2; j j < < ii; ; jj++) if(++) if(i i % % jj == 0) break; == 0) break; // // 该数非素数,终止内层循环该数非素数,终止内层循环
if( if(i i == == jj && && i i % 10 != 9){ % 10 != 9){ // // 若该数为素数且个位不等于若该数为素数且个位不等于99,打印输出,打印输出
printfprintf(“%(“%dd, “, , “, ii); ); lineline++; if(++; if(line line == 10){ == 10){ printfprintf(“\(“\nn“); “); line line = 0; }= 0; }
} }
} }
printfprintf(“\(“\nn“);“);
return 0; return 0;
} }
使用使用forfor循环循环
34清华大学计算中心
计
算
机
程
序
设
计
基
础
结构化程序设计应用示例一
#include <>#include <>
int int mainmain()()
{{
int int ii, , jj, , nn, , lineline = 0; = 0;
printfprintf(“Please input n:“); (“Please input n:“); scanfscanf(“%(“%dd“, &“, &nn););
if( if(n n <= 1){ <= 1){ printfprintf(“No number to output!\(“No number to output!\nn“); return 1; }“); return 1; }
ii = 2; = 2;
while( while(i i <= <= nn){ ){ // // 逐一取出待查数据逐一取出待查数据
j j = 2;= 2;
while( while(j j < < i i && && i i % % jj != 0) != 0) jj++; ++; // // 求该数的约数求该数的约数
if( if(i i == == jj && && i i % 10 != 9){ % 10 != 9){ // // 若该数为素数且个位不等于若该数为素数且个位不等于99,打印输出,打印输出
printfprintf(“%(“%dd, “, , “, ii); ); lineline++; if(++; if(line line == 10){ == 10){ printfprintf(“\(“\nn“); “); line line = 0; }= 0; }
} }
ii++;++;
} }
printfprintf(“\(“\nn“);“);
return 0; return 0;
} }
使用使用whilewhile循环循环
35清华大学计算中心
计
算
机
程
序
设
计
基
础
结构化程序设计应用示例二
• 百元买百鸡(穷举):已知公鸡每只百元买百鸡(穷举):已知公鸡每只55元,母鸡每元,母鸡每
只只33元,小鸡元,小鸡11元元33只,可买公鸡、母鸡、小鸡几只只,可买公鸡、母鸡、小鸡几只
#include <>#include <>
int int mainmain()()
{{
int int xx, , yy, , zz;;
for( for(x x = 0; = 0; x x <= 100; <= 100; xx++)++)
for( for(y y = 0; = 0; y y <= 100; <= 100; yy++)++)
for( for(zz = 0; = 0; zz <= 100; <= 100; zz++)++)
if( if( x x + + y y + + z z ==100 && 15 * ==100 && 15 * xx + 9 * + 9 * yy + + z z == 300)== 300)
printfprintf(“x = %(“x = %dd, y = %, y = %dd, z = %, z = %dd\\nn“, “, xx, , yy, , zz););
}}
设设xx、、yy、、zz分别表示可买的公鸡、母分别表示可买的公鸡、母
鸡、小鸡的个数,有不定方程组:鸡、小鸡的个数,有不定方程组:
36清华大学计算中心
计
算
机
程
序
设
计
基
础
结构化程序设计应用示例二
• 百元买百鸡(穷举):已知公鸡每只百元买百鸡(穷举):已知公鸡每只55元,母鸡每元,母鸡每
只只33元,小鸡元,小鸡11元元33只,可买公鸡、母鸡、小鸡几只只,可买公鸡、母鸡、小鸡几只
#include <>#include <>
int int mainmain()()
{{
int int xx, , yy, , zz;;
for( for(x x = 0; = 0; x x <=<= 2020; ; xx++)++)
for( for(y y = 0; = 0; y y <= 33<= 33; ; yy++)++)
for( for(zz = 0; = 0; zz <= 100; <= 100; zz++)++)
if( if( x x + + y y + + z z ==100 && 15 * ==100 && 15 * xx + 9 * + 9 * yy + + z z == 300)== 300)
printfprintf(“x = %(“x = %dd, y = %, y = %dd, z = %, z = %dd\\nn“, “, xx, , yy, , zz););
}}
设设xx、、yy、、zz分别表示可买的公鸡、母分别表示可买的公鸡、母
鸡、小鸡的个数,有不定方程组:鸡、小鸡的个数,有不定方程组:
#include <>#include <>
int int mainmain()()
{{
int int xx, , yy, , zz;;
for( for(x x = 0; = 0; x x <= 100; <= 100; xx++)++)
for( for(y y = 0; = 0; y y <= 100; <= 100; yy++)++)
for( for(zz = 0; = 0; zz <= 100; <= 100; zz++)++)
if( if( x x + + y y + + z z ==100 && 15 * ==100 && 15 * xx + 9 * + 9 * yy + + z z == 300)== 300)
printfprintf(“x = %(“x = %dd, y = %, y = %dd, z = %, z = %dd\\nn“, “, xx, , yy, , zz););
}}
37清华大学计算中心
计
算
机
程
序
设
计
基
础
结构化程序设计应用示例三
• 输出裴波那契数列前输出裴波那契数列前3030项值(递推)项值(递推)
#include <>#include <>
int int mainmain()()
{{
int int n1n1, , n2n2, , nn, , countcount;;
n1n1 = 0; = 0; n2n2 = 1; = 1;
printfprintf(“%(“%10d10d%%10d10d“, “, n1n1, , n2n2););
for( for(count count = 3; = 3; count count <= 30; <= 30; countcount++)++)
{ {
nn = = n1n1 + + n2n2; ;
printfprintf(“%(“%10d10d“, “, nn););
if( if(count count % 5 == 0) % 5 == 0) printfprintf(“\(“\nn“); “); // // 控制每行输出控制每行输出55个数个数
n1n1 = = n2n2; ; n2n2 = = nn;;
} }
printfprintf(“\(“\nn“);“);
}}
38清华大学计算中心
计
算
机
程
序
设
计
基
础
结构化程序设计应用示例四
• 设计一个简单的菜单程序
– 运行时,首先显示一个菜单画面用以提示输入操运行时,首先显示一个菜单画面用以提示输入操
作选择作选择
– 操作员从菜单上选择一个操作(即输入相应的代操作员从菜单上选择一个操作(即输入相应的代
码,例如码,例如11、、22等),程序接收选择后调用相应的等),程序接收选择后调用相应的
函数完成操作函数完成操作
– 假设系统提供假设系统提供selectselect()()、、insertinsert()()、、updateupdate()()和和deldel()()
函数,分别用以实现选择、插入、更新与删除等函数,分别用以实现选择、插入、更新与删除等
相应操作相应操作
39清华大学计算中心
计
算
机
程
序
设
计
基
础
结构化程序设计应用示例四
#include <>#include <>
void void insertinsert();();
void void selectselect();();
void void deldel();();
void void updateupdate();();
int int mainmain()()
{{
/*/* generate menu generate menu */*/
char char opop;;
printfprintf(“\(“\nn ********************************“); ********************************“); /*/*生成菜单生成菜单*/*/
printfprintf(“\(“\nn * Menu Options *“); * Menu Options *“);
printfprintf(“\(“\nn * 1. Insert *“); * 1. Insert *“);
printfprintf(“\(“\nn * 2. Select *“); * 2. Select *“);
printfprintf(“\(“\nn * 3. Delete *“); * 3. Delete *“);
printfprintf(“\(“\nn * 4. Update *“); * 4. Update *“);
printfprintf(“\(“\nn * 5. Exit *“); * 5. Exit *“);
printfprintf(“\(“\nn ********************************“); ********************************“);
40清华大学计算中心
计
算
机
程
序
设
计
基
础
结构化程序设计应用示例四
/* /* selection operationselection operation */ */
while(1) while(1)
{ {
printfprintf(“\(“\nnPlease enter selection: “); Please enter selection: “); scanfscanf(“%(“%dd“, &“, &opop););
switch( switch(opop))
{ { /* /* 根据输入,选择分支走向根据输入,选择分支走向 */ */
case ‘1‘: case ‘1‘: insertinsert(); break;(); break;
case ‘2‘: case ‘2‘: selectselect(); break;(); break;
case ‘3‘: case ‘3‘: deldel(); break ;(); break ;
case ‘4‘: case ‘4‘: updateupdate(); break;(); break;
case ‘5‘: break; case ‘5‘: break;
default: default: printfprintf(“\(“\nnSelection error!“); break;Selection error!“); break;
} }
if( if(opop == ‘5’) break; == ‘5’) break; /* /* 退出循环退出循环 */ */
} }
} } // // 结束主函数结束主函数
41清华大学计算中心
计
算
机
程
序
设
计
基
础
作 业
• 第71-72页:第二题(填空题)
– 第第88、、99、、1111小题小题
• 第72-73页:第三题(编程题)
– 第第22、、44小题小题