版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章
程序的控制结构1/6/20231第4章1/6/20231第4章程序的控制结构本章主要教学内容
算法的描述方法基本控制结构及基本控制语句常用算法程序的基本版式结构化程序设计的基本思想程序测试与改错1/6/20232第4章程序的控制结构本章主要教学内容算法的描述方法1/64.1算法的概念及其描述数据结构+算法=程序算法:为解决一个具体问题而采取的确定的有限的操作步骤。算法特性:有穷性确定性
有效性
没有输入或有多个输入
有一个或多个输出
1/6/202334.1算法的概念及其描述数据结构+算法=程序1/6/202算法的分类数值运算算法:解决的是求数值解的问题,例如用辗转相除法求两个数的最大公约数等非数值运算算法:主要用于解决需要用分析推理、逻辑推理才能解决的问题,例如人工智能中的许多问题,查找、分类等问题1/6/20234算法的分类数值运算算法:1/6/20234算法的描述方法自然语言表示传统的流程图表示N-S结构化流程图表示
伪代码表示1/6/20235算法的描述方法自然语言表示1/6/20235构成程序的三种基本结构顺序结构选择结构(分支结构)循环结构已经证明,任何程序均可只用这三种结构综合描述只用这三种结构编制的程序,叫结构化程序程序必须符合结构化规则1/6/20236构成程序的三种基本结构顺序结构1/6/20236结构化程序设计的核心思想采用顺序、选择和循环三种基本结构作为程序设计的基本单元只有一个入口;只有一个出口;无死语句,即不存在永远都执行不到的语句;无死循环,即不存在永远都执行不完的循环。采用“自顶向下、逐步求精”和模块化的方法进行结构化程序设计1/6/20237结构化程序设计的核心思想采用顺序、选择和循环三种基本结构作为4.2顺序结构BANS图传统流程图BA1/6/202384.2顺序结构BANS图传统流程图BA1/6/20238顺序结构——应用举例(1)例:设半径为1.5,求圆周长及面积。解:(1)问题分析:(算法)step1:给出圆的半径r=1.5step2:求圆的周长及面积step3:输出结果公式:圆周长=2*3.14*r圆面积=3.14*r*r1/6/20239顺序结构——应用举例(1)例:设半径为1.5,求圆周长及面积开始r=1.5L=2*3.14*rs=3.14*r*r输出L,s结束(2)画出流程图1/6/202310开始r=1.5L=2*3.14*rs=3.14*r*r输出#include<stdio.h>#definePI3.14main(){floatr,l,s;r=1.5;l=2*PI*r;s=PI*r*r;printf("\nl=%f,s=%f",l,s);}(3)根据流程图编程1/6/202311#include<stdio.h>(3)根据流程图编顺序结构——应用举例(2)例4.1设银行存款利率rate为2.25%,存款期为n年,本金为captial元,编程计算n年后的本利之和deposit解:(1)问题分析:(算法)step2:给出年n、本金captial(键盘输入)step3:n年后本利之和depositstep4:输出结果公式:deposit=captial*(1+rate)nstep1:给出存款利率rate1/6/202312顺序结构——应用举例(2)例4.1设银行存款利率rate为开始rate=0.0225输入n和captialdepoist=captial*(1+rate)n输出depoist结束(2)画出流程图1/6/202313开始rate=0.0225输入n和captialdepois(3)根据流程图编程#include<math.h>#include<stdio.h>main(){
intn;doublerate=0.0225;doublecapital,deposit;printf("pleaseenteryear,capital:");scanf("%d%lf",&n,&capital);deposit=capital*pow(1+rate,n);printf("deposit=%lf\n",deposit);}1/6/202314(3)根据流程图编程#include<math.h>1/以#开始的编译预处理命令
main(){局部变量说明语句;
执行语句;}简单的C程序结构框架1/6/202315以#开始的编译预处理命令简单的C程序结构框架1/6/2023编译预处理命令文件包含编译预处理命令#include指示编译系统将一个源文件嵌入到含有#include指令的源文件中该指令所在的位置处。使用形式:#include<头文件名>/"头文件名"注意:以#开头;每条一行;不是C语句1/6/202316编译预处理命令文件包含编译预处理命令#include指示编译查询情况编译预处理命令(1)用<>将头文件名括起,则在include子目录中查询(2)用"
"将头文件名括起,则先在当前目录中查找若无继续搜索C子目录。1/6/202317查询情况编译预处理命令(1)用<>将头文件名括起,则在(2)常用函数对应的头文件函数头文件名数学函数math.h字符串函数string.h输入、输出函数stdio.h动态存储分配函数stdlib.h/malloc.h1/6/202318常用函数对应的头文件函数4.3选择结构作用:根据条件控制程序流向。条件的组成:问题的提出:各种类型的常量、变量、表达式(常用:关系/逻辑表达式)注意各种表达式的用法1/6/2023194.3选择结构作用:根据条件控制程序流向。条件的组成:问题简单分支选择(单分支)结构yesno语句A条件成立否条件表达式.T..F.语句格式:
if(表达式)语句/语句组;1/6/202320简单分支选择(单分支)结构yesno语句A条件成立否条件表达双分支选择结构yesno程序段A程序段B条件成立否条件表达式.T..F.语句1语句2格式:If(表达式)语句1/语句组1;else语句2/语句组2;1/6/202321双分支选择结构yesno程序段A程序段B条件成立否条件表达式多分支选择结构表达式语句1TF语句2表达式表达式语句3语句4TTFF表达式1语句1TF语句2表达式2表达式3语句3语句4TTFF1/6/202322多分支选择结构表达式语句1TF语句2表达式表达式语句3语句4多分支选择结构
if(表达式)语句1;elseif(表达式2)语句2;:elseif(表达式m)语句m;else语句n;一般形式:1/6/202323多分支选择结构if(表达式)语句1;一般形式:1/6/分支嵌套
if(表达式1)
if(表达式2)语句1;else语句2;
else
if(表达式3)语句3;else语句4;一般形式:1/6/202324分支嵌套if(表达式1)一般形式:1/6/202324使用if语句需注意事项(1)条件判断表达式一定用圆括号括起。(2)复合语句必须用{}引起。(3)每一个else必须与一个if项匹配。(4)else总是与离它最近的if相匹配。1/6/202325使用if语句需注意事项(1)条件判断表达式一定用圆括号括体型判断。按“体指数”对肥胖程度进行划分:体指数t=体重w/(身高h)2(w单位为公斤,h单位为米)当t<18时,为低体重;当t介于18和25之间时,为正常体重;当t介于25和27之间时,为超重体重;当t>=27时,为肥胖。编程从键盘输入你的身高h和体重w,根据给定公式计算体指数t,然后判断你的体重属于何种类型。用3种方法编程:算法1:用不带else子句的if语句编程(ex45_1)算法2:用在if子句中嵌入if语句的形式编程(ex45_2)算法3:用在else子句中嵌入if语句的形式编程(ex45_3)
例4.51/6/202326体型判断。按“体指数”对肥胖程度进行划分:例4.51/6/2例:计算并输出下列分段函数值y=0x01x>0#include<stdio.h>main(){floatx,y;printf("inputx:");scanf("%f",&x);
y=0;if(x>0)y=1;printf("y=%f\n",y);}1/6/202327例:计算并输出下列分段函数值y=0x0#inc用switch语句构成的多分支结构多路选择switch
(表达式)
{
case
常数1:
语句序列1;
case
常数2:
语句序列2;
…………
default:
语句序列3;
}default可以没有,但最好不省略不要忘记break1/6/202328用switch语句构成的多分支结构多路选择1/6/2023例4.8编程设计一个简单的计算器程序。(ex48)要求根据用户从键盘输入的表达式:
操作数1运算符op操作数2计算表达式的值,指定的运算符为加(+)、减(-)、乘(*)、除(/)1/6/202329例4.8编程设计一个简单的计算器程序。(ex48)1/6/2使用switch语句应注意(1)各常量表达式的值不可相同。(2)case后可有多个语句,不用{}括起。(3)常量表达式仅是一个语句标号。(4)各case及default子句的顺序可随意。(5)每个分支执行后,利用break语句跳出。1/6/202330使用switch语句应注意(1)各常量表达式的值不可相同。4.4循环结构引入循环的目的:简化程序、提高编程效率三种循环方式当型循环直到型循环步长型循环1/6/2023314.4循环结构引入循环的目的:简化程序、提高编程效率三种循循环结构的流程图条件PA当型循环直到循环真假假条件PA假真假条件P条件PA假1/6/202332循环结构的流程图条件PA当型循环直到循环真假假条件PA假循环语句——while一般形式:while(表达式)
{ 语句;}只要表达式的值为非0,就重复执行语句,直到表达式值为0时止先判断,后执行1/6/202333循环语句——while一般形式:1/6/202333例:找出100以内的奇数。
main(){int
I=1;
while(I<=100)
{printf("%d",I);
I+=2;}}注意:(1)while构成的是“当型”循环。(2)循环体中一定有对于循环控制变量的操作。1/6/202334例:找出100以内的奇数。main()注意:(1)whi循环语句——do-while一般形式:do
{
语句;
}while
(表达式);首先执行语句,然后判断表达式的值。如果表达式为0,继续向下执行,否则,再次执行语句,再次判断表达式的值语句会被至少执行一次1/6/202335循环语句——do-while一般形式:1/6/20233例:找出100以内的奇数。
main(){int
I=1;
while(I<=100)
{printf("%d",I);
I+=2;}}
main(){int
I=1;
do
{printf("%d",I);
I+=2;}
while(I<=100);}1/6/202336例:找出100以内的奇数。main()main()1/6循环语句——for一般形式:for(表达式1;表达式2;表达式3)
{ 语句;}表达式2执行循环体计算表达式1的值计算表达式3的值跳出循环TF工作过程:1/6/202337循环语句——for一般形式:表达式2执行循环体计算表达式1有关for的说明(1)
for(表达式1;表达式2;表达式3)
{ 语句;}相当于:
表达式1;
while
(表达式2){
语句;
表达式3;
}1/6/202338有关for的说明(1)for(表达式1;表达式2在for和while语句之后一般没有分号有分号表示循环体就是分号之前的内容(空循环体)while(i<100);
i++;for(i=0;i<100;i++);
printf("%d",i);for通常有一个循环变量控制循环的次数,不要在循环体内改变这个变量有关for的说明(2)1/6/202339在for和while语句之后一般没有分号有关for的说明
for语句中的表达式1、表达式3可为逗号表达式。如:for(i=0,j=1;j<n&&i<n;i++,j++)表达式1和表达式3可以没有或者是用逗号分隔的多个表达式的组合。如:for(;i<=5;)有关for的说明(3)1/6/202340for语句中的表达式1、表达式3可为逗号表达式。如:main(){floatx,sum;while(x!=9999){if(x<0.0)sum+=x;printf("\nsum=%f",sum);scanf("%f",&x);}scanf("%f",&x);}例:给定一组数据如下,编程对负数求和。12,45,67.8,-12.5,-35.67,567.89方法1:用while1/6/202341main(){floatx,sum;while(x例:给定一组数据如下,编程对负数求和。12,45,67.8,-12.5,-35.67,567.89方法2:用formain()floatx,sum=0;for(i=1;i<=6;i++)if(x<0.0)sum+=x;}{scanf("%f",&x);printf("\nsum=%f",sum);inti;}{1/6/202342例:给定一组数据如下,编程对负数求和。12,45,67.8,选择三种循环的一般原则如果循环次数已知,用for如果循环次数未知,用while如果循环体至少要执行一次,用do-while这只是“一般”原则,不是“原则”1/6/202343选择三种循环的一般原则如果循环次数已知,用for1/6/20
猜数游戏:先由计算机“想”一个数请人猜,如果人猜对了,则计算机给出提示:“Right!”,否则提示:“Wrong!”,并告诉人所猜的数是大还是小。(ex46)例4.6分析:Step1:计算机想一个数;Step2:人猜一个数;Step3:判断三种情况并给出相应结果。1/6/202344猜数游戏:先由计算机“想”一个数请人猜,如果人猜对了,猜数游戏用到的库函数(1)随机函数rand()#include<stdlib.h>RAND_MAX在stdlib.h中定义,不大于双字节整数的最大值32767产生[0,RAND_MAX]之间的随机数magic=rand();产生[0,b-1]之间的随机数magic=rand()%b;产生[a,a+b-1]之间的随机数magic=rand()%b+a;1/6/202345猜数游戏用到的库函数(1)随机函数rand()1/6/202
猜数游戏:先由计算机“想”一个1到100之间的数请人猜,如果人猜对了,则结束游戏,否则计算机给出提示,告诉人所猜的数是太大还是太小,直到人猜对为止。计算机记录人猜的次数,以此来反映猜数者“猜”的水平。(ex49)例4.9运行程序发现问题每次运行程序,机器所想的数都是一样的;用函数rand所产生的随机数只是伪随机数。1/6/202346猜数游戏:先由计算机“想”一个1到100之间的数请人猜猜数游戏用到的库函数(2)随机函数srand为函数rand()设置随机数种子来实现对函数rand所产生的伪随机数的“随机化”通过键入随机数种子,产生[0,100]之间的随机数scanf("%u",&seed);srand(seed);magic=rand()%100+1;改进例4.9(ex49_1)1/6/202347猜数游戏用到的库函数(2)随机函数srand1/6/2023猜数游戏用到的库函数(3)随机函数srand:为函数rand()设置随机数种子来实现对其产生的伪随机数的“随机化”使用计算机读取其时钟值并把该值自动设置为随机数种子,产生[0,100]之间的随机数函数time()返回以秒计算的当前时间值,该值被转换为无符号整数并用作随机数发生器的种子#include<time.h>srand(time(NULL));magic=rand()%100+1;再改进例4.9(ex49_2)1/6/202348猜数游戏用到的库函数(3)随机函数srand:为函数rand永远不会退出的循环为死循环for(;;){}while(1){}do
{}while(1);一般情况下,要极力避免死循环绝大多数程序不需要死循环。如果出现,往往都是bug时间过长的循环会造成“假死”效果,也要考虑解决死循环1/6/202349永远不会退出的循环为死循环死循环1/6/202349例4.11国王的许诺相传国际象棋是古印度舍罕王的宰相达依尔发明的。舍罕王十分喜欢象棋,决定让宰相自己选择何种赏赐。位聪明的宰相指着8×8共64格的象棋盘说:陛下,请您赏给我一些麦子吧,就在棋盘的第一个格子中放1粒,第2格中放2粒,第3格放4粒,以后每一格都比前一格增加一倍,依此放完棋盘上的64个格子,我就感恩不尽了舍罕王让人扛来一袋麦子,他要兑现他的许诺。
国王能兑现他的许诺吗?试编程计算舍罕王共要多少麦子赏赐他的宰相,这些麦子合多少立方米?
(已知1立方米麦子约1.42e8粒)
总粒数为:sum=1+2+22+23+…+263
1/6/202350例4.11国王的许诺相传国际象棋是古印度舍罕王的宰相达依尔#defineCONST1.42e8#include<stdio.h>#include<math.h>main(){
int
n;
double
term,sum=0;
/*累加求和变量赋初值*/
for
(n=1;n<=64;n++)
{
term=
pow(2,n-1);
/*根据累加项的规律计算累加项
*/
sum=sum+term;
/*作累加运算*/
}
printf("sum=%e\n",sum);/*打印总麦粒数*/
printf("volum=%e\n",sum/CONST);/*打印折合的总麦粒体积数*/}方法11/6/202351#defineCONST1.42e8方法11/6/20方法2#defineCONST1.42e8/*定义符号常量CONST值为1.42e8*/#include<stdio.h>main(){
int
n;
double
term=1,sum=1;/*累乘求积、累加求和变量赋初值*/
for
(n=2;n<=64;n++)
{
term=term*2;/*根据后项总是前项的2倍计算累加项*/
sum=sum+term;
/*作累加运算*/
}
printf("sum=%e\n",sum);
/*打印总麦粒数*/
printf("volum=%e\n",sum/CONST);/*打印折合的总麦粒体积数*/}
1/6/202352方法2#defineCONST1.42e8/循环嵌套结构形式for(){:while(){:do{:}while();}}1/6/202353循环嵌套结构形式for(使用嵌套的循环时,应注意的问题在嵌套的各层循环体中,使用复合语句(即用一对大花括号将循环体语句括起来)保证逻辑上的正确性
内层和外层循环控制变量不应同名,以免造成混乱
嵌套的循环最好采用右缩进格式书写,以保证层次的清晰性
循环嵌套不能交叉,即在一个循环体内必须完整的包含着另一个循环
1/6/202354使用嵌套的循环时,应注意的问题在嵌套的各层循环体中,使用复合合法的嵌套循环1/6/202355合法的嵌套循环1/6/202355例4.14编程输出如下形式的九九表1/6/202356例4.14编程输出如下形式的九九表1/6/202356#include<stdio.h>main(){ intm,n;
for(m=1;m<10;m++)
printf("%4d",m);/*打印表头*/
printf("\n");
for(m=1;m<10;m++)
printf("-"); printf("\n");
for(m=1;m<10;m++) {
for(n=1;n<10;n++) {
printf("%4d",m*n); }
printf("\n");
}}例4.141/6/202357#include<stdio.h>例4.141/6/20例4.15将上例输出格式改变成下三角格式打印1/6/202358例4.15将上例输出格式改变成下三角格式打印1/6/2023#include<stdio.h>main(){ intm,n;
for(m=1;m<10;m++)
printf("%4d",m);/*打印表头*/
printf("\n");
for(m=1;m<10;m++)
printf("-");
printf("\n");
for(m=1;m<10;m++) {
for(n=1;n<=m;n++) {
printf("%4d",m*n); }
printf("\n"); }}例4.151/6/202359#include<stdio.h>例4.151/6/20例4.16马克思手稿中有一道趣味数学题:有30个人,其中有男人、女人和小孩,在一家饭馆里吃饭共花了50先令,每个男人各花3先令,每个女人各花2先令,每个小孩各花1先令,问男人、女人和小孩各有几人?
解方程组穷举法1/6/202360例4.16马克思手稿中有一道趣味数学题:有30个人,其中有方法1:穷举x,y,z的所有组合#include<stdio.h>main(){
intx,y,z;
printf("Man\tWomen\tChildern\n");
for(x=0;x<=30;x++)
for(y=0;y<=30;y++)
for(z=0;z<=30;z++)
if(x+y+z==30&&3*x+2*y+z==50)
printf("%3d\t%5d\t%8d\n",x,y,z);}
1/6/202361方法1:穷举x,y,z的所有组合#include<stdi方法2:改进算法#include<stdio.h>
main(){
intx,y,z;
printf("Man\tWomen\tChildern\n");
for(x=0;x<=16;x++)
for(y=0;y<=25;y++){z=30–x-y;
if(3*x+2*y+z==50)
printf("%3d\t%5d\t%8d\n",x,y,z);}}
1/6/202362方法2:改进算法#include<stdio.h>1/64.5流程的转移控制goto语句break语句continue语句return语句标准库函数exit()
1/6/2023634.5流程的转移控制goto语句1/6/202363goto语句一般形式goto语句标号;……语句标号:……或语句标号:…………goto语句标号;功能:无条件转去执行语句标号所指语句行。1/6/202364goto语句一般形式1/6/202364(1)语句标号用标识符表示。(2)语句标号一定为函数段中存在的。(3)该语句不可滥用。使用goto语句要注意标号举例error:goto举例goto
error;不能用整数作语句标号1/6/202365(1)语句标号用标识符表示。(2)语句标号一定为函数段中存在使用之后,程序仍然是单入口,单出口不要使用一个以上的标号不要用goto往回跳,要向下跳不要让goto制造出永远不会被执行的代码使用goto语句的原则1/6/202366使用之后,程序仍然是单入口,单出口使用goto语句的原则1break
与continue
语句
break语句的作用:循环中使用break语句可提前结束整个循环。
continue语句的作用:循环中使用continue语句可提前结束本次循环1/6/202367break与continue语句break语句的作用:break
与continue
语句示意图假假真真break表达式1表达式2循环语句的下一条语句循环语句的下一条语句假假真真contiue表达式1表达式2continue1/6/202368break与continue语句示意图假假真真break有关break
与continue的说明(1)break语句可用于switch结构,也可用于循环中;(2)continue语句仅用于循环中;(3)break与continue均只影响包含它的结构中;(4)break与continue少用为妙;1/6/202369有关break与continue的说明(1)break#include<stdio.h>#definePI3.14main(){intr;floatarea;for(r=1;r<=10;r++){
area=PI*r*r;if(area>50.0)
break;printf("面积等于%f\n",area);
}printf("现在r=%d\n",r);}例1/6/202370#include<stdio.h>#define例#include<stdio.h>#definePI3.14main(){intr;floatarea;for(r=1;r<=10;r++){area=PI*r*r;if(area<50.0)
continue;printf("面积等于%f\n",area);}}1/6/202371例#include<stdio.h>#defineExit()
函数exit(0)作用是终止整个程序的执行,强制返回操作系统
调用该函数需要嵌入头文件<stdlib.h>1/6/202372Exit()函数exit(0)1/6/202372例4.19从键盘任意输入一个正整数,编程判断它是否是素数,若是素数,输出“Yes!”;否则,输出“No!”问题分析:概念:素数是指除了能被1和它本身整除外,不能被其他任何整数整除的数;判断素数的方法:把m作为被除数,把i=2~(m-1)依次做为除数,若余数都不为0,则说明是素数。简单判断方法:只需用2~的数去除m,即可得到正确的判定结果。1/6/202373例4.19从键盘任意输入一个正整数,编程判断它是否是素数,若#include<math.h>main(){
intm,i,k;
printf("Pleaseenteranumber:");
scanf("%d",&m); k=sqrt(m);
for(i=2;i<=k;i++) {
if(m%i==0) {
printf("No!\n");
gotoend; } }
printf("Yes!\n");end:
printf("Programisover!\n");}Pleaseenteranumber:
6
Programisover!No!方法1:用goto1/6/202374#include<math.h>Pleaseenter方法1:用goto#include<math.h>main(){
intm,i,k;
printf("Pleaseenteranumber:");
scanf("%d",&m); k=sqrt(m);
for(i=2;i<=k;i++) {
if(m%i==0) {
printf("No!\n");
gotoend; } }
printf("Yes!\n");end:
printf("Programisover!\n");}Pleaseenteranumber:
5
Programisover!Yes!1/6/202375方法1:用goto#include<math.h>Ple#include<math.h>main(){
intm,i,k;
printf("Pleaseenteranumber:");
scanf("%d",&m); k=sqrt(m);
for(i=2;i<=k;i++){
if(m%i==0)
break;
}
if(i>k)
printf("Yes!\n");
else
printf("No!\n");
printf("Programisover!\n");}Pleaseenteranumber:
6
Programisover!No!方法2:用break1/6/202376#include<math.h>Pleaseenter#include<math.h>main(){
intm,i,k,flag=1;/*标志变量flag初值置为1*/
printf("Pleaseenteranumber:");
scanf("%d",&m); k=sqrt(m);
for(i=2;i<=k&&flag;i++) {
if(m%i==0)
flag=0;
}
if(flag)
printf("Yes!\n");
else
printf("No!\n");
printf("Programisover!\n");}方法3采用设置标志变量的方法1/6/202377#include<math.h>方法3采用设置1/6/2#include<math.h>main(){
intm,i,k,flag=1;/*标志变量flag初值置为1*/
printf("Pleaseenteranumber:");
scanf("%d",&m);
for(i=2;i<=m-1;i++) {
if(m%i==0){flag=0;
printf("%d\n",i);}
}
if(flag)
printf("Nodivisor!Itisaprimenumber.\n");
printf("Programisover!\n");}程序功能?1/6/202378#include<math.h>程序功能?1/6/202本章小结(1)算法的描述方法流程图与基本控制结构相应的结构化的控制语句if-elseswitchforwhiledo-whilebreakcontinue常用算法,如累加、累乘、统计、递推、迭代、穷举等1/6/202379本章小结(1)算法的描述方法1/6/202379常用算法(1)求阶乘:
数据类型的定义,long或double(2)统计:统计正数、平均分以上、n个成绩中100~90、89~80、79~70、69~60、<60的人数;输入字符串中字母d的个数设置一个计数变量k:初始化为1,每遇到一次将其加1:k++;本章小结(2)1/6/202380常用算法本章小结(2)1/6/202380本章小结(3)常用算法(3)累加和:存放累加和的变量初始化为0或第一项,再循环加每一项;循环控制:前n项之和—已知循环次数,可设置一个循环变量如i来控制;加到某一项或累加和满足一定条件。例:1+2+...+n与1+3+5+7+.…和2+4+6+8+.…及12+32+52+72+....输入n或累加和大于2000的最小的n1/6/202381本章小结(3)常用算法1/6/202381作业习题44.2、4.3、4.4、4.6、4.10、4.14、4.15、4.19、4.20、4.25、4.26、4.27下周实验内容:习题44.15、4.19、4.20、4.25、1/6/202382作业习题4下周实验内容:习题41/6/202382第4章
程序的控制结构1/6/202383第4章1/6/20231第4章程序的控制结构本章主要教学内容
算法的描述方法基本控制结构及基本控制语句常用算法程序的基本版式结构化程序设计的基本思想程序测试与改错1/6/202384第4章程序的控制结构本章主要教学内容算法的描述方法1/64.1算法的概念及其描述数据结构+算法=程序算法:为解决一个具体问题而采取的确定的有限的操作步骤。算法特性:有穷性确定性
有效性
没有输入或有多个输入
有一个或多个输出
1/6/2023854.1算法的概念及其描述数据结构+算法=程序1/6/202算法的分类数值运算算法:解决的是求数值解的问题,例如用辗转相除法求两个数的最大公约数等非数值运算算法:主要用于解决需要用分析推理、逻辑推理才能解决的问题,例如人工智能中的许多问题,查找、分类等问题1/6/202386算法的分类数值运算算法:1/6/20234算法的描述方法自然语言表示传统的流程图表示N-S结构化流程图表示
伪代码表示1/6/202387算法的描述方法自然语言表示1/6/20235构成程序的三种基本结构顺序结构选择结构(分支结构)循环结构已经证明,任何程序均可只用这三种结构综合描述只用这三种结构编制的程序,叫结构化程序程序必须符合结构化规则1/6/202388构成程序的三种基本结构顺序结构1/6/20236结构化程序设计的核心思想采用顺序、选择和循环三种基本结构作为程序设计的基本单元只有一个入口;只有一个出口;无死语句,即不存在永远都执行不到的语句;无死循环,即不存在永远都执行不完的循环。采用“自顶向下、逐步求精”和模块化的方法进行结构化程序设计1/6/202389结构化程序设计的核心思想采用顺序、选择和循环三种基本结构作为4.2顺序结构BANS图传统流程图BA1/6/2023904.2顺序结构BANS图传统流程图BA1/6/20238顺序结构——应用举例(1)例:设半径为1.5,求圆周长及面积。解:(1)问题分析:(算法)step1:给出圆的半径r=1.5step2:求圆的周长及面积step3:输出结果公式:圆周长=2*3.14*r圆面积=3.14*r*r1/6/202391顺序结构——应用举例(1)例:设半径为1.5,求圆周长及面积开始r=1.5L=2*3.14*rs=3.14*r*r输出L,s结束(2)画出流程图1/6/202392开始r=1.5L=2*3.14*rs=3.14*r*r输出#include<stdio.h>#definePI3.14main(){floatr,l,s;r=1.5;l=2*PI*r;s=PI*r*r;printf("\nl=%f,s=%f",l,s);}(3)根据流程图编程1/6/202393#include<stdio.h>(3)根据流程图编顺序结构——应用举例(2)例4.1设银行存款利率rate为2.25%,存款期为n年,本金为captial元,编程计算n年后的本利之和deposit解:(1)问题分析:(算法)step2:给出年n、本金captial(键盘输入)step3:n年后本利之和depositstep4:输出结果公式:deposit=captial*(1+rate)nstep1:给出存款利率rate1/6/202394顺序结构——应用举例(2)例4.1设银行存款利率rate为开始rate=0.0225输入n和captialdepoist=captial*(1+rate)n输出depoist结束(2)画出流程图1/6/202395开始rate=0.0225输入n和captialdepois(3)根据流程图编程#include<math.h>#include<stdio.h>main(){
intn;doublerate=0.0225;doublecapital,deposit;printf("pleaseenteryear,capital:");scanf("%d%lf",&n,&capital);deposit=capital*pow(1+rate,n);printf("deposit=%lf\n",deposit);}1/6/202396(3)根据流程图编程#include<math.h>1/以#开始的编译预处理命令
main(){局部变量说明语句;
执行语句;}简单的C程序结构框架1/6/202397以#开始的编译预处理命令简单的C程序结构框架1/6/2023编译预处理命令文件包含编译预处理命令#include指示编译系统将一个源文件嵌入到含有#include指令的源文件中该指令所在的位置处。使用形式:#include<头文件名>/"头文件名"注意:以#开头;每条一行;不是C语句1/6/202398编译预处理命令文件包含编译预处理命令#include指示编译查询情况编译预处理命令(1)用<>将头文件名括起,则在include子目录中查询(2)用"
"将头文件名括起,则先在当前目录中查找若无继续搜索C子目录。1/6/202399查询情况编译预处理命令(1)用<>将头文件名括起,则在(2)常用函数对应的头文件函数头文件名数学函数math.h字符串函数string.h输入、输出函数stdio.h动态存储分配函数stdlib.h/malloc.h1/6/2023100常用函数对应的头文件函数4.3选择结构作用:根据条件控制程序流向。条件的组成:问题的提出:各种类型的常量、变量、表达式(常用:关系/逻辑表达式)注意各种表达式的用法1/6/20231014.3选择结构作用:根据条件控制程序流向。条件的组成:问题简单分支选择(单分支)结构yesno语句A条件成立否条件表达式.T..F.语句格式:
if(表达式)语句/语句组;1/6/2023102简单分支选择(单分支)结构yesno语句A条件成立否条件表达双分支选择结构yesno程序段A程序段B条件成立否条件表达式.T..F.语句1语句2格式:If(表达式)语句1/语句组1;else语句2/语句组2;1/6/2023103双分支选择结构yesno程序段A程序段B条件成立否条件表达式多分支选择结构表达式语句1TF语句2表达式表达式语句3语句4TTFF表达式1语句1TF语句2表达式2表达式3语句3语句4TTFF1/6/2023104多分支选择结构表达式语句1TF语句2表达式表达式语句3语句4多分支选择结构
if(表达式)语句1;elseif(表达式2)语句2;:elseif(表达式m)语句m;else语句n;一般形式:1/6/2023105多分支选择结构if(表达式)语句1;一般形式:1/6/分支嵌套
if(表达式1)
if(表达式2)语句1;else语句2;
else
if(表达式3)语句3;else语句4;一般形式:1/6/2023106分支嵌套if(表达式1)一般形式:1/6/202324使用if语句需注意事项(1)条件判断表达式一定用圆括号括起。(2)复合语句必须用{}引起。(3)每一个else必须与一个if项匹配。(4)else总是与离它最近的if相匹配。1/6/2023107使用if语句需注意事项(1)条件判断表达式一定用圆括号括体型判断。按“体指数”对肥胖程度进行划分:体指数t=体重w/(身高h)2(w单位为公斤,h单位为米)当t<18时,为低体重;当t介于18和25之间时,为正常体重;当t介于25和27之间时,为超重体重;当t>=27时,为肥胖。编程从键盘输入你的身高h和体重w,根据给定公式计算体指数t,然后判断你的体重属于何种类型。用3种方法编程:算法1:用不带else子句的if语句编程(ex45_1)算法2:用在if子句中嵌入if语句的形式编程(ex45_2)算法3:用在else子句中嵌入if语句的形式编程(ex45_3)
例4.51/6/2023108体型判断。按“体指数”对肥胖程度进行划分:例4.51/6/2例:计算并输出下列分段函数值y=0x01x>0#include<stdio.h>main(){floatx,y;printf("inputx:");scanf("%f",&x);
y=0;if(x>0)y=1;printf("y=%f\n",y);}1/6/2023109例:计算并输出下列分段函数值y=0x0#inc用switch语句构成的多分支结构多路选择switch
(表达式)
{
case
常数1:
语句序列1;
case
常数2:
语句序列2;
…………
default:
语句序列3;
}default可以没有,但最好不省略不要忘记break1/6/2023110用switch语句构成的多分支结构多路选择1/6/2023例4.8编程设计一个简单的计算器程序。(ex48)要求根据用户从键盘输入的表达式:
操作数1运算符op操作数2计算表达式的值,指定的运算符为加(+)、减(-)、乘(*)、除(/)1/6/2023111例4.8编程设计一个简单的计算器程序。(ex48)1/6/2使用switch语句应注意(1)各常量表达式的值不可相同。(2)case后可有多个语句,不用{}括起。(3)常量表达式仅是一个语句标号。(4)各case及default子句的顺序可随意。(5)每个分支执行后,利用break语句跳出。1/6/2023112使用switch语句应注意(1)各常量表达式的值不可相同。4.4循环结构引入循环的目的:简化程序、提高编程效率三种循环方式当型循环直到型循环步长型循环1/6/20231134.4循环结构引入循环的目的:简化程序、提高编程效率三种循循环结构的流程图条件PA当型循环直到循环真假假条件PA假真假条件P条件PA假1/6/2023114循环结构的流程图条件PA当型循环直到循环真假假条件PA假循环语句——while一般形式:while(表达式)
{ 语句;}只要表达式的值为非0,就重复执行语句,直到表达式值为0时止先判断,后执行1/6/2023115循环语句——while一般形式:1/6/202333例:找出100以内的奇数。
main(){int
I=1;
while(I<=100)
{printf("%d",I);
I+=2;}}注意:(1)while构成的是“当型”循环。(2)循环体中一定有对于循环控制变量的操作。1/6/2023116例:找出100以内的奇数。main()注意:(1)whi循环语句——do-while一般形式:do
{
语句;
}while
(表达式);首先执行语句,然后判断表达式的值。如果表达式为0,继续向下执行,否则,再次执行语句,再次判断表达式的值语句会被至少执行一次1/6/2023117循环语句——do-while一般形式:1/6/20233例:找出100以内的奇数。
main(){int
I=1;
while(I<=100)
{printf("%d",I);
I+=2;}}
main(){int
I=1;
do
{printf("%d",I);
I+=2;}
while(I<=100);}1/6/2023118例:找出100以内的奇数。main()main()1/6循环语句——for一般形式:for(表达式1;表达式2;表达式3)
{ 语句;}表达式2执行循环体计算表达式1的值计算表达式3的值跳出循环TF工作过程:1/6/2023119循环语句——for一般形式:表达式2执行循环体计算表达式1有关for的说明(1)
for(表达式1;表达式2;表达式3)
{ 语句;}相当于:
表达式1;
while
(表达式2){
语句;
表达式3;
}1/6/2023120有关for的说明(1)for(表达式1;表达式2在for和while语句之后一般没有分号有分号表示循环体就是分号之前的内容(空循环体)while(i<100);
i++;for(i=0;i<100;i++);
printf("%d",i);for通常有一个循环变量控制循环的次数,不要在循环体内改变这个变量有关for的说明(2)1/6/2023121在for和while语句之后一般没有分号有关for的说明
for语句中的表达式1、表达式3可为逗号表达式。如:for(i=0,j=1;j<n&&i<n;i++,j++)表达式1和表达式3可以没有或者是用逗号分隔的多个表达式的组合。如:for(;i<=5;)有关for的说明(3)1/6/2023122for语句中的表达式1、表达式3可为逗号表达式。如:main(){floatx,sum;while(x!=9999){if(x<0.0)sum+=x;printf("\nsum=%f",sum);scanf("%f",&x);}scanf("%f",&x);}例:给定一组数据如下,编程对负数求和。12,45,67.8,-12.5,-35.67,567.89方法1:用while1/6/2023123main(){floatx,sum;while(x例:给定一组数据如下,编程对负数求和。12,45,67.8,-12.5,-35.67,567.89方法2:用formain()floatx,sum=0;for(i=1;i<=6;i++)if(x<0.0)sum+=x;}{scanf("%f",&x);printf("\nsum=%f",sum);inti;}{1/6/2023124例:给定一组数据如下,编程对负数求和。12,45,67.8,选择三种循环的一般原则如果循环次数已知,用for如果循环次数未知,用while如果循环体至少要执行一次,用do-while这只是“一般”原则,不是“原则”1/6/2023125选择三种循环的一般原则如果循环次数已知,用for1/6/20
猜数游戏:先由计算机“想”一个数请人猜,如果人猜对了,则计算机给出提示:“Right!”,否则提示:“Wrong!”,并告诉人所猜的数是大还是小。(ex46)例4.6分析:Step1:计算机想一个数;Step2:人猜一个数;Step3:判断三种情况并给出相应结果。1/6/2023126猜数游戏:先由计算机“想”一个数请人猜,如果人猜对了,猜数游戏用到的库函数(1)随机函数rand()#include<stdlib.h>RAND_MAX在stdlib.h中定义,不大于双字节整数的最大值32767产生[0,RAND_MAX]之间的随机数magic=rand();产生[0,b-1]之间的随机数magic=rand()%b;产生[a,a+b-1]之间的随机数magic=rand()%b+a;1/6/2023127猜数游戏用到的库函数(1)随机函数rand()1/6/202
猜数游戏:先由计算机“想”一个1到100之间的数请人猜,如果人猜对了,则结束游戏,否则计算机给出提示,告诉人所猜的数是太大还是太小,直到人猜对为止。计算机记录人猜的次数,以此来反映猜数者“猜”的水平。(ex49)例4.9运行程序发现问题每次运行程序,机器所想的数都是一样的;用函数rand所产生的随机数只是伪随机数。1/6/2023128猜数游戏:先由计算机“想”一个1到100之间的数请人猜猜数游戏用到的库函数(2)随机函数srand为函数rand()设置随机数种子来实现对函数rand所产生的伪随机数的“随机化”通过键入随机数种子,产生[0,100]之间的随机数scanf("%u",&seed);srand(seed);magic=rand()%100+1;改进例4.9(ex49_1)1/6/2023129猜数游戏用到的库函数(2)随机函数srand1/6/2023猜数游戏用到的库函数(3)随机函数srand:为函数rand()设置随机数种子来实现对其产生的伪随机数的“随机化”使用计算机读取其时钟值并把该值自动设置为随机数种子,产生[0,100]之间的随机数函数time()返回以秒计算的当前时间值,该值被转换为无符号整数并用作随机数发生器的种子#include<time.h>srand(time(NULL));magic=rand()%100+1;再改进例4.9(ex49_2)1/6/2023130猜数游戏用到的库函数(3)随机函数srand:为函数rand永远不会退出的循环为死循环for(;;){}while(1){}do
{}while(1);一般情况下,要极力避免死循环绝大多数程序不需要死循环。如果出现,往往都是bug时间过长的循环会造成“假死”效果,也要考虑解决死循环1/6/2023131永远不会退出的循环为死循环死循环1/6/202349例4.11国王的许诺相传国际象棋是古印度舍罕王的宰相达依尔发明的。舍罕王十分喜欢象棋,决定让宰相自己选择何种赏赐。位聪明的宰相指着8×8共64格的象棋盘说:陛下,请您赏给我一些麦子吧,就在棋盘的第一个格子中放1粒,第2格中放2粒,第3格放4粒,以后每一格都比前一格增加一倍,依此放完棋盘上的64个格子,我就感恩不尽了舍罕王让人扛来一袋麦子,他要兑现他的许诺。
国王能兑现他的许诺吗?试编程计算舍罕王共要多少麦子赏赐他的宰相,这些麦子合多少立方米?
(已知1立方米麦子约1.42e8粒)
总粒数为:sum=1+2+22+23+…+263
1/6/2023132例4.11国王的许诺相传国际象棋是古印度舍罕王的宰相达依尔#defineCONST1.42e8#include<stdio.h>#include<math.h>main(){
int
n;
double
term,sum=0;
/*累加求和变量赋初值*/
for
(n=1;n<=64;n++)
{
term=
pow(2,n-1);
/*根据累加项的规律计算累加项
*/
sum=sum+term;
/*作累加运算*/
}
printf("sum=%e\n",sum);/*打印总麦粒数*/
printf("volum=%e\n",sum/CONST);/*打印折合的总麦粒体积数*/}方法11/6/2023133#defineCONST1.42e8方法11/6/20方法2#defineCONST1.42e8/*定义符号常量CONST值为1.42e8*/#include<stdio.h>main(){
int
n;
double
term=1,sum=1;/*累乘求积、累加求和变量赋初值*/
for
(n=2;n<=64;n++)
{
term=term*2;/*根据后项总是前项的2倍计算累加项*/
sum=sum+term;
/*作累加运算*/
}
printf("sum=%e\n",sum);
/*打印总麦粒数*/
printf("volum=%e\n",sum/CONST);/*打印折合的总麦粒体积数*/}
1/6/2023134方法2#defineCONST1.42e8/循环嵌套结构形式for(){:while(){:do{:}while();}}1/6/2023135循环嵌套结构形式for(使用嵌套的循环时,应注意的问题在嵌套的各层循环体中,使用复合语句(即用一对大花括号将循环体语句括起来)保证逻辑上的正确性
内层和外层循环控制变量不应同名,以免造成混乱
嵌套的循环最好采用右缩进格式书写,以保证层次的清晰性
循环嵌套不能交叉,即在一个循环体内必须完整的包含着另一个循环
1/6/2023136使用嵌套的循环时,应注意的问题在嵌套的各层循环体中,使用复合合法的嵌套循环1/6/2023137合法的嵌套循环1/6/202355例4.14编程输出如下形式的九九表1/6/2023138例4.14编程输出如下形式的九九表1/6/202356#include<stdio.h>main(){ intm,n;
for(m=1;m<10;m++)
printf("%4d",m);/*打印表头*/
printf("\n");
for(m=1;m<10;m++)
printf("-"); prin
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 智能化远程检验报告在交通中断期的时效性
- GB-T 15342-2023 滑石粉标准规范
- 九年级数学下册-27.1-圆的认识-27.1.1-圆的基本元素讲义-(新版)华东师大版
- 2026年球宝复活测试题及答案
- 2026年销售岗位心里测试题及答案
- 2026年防汛抢险技术测试题及答案
- 2026年古诗《元日》测试题及答案
- 2026年语文园地测试题及答案
- 2026年发给男友的测试题及答案
- 旅游业客户投诉处理流程方案
- 国家义务教育检测质量监测八年级语文模拟测试题有答案
- 2025年天津市八年级地理生物会考真题试卷+解析及答案
- 2025年泸州市中考物理试卷真题(含答案解析)
- DB11T 695-2025 建筑工程资料管理规程
- GB/T 4450-1995船用盲板钢法兰
- 汽轮机TSI系统详解
- 建档立卡-退役军人信息登记表(基础电子档案)
- (部编版)统编四年级语文下册第六单元《习作:我学会了-》教学课件
- 除尘器拆除方案
- 实验室菌种运输、保存、使用与销毁管理制度
- 单位减少存档人员表
评论
0/150
提交评论