资源预览内容
第1页 / 共223页
第2页 / 共223页
第3页 / 共223页
第4页 / 共223页
第5页 / 共223页
第6页 / 共223页
第7页 / 共223页
第8页 / 共223页
第9页 / 共223页
第10页 / 共223页
亲,该文档总共223页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
测绘测绘C语言程序设计语言程序设计第五章第五章2第五章第五章 选择结构程序设计选择结构程序设计一、关系运算符和关系表达式一、关系运算符和关系表达式二、逻辑运算符和逻辑表达式二、逻辑运算符和逻辑表达式三、三、if语句语句四、四、switch语句语句五、程序举例五、程序举例3第五章第五章 选择结构程序设计选择结构程序设计一、关系运算符和关系表达式一、关系运算符和关系表达式p在现实生活中在现实生活中如果你在家,我去拜访你如果你在家,我去拜访你如果考试不及格,要补考如果考试不及格,要补考如果遇到红灯,要停车等待如果遇到红灯,要停车等待周末我们去郊游周末我们去郊游70岁以上的老年人,入公园免票岁以上的老年人,入公园免票p处理这些问题,关键在于进处理这些问题,关键在于进行行条件判断条件判断p由于程序处理问题的需要,由于程序处理问题的需要,在大多数程序中都会包含选择在大多数程序中都会包含选择结构,需要在进行结构,需要在进行下一个操作下一个操作之前先进行条件判断之前先进行条件判断4第五章第五章 选择结构程序设计选择结构程序设计一、关系运算符和关系表达式一、关系运算符和关系表达式例 求ax2+bx+c=0方程的根。 分析分析分析分析:由键盘输入由键盘输入a,b,c。假设。假设a,b,c的值任意,并不保证的值任意,并不保证b2-4ac0。需要在程序中进。需要在程序中进行判别,如果行判别,如果b2-4ac0,就计算并输出方程的两,就计算并输出方程的两个实根,否则就输出个实根,否则就输出“方方程无实根程无实根”的信息。的信息。输入输入a,b,c计算计算discdisc0计算计算x1,x2输出无实根输出无实根输出输出x1,x2真真假假5第五章第五章 选择结构程序设计选择结构程序设计一、关系运算符和关系表达式一、关系运算符和关系表达式1、关系运算符及其优先级、关系运算符及其优先级p优先级相同优先级相同(高高):(小于小于)=(小于或等于小于或等于)(大于大于)=(大于或等于大于或等于)p优先级相同优先级相同(低低):=(等于等于)!=(不等于不等于)说明说明:p关系运算符的优先级关系运算符的优先级低于低于算术运算符算术运算符p关系运算符的优先级关系运算符的优先级高于高于赋值运算符赋值运算符ca+b等效于等效于c(a+b)ab=c等效于等效于(ab)=ca=bc等效于等效于a=(bc等效于等效于a=(bc)6第五章第五章 选择结构程序设计选择结构程序设计一、关系运算符和关系表达式一、关系运算符和关系表达式2、关系表达式、关系表达式p用用关关系系运运算算符符将将两两个个表表达达式式(可可以以是是算算术术表表达达式式或或关关系系表表达达式式,逻辑表达式,赋值表达式,逻辑表达式,赋值表达式,字符字符表达式表达式)连接起来的式子连接起来的式子p关系表达式的关系表达式的值是一个逻辑值值是一个逻辑值,即,即“真真”或或“假假”p在在C的的逻逻辑辑运运算算中中,以以“”代代表表“真真”,以以“”代代表表“假假”C语言中没有语言中没有专用的逻辑值专用的逻辑值ab,a+bb+c,(a=3)(b=5),ab)(bb的值为的值为“真真”,表达式,表达式的值为的值为1p对字符比较对字符比较:比较其比较其ASCIIp不可比较字符串不可比较字符串7第五章第五章 选择结构程序设计选择结构程序设计二、逻辑运算符和逻辑表达式二、逻辑运算符和逻辑表达式1、逻辑运算符及其优先级、逻辑运算符及其优先级p3种逻辑运算符:种逻辑运算符:&(逻辑与逻辑与)相当于其他语言中的相当于其他语言中的AND|(逻辑或逻辑或)相当于其他语言中的相当于其他语言中的OR!(逻辑非逻辑非)相当于其他语言中的相当于其他语言中的NOTa&b若若a,b为真,则为真,则a&b为真。为真。a|b若若a,b之一为真,则之一为真,则a|b为真。为真。!a若若a为真,则为真,则!a为假。为假。双目双目(元元)运算符运算符一一目目(元元)运算符运算符8第五章第五章 选择结构程序设计选择结构程序设计二、逻辑运算符和逻辑表达式二、逻辑运算符和逻辑表达式1、逻辑运算符及其优先级、逻辑运算符及其优先级p3种逻辑运算符:种逻辑运算符:9第五章第五章 选择结构程序设计选择结构程序设计二、逻辑运算符和逻辑表达式二、逻辑运算符和逻辑表达式1、逻辑运算符及其优先级、逻辑运算符及其优先级p逻辑运算符优先级:逻辑运算符优先级:!(非非)&(与与)|(或或)逻逻辑辑运运算算符符中中的的“&”和和“|”低低于于关关系系运运算算符,符,“!”高于算术运算符高于算术运算符(ab)&(xy)可写成可写成ab&xy(a=b)|(x=y)可写成可写成a=b|x=y(!a)|(ab)可写成可写成!a|ab10第五章第五章 选择结构程序设计选择结构程序设计二、逻辑运算符和逻辑表达式二、逻辑运算符和逻辑表达式2、逻辑表达式、逻辑表达式p逻辑表达式逻辑表达式:用逻辑运算符将关系表达式或逻辑量连接起来的式子用逻辑运算符将关系表达式或逻辑量连接起来的式子p逻辑表达式的值应该是一个逻辑量逻辑表达式的值应该是一个逻辑量“真真”(1)或或“假假”(0)设设a=4,b=5:!a的值为的值为a&b的的值为值为a|b的值为的值为!a|b的值为的值为4&0|2的值为的值为p在在判断判断一个量是否为一个量是否为“真真”时,时,以以0代表代表“假假”,以非,以非0代表代表“真真”。0111111第五章第五章 选择结构程序设计选择结构程序设计二、逻辑运算符和逻辑表达式二、逻辑运算符和逻辑表达式2、逻辑表达式、逻辑表达式p在在一一个个表表达达式式中中不不同同位位置置上上出出现现数数值值,应应区区分分哪哪些些是是作作为为数数值值运运算算或关系运算的对象,哪些作为逻辑运算的对象。或关系运算的对象,哪些作为逻辑运算的对象。53&84-!01&0逻辑值为逻辑值为083逻辑值为逻辑值为1表达式值为表达式值为012第五章第五章 选择结构程序设计选择结构程序设计二、逻辑运算符和逻辑表达式二、逻辑运算符和逻辑表达式2、逻辑表达式、逻辑表达式13第五章第五章 选择结构程序设计选择结构程序设计二、逻辑运算符和逻辑表达式二、逻辑运算符和逻辑表达式2、逻辑表达式、逻辑表达式p在逻辑表达式的求解中,并不是所有的逻辑运算符都要被执行在逻辑表达式的求解中,并不是所有的逻辑运算符都要被执行a&b&c只有只有a为真时,才需要判断为真时,才需要判断b的值,只有的值,只有a和和b都为真时,才需要判断都为真时,才需要判断c的值。的值。a|b|c只要只要a为真,就不必判断为真,就不必判断b和和c的值,只有的值,只有a为假,为假,才判断才判断b。a和和b都为假才判断都为假才判断c设设:a=1,b=2,c=3,d=4,m=1,n=1(m=ab)&(n=cd)说明说明:p由于由于ab的值为的值为0,因此,因此m=0,而,而n=cd不被执行,因此不被执行,因此n的值不是的值不是0而仍保持原而仍保持原值值1。14第五章第五章 选择结构程序设计选择结构程序设计二、逻辑运算符和逻辑表达式二、逻辑运算符和逻辑表达式2、逻辑表达式、逻辑表达式例 用逻辑表达式来表示闰年的条件。 分析分析:闰年条件:闰年条件p能被能被4整除,但不能被整除,但不能被100整除。整除。p能被能被4整除,又能被整除,又能被400整除。整除。(year%4=0&year%100!=0)|year%400=0 !(year4=0&year100!=0)|year400=0) 如果表达式值为如果表达式值为1,则闰年;,则闰年;否则为非闰年否则为非闰年 如果表达式值为如果表达式值为1,则非闰年;,则非闰年;否则为闰年否则为闰年 (year4!=0)|(year100=0&year400!=0) 如果表达式值为如果表达式值为1,则非闰年;,则非闰年;否则为闰年否则为闰年 15第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句1、if语句的三种形式语句的三种形式pif(表达式表达式)语句语句pif(表达式表达式)语句语句1else语句语句2pif(表达式表达式1)语句语句1elseif(表达式表达式2)语句语句2elseif(表达式表达式3)语句语句3elseif(表达式表达式m)语句语句melse语句语句np关系表达式关系表达式p逻辑表达式逻辑表达式p数值表达式数值表达式if(a=b&x=y)printf(“a=b,x=y”)if(3)printf(K);if(a)printf(d,a)p整个整个if语句可写在多行上语句可写在多行上,也可写也可写在一行上在一行上,但都是一个整体,属于但都是一个整体,属于同一个语句同一个语句16第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句1、if语句的三种形式语句的三种形式pif(表达式表达式)语句语句pif(表达式表达式)语句语句1else语句语句2if(xy)printf(“d”,x);if(xy)printf(d,x);elseprintf(d,y);17第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句1、if语句的三种形式语句的三种形式pif(表达式表达式1)语句语句1elseif(表达式表达式2)语句语句2elseif(表达式表达式3)语句语句3elseif(表达式表达式m)语句语句melse语句语句np“语句语句1”“语句语句m”是是if中的内嵌中的内嵌语句语句,内嵌语句也可以是一个内嵌语句也可以是一个if语句语句18第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句1、if语句的三种形式语句的三种形式;elsecost=0;else;else;else;elsecost=0;19第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句1、if语句的三种形式语句的三种形式p在在if和和else后后面面可可以以只只含含一一个个内内嵌嵌的的操操作作语语句句,也也可可以以有有多多个个操操作作语语句,此时用花括号句,此时用花括号“”将几个语句括起来成为一个将几个语句括起来成为一个复合语句复合语句if(abc&bca&cab)s=0.5*(a+b+c);area=sqrt(S*(S-a)*(S-b)*(S-c);printf(area=6.2f,area);elseprintf(Itisnotatrilateral);20第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句例5.1 输入两个实数,按代数值由小到大的次序输出这两个数。 AB互换前AB互换后分析分析:p只需要做一次比较,然后进行一次只需要做一次比较,然后进行一次交换即可交换即可p用用if语句实现条件判断语句实现条件判断p关键是怎样实现两个变量值的互换关键是怎样实现两个变量值的互换21第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句例5.1 输入两个实数,按代数值由小到大的次序输出这两个数。 分析分析:p只需要做一次比较,然后进行一次只需要做一次比较,然后进行一次交换即可交换即可p用用if语句实现条件判断语句实现条件判断p关键是怎样实现两个变量值的互换关键是怎样实现两个变量值的互换ABC22第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句例5.1 输入两个实数,按代数值由小到大的次序输出这两个数。 分析分析:p只需要做一次比较,然后进行一次只需要做一次比较,然后进行一次交换即可交换即可p用用if语句实现条件判断语句实现条件判断p关键是怎样实现两个变量值的互换关键是怎样实现两个变量值的互换ABC23第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句例5.1 输入两个实数,按代数值由小到大的次序输出这两个数。 分析分析:p只需要做一次比较,然后进行一次只需要做一次比较,然后进行一次交换即可交换即可p用用if语句实现条件判断语句实现条件判断p关键是怎样实现两个变量值的互换关键是怎样实现两个变量值的互换ABC24第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句例5.1 输入两个实数,按代数值由小到大的次序输出这两个数。#includevoid main() float a, b, t; scanf(“%f,%f,&a,&b); if(ab) t=a; a=b; b=t; printf(“%5.2f, %5.2f“, a, b); 说明说明:pif(ab):判断两数大小,选择结构,判断两数大小,选择结构,用用if语句实现的语句实现的pt=a;a=b;b=t;:将将a和和b的值互换的值互换25第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句例输入3个数a,b,c,要求按由小到大的顺序输出。#include int main() float a,b,c,t; scanf(%f,%f,%f,&a,&b,&c); if(ab) t=a; a=b; b=t; if(ac) t=a; a=c; c=t; if(bc) t=b; b=c; c=t; printf(%5.2f,%5.2f,%5.2fn,a,b,c); return 0; 分析分析:pifab,a和和b对换对换(a是是a、b中的小者)中的小者)pifac,a和和c对换对换(a是三者中最小者)是三者中最小者)pifbc,b和和c对换对换(b是三者中次小者)是三者中次小者)p顺序输出顺序输出a,b,c26第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句2、if语句的嵌套语句的嵌套p在在if语句中又包含一个或多个语句中又包含一个或多个if语句称为语句称为if语句的嵌套语句的嵌套if()if()语句语句1else语句语句2elseif()语句语句3else语句语句4 p注意注意if与与else的配对关系的配对关系pelse总是与它上面的总是与它上面的最近的未配最近的未配对对if配对配对if()if()语句语句1elseif()语句语句2else语句语句3内内嵌嵌if内内嵌嵌if内内嵌嵌if分析分析:p第一个第一个else是与第二个是与第二个if配对配对p最好使内嵌最好使内嵌if语句也包含语句也包含else部分,这样部分,这样if的数目和的数目和else的数目相同的数目相同,从内层到外层从内层到外层一一对应一一对应,不致出错。不致出错。p如果如果if与与else的数目不一样的数目不一样,加花括弧来确加花括弧来确定配对关系定配对关系27第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句2、例有一函数:编一程序, 输入一个x值,输出y值。#include void main() int x,y; scanf(%d,&x); if(x0) y=-1; if(x=0) y=0;if(x0) y=1; printf(x=%d,y=%dn, x, y); 分析分析:p输入输入x若若x0y=1;输出输出y 28第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句2、例有一函数:编一程序, 输入一个x值,输出y值。#include void main() int x,y; scanf(d,&x); if(x0) y=-1; else if(x=0) y=0;else y=1; printf(x=d,y=dn,x,y); 分析分析:p输入输入x若若x0y=1;输出输出y 29第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句2、例有一函数:编一程序, 输入一个x值,输出y值。#include void main() int x,y; scanf(d,&x); if(x=0) if(x0) y=1; else y=0 else y=-1; printf(x=d,y=dn,x,y); 30第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句2、例有一函数:编一程序, 输入一个x值,输出y值。#include void main() int x,y; scanf(d,&x); y=-1; if(x!=0) if(x0)y=1; else y=0; printf(x=d,y=dn,x,y); if(x0)y=1;31第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句3、条件运算符条件运算符p若若if语语句句中中,在在表表达达式式为为“真真”和和“假假”时时,且且都都只只执执行行一一个个赋赋值值语语句给同一个变量赋值时句给同一个变量赋值时,可以用简单的条件运算符来处理,可以用简单的条件运算符来处理p三目三目(元元)运算符,运算符,C语言中唯一的一个三目运算符语言中唯一的一个三目运算符if(ab)max=a;elsemax=b;max=(ab)?a:b;表达式表达式1?表达式表达式2:表达式表达式3p数值表达式数值表达式p赋值表达式赋值表达式p函数表达式函数表达式32第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句3、条件运算符条件运算符p优先级和结合性优先级和结合性:条件运算符条件运算符优先优先于赋值运算符于赋值运算符条件运算符的优先级别比关系运算符和算术运算符都条件运算符的优先级别比关系运算符和算术运算符都低低条件运算符的结合方向为条件运算符的结合方向为“自右至左自右至左”max=(ab)?a:bmax=ab?a:bab?a:b+1ab?a:(b+1)(ab?a:b)+133第五章第五章 选择结构程序设计选择结构程序设计三、三、if语句语句3、条件运算符条件运算符条件表达式中,表达式条件表达式中,表达式1的类型可以与表达式的类型可以与表达式2和表达式和表达式3的类型不同的类型不同例5.4 用条件表达式来处理,当字母是大写时,转换成小写字母,否则不转换。#include void main() char ch; scanf(%c,&ch); ch=(ch=A & ch=Z )?(ch+32):ch; printf(%cn,ch); 34第五章第五章 选择结构程序设计选择结构程序设计四、四、switch语句语句p学生成绩分类学生成绩分类85分以上为分以上为A等等7084分为分为B等等6069分为分为C等等p人口统计分类人口统计分类:按年龄分为老、中、青、少、儿童按年龄分为老、中、青、少、儿童35第五章第五章 选择结构程序设计选择结构程序设计四、四、switch语句语句pSwitch语句语句:多分支选择语句多分支选择语句switch语句的作用是根据表达式的值,使流程跳转到不同的语句语句的作用是根据表达式的值,使流程跳转到不同的语句执行完一个执行完一个case后面的语句后,后面的语句后,流程控制转移到下一个流程控制转移到下一个case继续执行继续执行switch(表达式表达式)case常量表达式常量表达式1:语句语句1case常量表达式常量表达式2:语句语句2case常量表达式常量表达式n:语句语句ndefault:语句语句n+1p整型整型p字符型字符型p枚举型枚举型不能相同不能相同36第五章第五章 选择结构程序设计选择结构程序设计四、四、switch语句语句pSwitch语句语句:多分支选择语句多分支选择语句break语语句句:在在执执行行一一个个case分分支支后后,使使流流程程跳跳出出switch结结构构,终终止止switch语句的执行语句的执行多个多个case可以共用一组执行语句可以共用一组执行语句casea:caseb:casec:printf(60n);break;37第五章第五章 选择结构程序设计选择结构程序设计四、四、switch语句语句switch(grade)caseA:printf(85100n);break;caseB:printf(7084n);break;caseC:printf(6069n);break;caseD:printf(60n);break;default:printf(Enterdataerror!n);值为A38第五章第五章 选择结构程序设计选择结构程序设计四、四、switch语句语句switch(grade)caseA:printf(85100n);break;caseB:printf(7084n);break;caseC:printf(6069n);break;caseD:printf(60n);break;default:printf(Enterdataerror!n);值为C39第五章第五章 选择结构程序设计选择结构程序设计四、四、switch语句语句switch(grade)caseA:printf(85100n);break;caseB:printf(7084n);break;caseC:printf(6069n);break;caseD:printf(60n);break;default:printf(Enterdataerror!n);值为F40第五章第五章 选择结构程序设计选择结构程序设计四、四、switch语句语句switch(grade)caseA:printf(85100n);break;caseB:printf(7084n);break;caseC:printf(6069n);break;caseD:printf(60n);break;default:printf(Enterdataerror!n);值为A851007084606960Enterdataerror!41第五章第五章 选择结构程序设计选择结构程序设计五、程序举例五、程序举例例5.5 判断某一年是否闰年。#includevoidmain()intyear,leap;printf(enteryear:);scanf(%d,&year);if(year%4=0)if(year%100=0)if(year%400=0)leap=1;elseleap=0;elseleap=1;elseleap=0;if(leap)printf(%dis,year);elseprintf(%disnot,year);printf(aleapyear.n);标志变量标志变量与与if(leap!=0)含含义相同相同采取锯齿形式采取锯齿形式if(year%4!=0)leap=0;elseif(year%100!=0)leap=1;elseif(year%400!=0)leap=0;elseleap=1;if(year%4=0&year%100!=0)|(year%400=0)leap=1;elseleap=0;42第五章第五章 选择结构程序设计选择结构程序设计五、程序举例五、程序举例例5.6 求ax2+bx+c=0 方程的解。#include#includevoidmain()floata,b,c,disc,x1,x2,realpart,imagpart;scanf(“%f,%f,%f,&a,&b,&c);printf(Theequation);if(fabs(a)0,有两个不等实根,有两个不等实根;b2-4ac0,有两个共轭复根,有两个共轭复根;p应当以应当以p+qi和和p-qi的形式输出复的形式输出复根根:其中其中, p=-b/2a,q=()/2a实型不能用型不能用if(a=0)43第五章第五章 选择结构程序设计选择结构程序设计五、程序举例五、程序举例elsedisc=b*b-4*a*c;if(fabs(disc)1e-6)x1=(-b+sqrt(disc)/(2*a);x2=(-b-sqrt(disc)/(2*a);printf(hasdistinctrealroots:%8.4fand%8.4fn,x1,x2);elserealpart=-b/(2*a);imagpart=sqrt(-disc)/(2*a);printf(hascomplexroots:n);printfin,realpart,imagpart);printfin,realpart,imagpart);先算先算disc,以减少重复计算,以减少重复计算不能用不能用if(disc=0)44第五章第五章 选择结构程序设计选择结构程序设计五、程序举例五、程序举例例5.7 运输公司对用户计算运输费用。分析分析:p标准如下标准如下: s 250没有折扣没有折扣250s5002%折扣折扣500s10005%折扣折扣1000s 20008%折扣折扣2000s300010%折扣折扣3000s 15%折扣折扣p解题思路解题思路:(1)设每吨每千米货物的基本运费为设每吨每千米货物的基本运费为p,货物重为,货物重为w,距离为,距离为s,折扣,折扣为为d(2)总运费总运费f的计算公式为的计算公式为f=pws(1-d)45第五章第五章 选择结构程序设计选择结构程序设计五、程序举例五、程序举例例5.7 运输公司对用户计算运输费用。分析分析:p折扣的变化规律(参见教材图折扣的变化规律(参见教材图):折扣的折扣的“变化点变化点”都是都是250的倍数的倍数在横轴上加一种坐标在横轴上加一种坐标c,c的值为的值为s/250,c代表代表250的倍数的倍数当当c1时,表示时,表示s250,无折扣,无折扣当当1c2时,表示时,表示250s500,折扣,折扣d=2%当当2c4时,时,d=5%当当4c8时,时,d=8%当当8c12时,时,d=10%当当c12时,时,d=15%46第五章第五章 选择结构程序设计选择结构程序设计五、程序举例五、程序举例#includevoidmain()intc,s;floatp,w,d,f;printf(Pleaseenterprice,weight,distance:);scanf(%f,%f,%d,&p,&w,&s);if(s=3000)c=12;elsec=s/250;说明说明:pintc,s:将将c和和s定义为整型,定义为整型,保证保证c的值为整数的值为整数pif(s=3000)c=12:保证保证c不不随随s的增大而增大的增大而增大47第五章第五章 选择结构程序设计选择结构程序设计五、程序举例五、程序举例switch(c)case0:d=0;break;case1:d=2;break;case2:case3:d=5;break;case4:case5:case6:case7:d=8;break;case8:case9:case10:case11:d=10;break;case12:d=15;break;f=p*w*s*(1-d/);printf(freight=%fn,f);当当c1时,时, d=0%当当1c2时,时,d=2%当当2c4时,时,d=5%当当4c8时,时,d=8%当当8c12时,时,d=10%当当c12时,时,d=15%48第五章第五章 选择结构程序设计选择结构程序设计补充补充:这不是这不是Bug,而是语言特性而是语言特性Bugs are by far the largest and most successful class of entity, with nearly a million known species. In this respect they outnumber all the other known creatures about four to one.Professor Snopes Encyclopedia of Animal lifeBug是迄今为止地球上最庞大最成功的实体类型,有近百万种已知的是迄今为止地球上最庞大最成功的实体类型,有近百万种已知的品种。在这个方面,它比其他任何已知的生物种类的总和还要多,而且至品种。在这个方面,它比其他任何已知的生物种类的总和还要多,而且至少多出少多出4倍。倍。摘自摘自Snope教授的教授的Encyclopedia of Animal life49第五章第五章 选择结构程序设计选择结构程序设计补充补充:这不是这不是Bug,而是语言特性而是语言特性50第五章第五章 选择结构程序设计选择结构程序设计习题 #includemain()main()floatscore;chargrade;printf(请输入学生成绩:请输入学生成绩:);scanf(%f,&score);while(score100|score0)printf(n输入有误输入有误,请重新输入:请重新输入:);scanf(%f,&score); switch(int)(score/10)case10:case9:grade=A;break;case8:grade=B;break;case7:grade=C;break;case6:grade=D;break;case5:case4:case3:case2:case1:case0:grade=E;printf(成绩是,相应的等级是成绩是,相应的等级是%c。n,score,grade); 习题 #includemain()longintnum;intindiv,ten,hundred,thousand,ten_thousand,place;/*分别代表个位、十位、百位、千位、万分别代表个位、十位、百位、千位、万位和位数位和位数*/printf(请输入一个整数(请输入一个整数(099999):):);scanf(%ld,&num);if(num9999)place=5;elseif(num999)place=4;elseif(num99)place=3;elseif(num9)place=2;elseplace=1;printf(place=%dn,place); ten_thousand=num/10000;thousand=num/1000%10;hundred=num/100%10;ten=num%100/10;indiv=num%10;switch(place)case5:printf(%d,%d,%d,%d,%d,ten_thousand,thousand,hundred,ten,indiv);printf(n反序数字为;反序数字为;);printf(%d%d%d%d%dn,indiv,ten,hundred,thousand,ten_thousand);break;case4:printf(%d,%d,%d,%d,thousand,hundred,ten,indiv);printf(n反序数字为:反序数字为:);printf(%d%d%d%dn,indiv,ten,hundred,thousand);break;case3:printf(%d,%d,%d,hundred,ten,indiv);printf(n反序数字为:反序数字为:);printf(%d%d%dn,indiv,ten,hundred);break;case2:printf(%d,%d,ten,indiv);printf(n反序数字为:反序数字为:);printf(%d%dn,indiv,ten);break;case1:printf(%d,indiv);printf(n反序数字为:反序数字为:);printf(%dn,indiv);break;测绘测绘C语言程序设计语言程序设计第六章第六章55第六章第六章 循环结构程序设计循环结构程序设计一、概述一、概述二、用二、用while语句实现循环语句实现循环三、用三、用dowhile语句实现循环语句实现循环四、用四、用for语句实现循环语句实现循环五、循环的嵌套五、循环的嵌套六、几种循环的比较六、几种循环的比较七、七、break语句和语句和continue语句语句八、程序举例八、程序举例56第六章第六章 循环结构程序设计循环结构程序设计一、概述一、概述p在在现现实实生生活活中中或或是是在在程程序序所所处处理理的的问问题题中中常常常常遇遇到到需需要要重重复复处处理理的问题的问题要向计算机输入测绘要向计算机输入测绘C程序设计课程程序设计课程61个学生的成绩个学生的成绩分别统计测绘分别统计测绘1301、1302、地信、地信1301班的平均成绩班的平均成绩教师检查教师检查84个学生的成绩是否及格个学生的成绩是否及格p大多数的应用程序都会大多数的应用程序都会包含循环结构包含循环结构p循循环环结结构构和和顺顺序序结结构构、选选择择结结构构是是结结构构化化程程序序设设计计的的三三种种基基本本结构,它们是各种复杂程序的基本构造单元结构,它们是各种复杂程序的基本构造单元57第六章第六章 循环结构程序设计循环结构程序设计一、概述一、概述p用用goto语句和语句和if语句构成循环语句构成循环p用用while语句语句p用用dowhile语句语句p用用for语句语句58第六章第六章 循环结构程序设计循环结构程序设计二、用二、用while语句实现循环语句实现循环pwhile语句的一般形式如下语句的一般形式如下pwhile循环的特点是:先判断条件表达式,后执行循环体语句循环的特点是:先判断条件表达式,后执行循环体语句while(表达式表达式)语句语句“真真”时执行循环体语句时执行循环体语句“假假”时不执行时不执行59第六章第六章 循环结构程序设计循环结构程序设计二、用二、用while语句实现循环语句实现循环例6.2 求 。 分析分析:p这是累加问题,需要先后将这是累加问题,需要先后将100个数相个数相加加p要重复要重复99次加法运算,可用循环实现次加法运算,可用循环实现p后一个数是前一个数加后一个数是前一个数加1而得而得p加完上一个数加完上一个数i后,使后,使i加加1可得到下一个可得到下一个数数60第六章第六章 循环结构程序设计循环结构程序设计二、用二、用while语句实现循环语句实现循环例#includevoidmain()inti=1,sum=0;while(i=100)sum=sum+i;i+;printf(sum=%dn,sum); 说明说明:p循环体如果包含一个以上的语句,应循环体如果包含一个以上的语句,应该用该用花括弧花括弧括起来,以复合语句形式括起来,以复合语句形式出现。如果不加花括弧,则出现。如果不加花括弧,则while语句语句的范围只到的范围只到while后面第一个分号处。后面第一个分号处。p在循环体中应有使循环在循环体中应有使循环趋向于结束趋向于结束的的语句。语句。不能少不能少复合语句复合语句不能丢,否则不能丢,否则循循环永不结束环永不结束61第六章第六章 循环结构程序设计循环结构程序设计三、用三、用dowhile语句实现循环语句实现循环pdo-while语句的一般形式为:语句的一般形式为:pdowhile语语句句的的特特点点:先先无无条条件件地地执执行行循循环环体体,然然后后判判断断循循环环条件是否成立条件是否成立do语语句句while(表达式表达式);表达式表达式YN循环体语句循环体语句62第六章第六章 循环结构程序设计循环结构程序设计三、用三、用dowhile语句实现循环语句实现循环例用dowhile语句求 。 i100YNsum=sum+ii=i+1sum=0i=1i=1;sum=0;dosum=sum+i;i+;while(i=100);63第六章第六章 循环结构程序设计循环结构程序设计三、用三、用dowhile语句实现循环语句实现循环例用dowhile语句求 。#includevoidmain()inti=1,sum=0;dosum=sum+i;i+;while(i=100);printf(sum=%dn,sum); 说明说明:p对同一个问题可以用对同一个问题可以用while语句处理,语句处理,也可以用也可以用dowhile语句处理。语句处理。dowhile语句结构可以转换成语句结构可以转换成while结结构。构。64第六章第六章 循环结构程序设计循环结构程序设计例6.4 while和dowhile循环的比较。 #includevoidmain()inti,sum=0;printf(“i=?”);scanf(“%d”,&i);while(i=10)sum=sum+i;i+;printf(“sum=%dn,sum);#includevoidmain()inti,sum=0;printf(“i=?”);scanf(“%d”,&i);dosum=sum+i;i+;while(i=10);printf(“sum=%dn,sum);i=?1sum=55 i=?11sum=0 i=?1sum=55 i=?11sum=11 当当while后面的表达式的第一次的值后面的表达式的第一次的值为为“真真”时,两种循环得到的结果相时,两种循环得到的结果相同;否则不相同同;否则不相同65第六章第六章 循环结构程序设计循环结构程序设计四、用四、用for语句实现循环语句实现循环pfor语语句句不不仅仅可可以以用用于于循循环环次次数数已已经经确确定定的的情情况况,还还可可以以用用于于循循环次数不确定环次数不确定而只给出循环结束条件的情况而只给出循环结束条件的情况pfor语句完全可以代替语句完全可以代替while语句语句pfor语句的一般形式为:语句的一般形式为:for(表达式表达式1;表达式表达式2;表表达式达式3)语句语句设置初始条件,只执行一设置初始条件,只执行一次。可以为次。可以为零个零个、一个一个或或多个多个变量设置初值变量设置初值执行执行循环条件表达式,用来判定是否继续循环条件表达式,用来判定是否继续循环。在循环。在每次执行循环体前先执行此每次执行循环体前先执行此表达式表达式,决定是否继续执行循环,决定是否继续执行循环作为循环的调整器,例如作为循环的调整器,例如使循环变量增值,它是在使循环变量增值,它是在执行完循环体后才进行执行完循环体后才进行的的66第六章第六章 循环结构程序设计循环结构程序设计四、用四、用for语句实现循环语句实现循环pfor语句的执行过程:语句的执行过程:(1)求解表达式求解表达式1(2)求求解解表表达达式式2,若若其其值值为为真真,执执行行循循环环体体,然然后后执执行行第第(3)步步。若若为为假,则结束循环,转到第假,则结束循环,转到第(5)步步(3)求解表达式求解表达式3(4)转回上面步骤转回上面步骤(2)继续执行继续执行(5)循环结束,执行循环结束,执行for语句下面的一个语句语句下面的一个语句for(表达式表达式1;表达式表达式2;表表达式达式3)语句语句67第六章第六章 循环结构程序设计循环结构程序设计四、用四、用for语句实现循环语句实现循环p表达式表达式1省略:省略:p表达式表达式1与循环变量无关与循环变量无关for(表达式表达式1;表达式表达式2;表表达式达式3)语句语句一个或两个或三个表达式均一个或两个或三个表达式均可以省略可以省略for(;i=100;i+)sum=sum+i;for(sum=0;i=100;i+)sum=sum+i; 68第六章第六章 循环结构程序设计循环结构程序设计四、用四、用for语句实现循环语句实现循环p表达式表达式2省略:省略:for(表达式表达式1;表达式表达式2;表表达式达式3)语句语句一个或两个或三个表达式均一个或两个或三个表达式均可以省略可以省略for(i=1;i+)sum=sum+i; 69第六章第六章 循环结构程序设计循环结构程序设计四、用四、用for语句实现循环语句实现循环p表达式表达式3省略:省略:for(表达式表达式1;表达式表达式2;表表达式达式3)语句语句一个或两个或三个表达式均一个或两个或三个表达式均可以省略可以省略for(i=1;i=100;)sum=sum+i; for(i=1;i=100;)sum=sum+i;i+; 当表达式当表达式3省略时,省略时,此时程序设计者应此时程序设计者应另外设法保证循环另外设法保证循环能正常结束能正常结束for(i=1,sum=0;i=100;i+)sum=sum+i;70第六章第六章 循环结构程序设计循环结构程序设计四、用四、用for语句实现循环语句实现循环p表表达达式式1和和表表达达式式3可可以以是是一一个个简简单单的的表表达达式式,也也可可以以是是逗逗号号表表达式达式p表表达达式式可可以以为为关关系系表表达达式式、逻逻辑辑表表达达式式,也也可可以以是是数数值值表表达达式式或字符表达式,只要其值为非零,就执行循环体或字符表达式,只要其值为非零,就执行循环体 for(i=0,j=100;i=j;i+,j-)k=i+j; for(;(c=getchar()!=n;)printf(%c,c);for(i=0;(c=getchar()!=n;i+=c);71第六章第六章 循环结构程序设计循环结构程序设计五、循环的嵌套五、循环的嵌套p一个循环体内又包含另一个完整的循环结构,称为一个循环体内又包含另一个完整的循环结构,称为循环的嵌套循环的嵌套p内嵌的循环中还可以嵌套循环,这就是多层循环内嵌的循环中还可以嵌套循环,这就是多层循环p3种循环种循环(while循环、循环、dowhile循环和循环和for循环循环)可以互相嵌套可以互相嵌套while()while()dodowhile();while();for(;)for(;)while()dowhile();for(;)while()dofor(;)while();72第六章第六章 循环结构程序设计循环结构程序设计六、几种循环的比较六、几种循环的比较p一般情况下一般情况下,3种循环可以互相代替种循环可以互相代替p在在while和和dowhile循循环环中中,循循环环体体应应包包含含使使循循环环趋趋于于结结束束的的语语句句。p用用while和和dowhile循循环环时时,循循环环变变量量初初始始化化的的操操作作应应在在while和和dowhile语语句句之之前前完完成成。而而for语语句句可可以以在在表表达达式式1中中实实现现循循环变量的初始化。环变量的初始化。pwhile循循型型、dowhile循循环环和和for循循环环,可可以以用用break语语句句跳跳出出循循环环,用,用continue语句结束本次循环语句结束本次循环73第六章第六章 循环结构程序设计循环结构程序设计七、七、break语句和语句和continue语句语句1、break语句语句pbreak语语句句可可以以用用来来从从循循环环体体内内跳跳出出循循环环体体,即即提提前前结结束束循循环环,接接着执行循环下面的语句着执行循环下面的语句pbreak语句不能用于循环语句和语句不能用于循环语句和switch语句之外的任何其他语句中语句之外的任何其他语句中for(r=1;r100)break;printf(%f,area);74第六章第六章 循环结构程序设计循环结构程序设计七、七、break语句和语句和continue语句语句2、continue语句语句pcontinue语句语句只提前结束只提前结束本次本次循环循环,而接着执行而接着执行下次下次循环循环pcontinue语语句句和和break语语句句的的区区别别:continue语语句句只只结结束束本本次次循循环环,而而不不是是终终止止整整个个循循环环的的执执行行。而而break语语句句则则是是结结束束整整个个循循环环过过程程,不再判断执行循环的条件是否成立不再判断执行循环的条件是否成立while(表达式表达式1)if(表达式表达式2)break;while(表达式表达式1)if(表达式表达式2)continue;75第六章第六章 循环结构程序设计循环结构程序设计七、七、break语句和语句和continue语句语句N表达式表达式1Y表达式表达式2NYN表达式表达式1Y表达式表达式2NYbreak语句句continue语句句强行退出循环强行退出循环只结束本次循环只结束本次循环76第六章第六章 循环结构程序设计循环结构程序设计七、七、break语句和语句和continue语句语句例6.5 输出100200之间的不能被3整除的数。 分析分析:p对对100到到200之间的每一个整数进之间的每一个整数进行检查行检查p如果不能被如果不能被3整除,输出,否则整除,输出,否则不输出不输出p无论是否输出此数,都要接着检无论是否输出此数,都要接着检查下一个数查下一个数(直到直到200为止为止)。Nn=100n200Yn能被能被3整除整除Nn=n+1输出出nYfor(n=100;n=200;n+)if(n%3=0)continue;printf(%d,n);分析分析:pp每项的每项的分子都是分子都是1p后一项的分母是前一项的分后一项的分母是前一项的分母加母加2p第第1项的符号为正,从第项的符号为正,从第2项项起,每一项的符号与前一项的起,每一项的符号与前一项的符号相反符号相反77第六章第六章 循环结构程序设计循环结构程序设计八、程序举例八、程序举例例6.6 用计算公式求的近似值,直到发现某一项的绝对值小于10-6 为止(该项不累计加) 。 sign=1,pi=0,n=1,term=1当当term10-6pi=pi+termn=n+2sing=-signterm=sign/npi=pi*4输出输出pi说明说明:pfabs():求绝对值的函数求绝对值的函数78第六章第六章 循环结构程序设计循环结构程序设计八、程序举例八、程序举例#include#includevoidmain()intsign=1;doublepi=0,n=1,term=1;while(fabs(term)=1e-6)pi=pi+term;n=n+2;sign=-sign;term=sign/n;pi=pi*4;printf(pi=%fn,pi);改改为1e-8输出出只保证前只保证前5位小数是准确的位小数是准确的输出出分析分析:p有趣的古典数学问题有趣的古典数学问题有一对兔子,从出生后第有一对兔子,从出生后第3个个月起每个月都生一对兔子。月起每个月都生一对兔子。小兔子长到第小兔子长到第3个月后每个月个月后每个月又生一对兔子。又生一对兔子。假设所有兔子都不死,问每个假设所有兔子都不死,问每个月的兔子总数为多少?月的兔子总数为多少?pp这个数列有如下特点:第这个数列有如下特点:第1、2两个数为两个数为1、1。从第。从第3个数开个数开始,该数是其前面两个数之和。始,该数是其前面两个数之和。79第六章第六章 循环结构程序设计循环结构程序设计八、程序举例八、程序举例例6.7 求费波那西(Fibonacci)数列的前40个数。 80第六章第六章 循环结构程序设计循环结构程序设计八、程序举例八、程序举例#includevoidmain()intf1=1,f2=1,f3;inti;printf(%12dn%12dn,f1,f2);for(i=1;i=38;i+)f3=f1+f2;printf(%12dn,f3);f1=f2;f2=f3;#includevoidmain()intf1=1,f2=1;inti;for(i=1;i=20;i+)printf(%12d%12d,f1,f2);if(i%2=0)printf(n);f1=f1+f2;f2=f2+f1;分析分析:p让让n被被i整除整除(i的值从的值从2变到变到)p如果如果n能被能被2之中任何一个之中任何一个整数整除,则表示整数整除,则表示n肯定不是素肯定不是素数,不必再继续被后面的整数数,不必再继续被后面的整数除,因此,除,因此,可以提前结束循环可以提前结束循环p注意:注意:此时此时i的值必然小于的值必然小于n81第六章第六章 循环结构程序设计循环结构程序设计八、程序举例八、程序举例例6.8 输入一个大于3的整数n,判定它是否素数(prime,又称质数) 。#include#includevoidmain()intn,i,k;printf(n=?);scanf(%d,&n);k=sqrt(n);for(i=2;i=k;i+)if(n%i=0)break;if(i=k)printf(%disnotn,n);elseprintf(%disn,n); 说明说明:psqrt(n):平方根函数平方根函数分析分析:p使用素数判断程序实现对一个使用素数判断程序实现对一个数的判断数的判断p只要增加一个只要增加一个外层循环外层循环,先后,先后对对100200间的全部整数一一进行间的全部整数一一进行判定即可判定即可82第六章第六章 循环结构程序设计循环结构程序设计八、程序举例八、程序举例例6.9 求100200间的全部素数。#include#includevoidmain()intn,i,k,m=0;for(n=101;n=200;n=n+2)k=sqrt(n);for(i=2;i=k+1)printf(%d,n);m=m+1;if(m%10=0)printf(n);printf(n); 说明说明:psqrt(n):平方根函数平方根函数pm:用用m个数控制每行输入个数个数控制每行输入个数控制每行输出控制每行输出10个数据个数据只对奇数进只对奇数进行检查行检查分析分析:p非字母字符保持原状不变非字母字符保持原状不变p输入一行字符,要求输出其相输入一行字符,要求输出其相应的密码应的密码83第六章第六章 循环结构程序设计循环结构程序设计八、程序举例八、程序举例例6.10 译密码。为使电文保密,往往按一定规律将其转换成密码,收报人再按约定的规律将其译回原文。 A B C D E F G W X Y Zif(c=a&c=A&c=W&c=w&c=z)c=c-22;elsec=c+4; 84第六章第六章 循环结构程序设计循环结构程序设计八、程序举例八、程序举例#includevoidmain()charc;while(c=getchar()!=n)if(c=a&c=A&c=Z&cz)c=c-26;printf(%c,c); 说明说明:psqrt(n):平方根函数平方根函数p&cZ条件,条件,从而也执行从而也执行c=c-26;语句,语句,这就会出错这就会出错85第六章第六章 循环结构程序设计循环结构程序设计习题 #includevoidmain()inta,n,sn=0;/题目中题目中a,n由用户输入由用户输入inti,b;/b为中间变量,用于存储各个数据项为中间变量,用于存储各个数据项printf(pleaseinputa:);scanf(%d,&a);printf(pleaseinputn:);scanf(%d,&n);b=a;for(i=1;i=n;i+)sn=sn+b;b=b*10+a;printf(sn=%d,sn); 习题 #include#includevoidmain()intn,sn=0,i,a,b;printf(pleaseinputa:);scanf(%d,&a);printf(pleaseinputn:);scanf(%d,&n);b=a;for(i=1;i=n;i+)sn=sn+b;b=b+a*pow(10,i);printf(sn=%dn,sn); 86第六章第六章 循环结构程序设计循环结构程序设计习题 #includevoidmain()intn,i=1;doublesum=0,s=1;printf(pleaseinputn:);scanf(%d,&n);while(i=n)s=s*i;/存放上一个数的阶乘存放上一个数的阶乘sum=sum+s;i+;printf(sum=%fn,sum);0300 87第六章第六章 循环结构程序设计循环结构程序设计习题 #include#includevoidmain()floatx0,x1,a;scanf(%f,&a);x0=a/2;dox1=x0;x0=(x1+a/x1)/2;while(fabs(x0-x1)=0.00001);printf(%.3fn,x0); 分析分析:p求求a的平方根的平方根,先假设一猜测值,先假设一猜测值x0 =a/2,然后根据以下公式求出,然后根据以下公式求出x1,再将,再将x1代入公式右边,继续求代入公式右边,继续求出出x2通过有效次迭代后即可求通过有效次迭代后即可求出出a的平方根,的平方根,xn+1测绘测绘C语言程序设计语言程序设计第七章第七章89第七章第七章 数数 组组一、一维数组的定义和引用一、一维数组的定义和引用二、二维数组的定义和引用二、二维数组的定义和引用三、字符数组三、字符数组90第七章第七章 数数 组组数组和数组元素数组和数组元素p数数组组:将将一一组组排排列列有有序序的的、个个数数有有限限的的变变量量作作为为一一个个整整体体,用用统统一的名字来表示,这些有序变量的一的名字来表示,这些有序变量的全体全体称为数组。称为数组。(1)数组中元素属于同一类型数组中元素属于同一类型(2)An:A为数组的名称,为数组的名称,n为下标变量,不同的下标表示不同的数据为下标变量,不同的下标表示不同的数据p维数维数:下标变量中下标的个数。下标变量中下标的个数。91第七章第七章 数数 组组一、一维数组的定义和引用一、一维数组的定义和引用1、一维数组的定义、一维数组的定义p定义一维数组的一般形式为:定义一维数组的一般形式为:数组名命名原则同简单变量,但数组名命名原则同简单变量,但一数组名不可以与某一变量名同名一数组名不可以与某一变量名同名定义数组时,需指定数组元素个数定义数组时,需指定数组元素个数常量表达式常量表达式:常量、符号常量常量、符号常量类型符类型符数组名数组名常量常量表达式表达式;inta10;数组名数组名数组数组长度长度inta4+6;合法合法intn=10;intan;不合法不合法92第七章第七章 数数 组组一、一维数组的定义和引用一、一维数组的定义和引用2、一维数组的引用、一维数组的引用p数组必须先定义,然后使用。数组必须先定义,然后使用。p在定义数组并对其中各元素赋值后,就可以引用数组中的元素在定义数组并对其中各元素赋值后,就可以引用数组中的元素p注意注意:只能引用数组元素而不能一次整体调用整个数组全部元素的值只能引用数组元素而不能一次整体调用整个数组全部元素的值93第七章第七章 数数 组组一、一维数组的定义和引用一、一维数组的定义和引用2、一维数组的引用、一维数组的引用p引用数组元素的表示形式为引用数组元素的表示形式为:下标下标:整型常量整型常量或或整型表达式整型表达式数组名数组名下标下标a0=a5+a7-a2*3 intn=5,a10;an=20; 94第七章第七章 数数 组组一、一维数组的定义和引用一、一维数组的定义和引用2、一维数组的引用、一维数组的引用例对10个数组元素依次赋值为0,1, 2,3,4,5,6,7,8,9,要求按逆序输出。#includevoidmain()inti,a10;for(i=0;i=0;i-)printf(%d,ai);printf(n); 分析分析:p定义一个定义一个长度为长度为10的数组,数组定义的数组,数组定义为为整型整型p要赋的值是从要赋的值是从0到到9,可以用,可以用循环循环来赋来赋值值p用循环用循环按下标从大到小按下标从大到小输出这输出这10个元个元素素使使a0a9的的值为09a0a1a2a3a4a5a6a7a8a9先先输出出a9,最后,最后输出出a095第七章第七章 数数 组组一、一维数组的定义和引用一、一维数组的定义和引用3、一维数组的初始化、一维数组的初始化p在定义数组的同时,给各数组元素赋值在定义数组的同时,给各数组元素赋值p定义数组的同时给一部分元素赋值定义数组的同时给一部分元素赋值inta10=0,1,2,3,4,5,6,7,8,9;inta10=0,1,2,3,4;相当于相当于inta10=0,1,2,3,4,0,0,0,0,0;inta10=0,0,0,0,0,0,0,0,0,0;可写为可写为inta10=0;96第七章第七章 数数 组组一、一维数组的定义和引用一、一维数组的定义和引用3、一维数组的初始化、一维数组的初始化p在对全部数组元素赋初值时,可以不指定数组长度。在对全部数组元素赋初值时,可以不指定数组长度。inta5=1,2,3,4,5;可写为可写为inta=1,2,3,4,5;97第七章第七章 数数 组组一、一维数组的定义和引用一、一维数组的定义和引用4、一维数组程序举例、一维数组程序举例例7.2 用数组处理求Fibonacci数列问题。#includevoidmain()inti;intf20=1,1;for(i=2;i20;i+)fi=fi-2+fi-1;for(i=0;i20;i+)if(i%5=0)printf(n);printf(%12d,fi);printf(n); 分析分析:p用简单变量处理的缺点用简单变量处理的缺点:不能在内存不能在内存中保存这些数。假如想直接输出数列中保存这些数。假如想直接输出数列中第中第25个数,是很困难的。个数,是很困难的。p用数组处理,每一个数组元素代表数用数组处理,每一个数组元素代表数列中的一个数,依次求出各数并存放列中的一个数,依次求出各数并存放在相应的数组元素中在相应的数组元素中98第七章第七章 数数 组组例7.3 用起泡法对10个数排序(由小到大)。 起泡法起泡法:p将相邻两个数比较,将小的调到前头将相邻两个数比较,将小的调到前头985420895420859420854920854290854209a0a1a2a3a4a5大数沉淀,大数沉淀,小数起泡小数起泡for(i=0;iai+1)t=ai;ai=ai+1;ai+1=t;99第七章第七章 数数 组组854209584209548209542809542089a0a1a2a3a4a5for(i=0;iai+1)t=ai;ai=ai+1;ai+1=t;100第七章第七章 数数 组组a0a1a2a3a4a5for(i=0;iai+1)t=ai;ai=ai+1;ai+1=t;542089452089425089420589101第七章第七章 数数 组组a0a1a2a3a4a5for(i=0;iai+1)t=ai;ai=ai+1;ai+1=t;420589240589204589a0a1a2a3a4a5for(i=0;iai+1)t=ai;ai=ai+1;ai+1=t;204589024589for(j=0;j5;j+)for(i=0;iai+1)t=ai;ai=ai+1;ai+1=t;for(j=0;j9;j+)for(i=0;iai+1)t=ai;ai=ai+1;ai+1=t;102第七章第七章 数数 组组#includevoidmain()inta10;inti,j,t;printf(input10numbers:n);for(i=0;i10;i+)scanf(%d,&ai);printf(n);for(j=0;j9;j+)for(i=0;iai+1)t=ai;ai=ai+1;ai+1=t;printf(thesortednumbers:n);for(i=0;i10;i+)printf(%d,ai);printf(n); 103第七章第七章 数数 组组二、二维数组的定义和引用二、二维数组的定义和引用1、二维数组的定义、二维数组的定义p定义二维数组的一般形式为:定义二维数组的一般形式为:p二二维维数数组组可可被被看看作作是是一一种种特特殊殊的的一一维维数数组组:它它的的元元素素又又是是一一个个一一维维数数组组类型符类型符数组名数组名常量表达式常量表达式常量常量表达式表达式;floata34,b510;a34/把把a看作是一个一维数组,它有看作是一个一维数组,它有3个元素:个元素:a0、a1、a2,每个元素又是一个包含,每个元素又是一个包含4个元素的一维数组个元素的一维数组104第七章第七章 数数 组组二、二维数组的定义和引用二、二维数组的定义和引用1、二维数组的定义、二维数组的定义a0a1a2105第七章第七章 数数 组组二、二维数组的定义和引用二、二维数组的定义和引用1、二维数组的定义、二维数组的定义逻辑存储逻辑存储内存中的存储顺序内存中的存储顺序106第七章第七章 数数 组组二、二维数组的定义和引用二、二维数组的定义和引用2、二维数组的引用、二维数组的引用p引用数组元素的表示形式为引用数组元素的表示形式为:下标下标:整型常量整型常量或或整型表达式整型表达式下标值应在已定义的数组大小的范围内下标值应在已定义的数组大小的范围内数组名数组名下标下标下标下标b12=a23/2for(i=0;im;i+)printf(%d,%dn,ai0,a0i); 107第七章第七章 数数 组组二、二维数组的定义和引用二、二维数组的定义和引用3、二维数组的初始化、二维数组的初始化p分行给二维数组赋初值分行给二维数组赋初值:p按数组排列的顺序对各元素赋初值按数组排列的顺序对各元素赋初值:p对部分元素赋初值对部分元素赋初值:inta34=1,2,3,4,5,6,7,8,9,10,11,12;inta34=1,2,3,4,5,6,7,8,9,10,11,12;inta34=1,5,9;等价于等价于inta34=1,0,0,0,5,0,0,0,9,0,0,0;108第七章第七章 数数 组组二、二维数组的定义和引用二、二维数组的定义和引用3、二维数组的初始化、二维数组的初始化p对对全全部部元元素素都都赋赋初初值值(即即提提供供全全部部初初始始数数据据):定定义义数数组组时时对对第第一一维维的的长长度可以不指定度可以不指定,但,但第二维的长度不能省第二维的长度不能省p对部分元素赋初值对部分元素赋初值:省略第一维的长度,分行赋初值省略第一维的长度,分行赋初值inta34=1,2,3,4,5,6,7,8,9,10,11,12;可以可以:inta4=1,2,3,4,5,6,7,8,9,10,11,12;inta4=0,0,3,0,10;109第七章第七章 数数 组组二、二维数组的定义和引用二、二维数组的定义和引用4、二维数组程序举例、二维数组程序举例例将一个二维数组行和列的元素互换,存到另一个二维数组中。 分析分析:p可以定义两个数组:数组可以定义两个数组:数组a为为2行行3列列,存放指定的存放指定的6个数个数p数组数组b为为3行行2列列,开始时未赋值开始时未赋值p将将a数组中的元素数组中的元素aij存放存放到到b数组数组中的中的bji元素中元素中p用嵌套的用嵌套的for循环循环完成完成110第七章第七章 数数 组组#includevoidmain()inta23=1,2,3,4,5,6;intb32,i,j;printf(arraya:n);for(i=0;i=1;i+)for(j=0;j=2;j+)printf(%5d,aij);bji=aij;printf(n);printf(arrayb:n);for(i=0;i=2;i+)for(j=0;j=1;j+)printf(%5d,bij);printf(n); 说明说明:pfor(i=0;i=1;i+):处理处理a的一行中各元的一行中各元素素pfor(j=0;jmax,则表示则表示a01是已是已经比过的数据中值最大的经比过的数据中值最大的,把它把它的值赋给的值赋给max,取代了取代了max的原的原值值p以后依此处理,最后以后依此处理,最后max就是就是最大的值最大的值fori=0to2forj=0to3max=aijrow=icolum=jaijmax真真max=a00输出:输出:max,row,colum假假112第七章第七章 数数 组组#includevoidmain()inti,j,row=0,colum=0,max;inta34=1,2,3,4,9,8,7,6,-10,10,-5,2;max=a00;for(i=0;i=2;i+)for(j=0;jmax)max=aij;row=i;colum=j;printf(max=%dnrow=%dncolum=%dn,max,row,colum); 记行号记行号记记最大值最大值记记列列号号113第七章第七章 数数 组组三三、字符数组、字符数组p用来存放用来存放字符数据字符数据的数组是字符数组的数组是字符数组p字符数组中的字符数组中的一个元素存放一个字符一个元素存放一个字符p定义字符数组的方法与定义数值型数组的方法类似定义字符数组的方法与定义数值型数组的方法类似114第七章第七章 数数 组组三三、字符数组、字符数组1、字符数组的定义、字符数组的定义charc10;c0=I;c1=;c2=a;c3=m;c4=;c5=h;c6=a;c7=p;c8=p;c9=y;115第七章第七章 数数 组组三三、字符数组、字符数组2、字符数组的初始化、字符数组的初始化p逐个字符赋给数组中各元素逐个字符赋给数组中各元素如如果果花花括括弧弧中中提提供供的的初初值值个个数数(即即字字符符个个数数)大大于于数数组组长长度度,则则按按语语法法错错误误处理。处理。如如果果初初值值个个数数小小于于数数组组长长度度,则则只只将将这这些些字字符符赋赋给给数数组组中中前前面面那那些些元元素素,其余的元素自动定为空字符其余的元素自动定为空字符(即即0)。如如果果提提供供的的初初值值个个数数与与预预定定的的数数组组长长度度相相同同,在在定定义义时时可可以以省省略略数数组组长长度,系统会自动根据初值个数确定数组长度。度,系统会自动根据初值个数确定数组长度。116第七章第七章 数数 组组三三、字符数组、字符数组2、字符数组的初始化、字符数组的初始化charc10=I,a,m,h,a,p,p,y;charc10=c,p,r,o,g,r,a,m;117第七章第七章 数数 组组三三、字符数组、字符数组2、字符数组的初始化、字符数组的初始化chardiamond55=,*,*,*,*,*,*,*,*;118第七章第七章 数数 组组三三、字符数组、字符数组3、字符数组的引用、字符数组的引用例7.6 输出一个已知的字符串。#includevoidmain()charc15=I,a,m,a,s,t,u,d,e,n,t,.;inti;for(i=0;i15;i+)printf(%c,ci);printf(n); 分析分析:p定义一个字符数组,并用定义一个字符数组,并用“初始化列初始化列表表”对其赋以初值对其赋以初值p用循环逐个输出此字符数组中的字符用循环逐个输出此字符数组中的字符119第七章第七章 数数 组组三三、字符数组、字符数组4、字符串和字符串结束标志、字符串和字符串结束标志pC语言将语言将字符串作为字符数组字符串作为字符数组来处理的来处理的p字符串的字符串的有效长度有效长度、字符数组的长度字符数组的长度p为为了了测测定定字字符符串串的的实实际际长长度度,C语语言言规规定定了了字字符符串串结结束束标标志志0(0代代表表ASCII码为码为0的字符的字符)pASCII码码为为0的的字字符符不不是是一一个个可可以以显显示示的的字字符符,而而是是一一个个“空空操操作作符符”,即即它它什什么么也也不不做做。用用它它作作为为字字符符串串结结束束标标志志不不会会产产生生附附加加的的操操作作或增加有效字符,只起一个供辨别的标志。或增加有效字符,只起一个供辨别的标志。120第七章第七章 数数 组组三三、字符数组、字符数组4、字符串和字符串结束标志、字符串和字符串结束标志charc=Iamhappy;可写成可写成:charc=Iamhappy;相当于相当于:charc11=Iamhappy;charc10=China;可写成可写成:charc10=China;121第七章第七章 数数 组组三三、字符数组、字符数组5、字符数组的输入输出、字符数组的输入输出p字符数组的输入输出可以有两种方法字符数组的输入输出可以有两种方法:逐个字符输入输出逐个字符输入输出:%c整个字符串一次输入输出整个字符串一次输入输出:%sp输出的字符中不包括结束符输出的字符中不包括结束符0p用用%s输输出出字字符符串串时时,printf函函数数中中的的输输出出项项是是字字符符数数组组名名,不不是是数数组组元素名元素名p如果一个字符数组中包含多个如果一个字符数组中包含多个0,则,则遇第一个遇第一个0时输出就结束时输出就结束122第七章第七章 数数 组组三三、字符数组、字符数组5、字符数组的输入输出、字符数组的输入输出p用用scanf函数输入一个字符串函数输入一个字符串pscanf函函数数中中的的输输入入项项c是是已已定定义义的的字字符符数数组组名名,输输入入的的字字符符串串应应短短于于已定义的字符数组的长度已定义的字符数组的长度charc6;scanf(%s,c);China 系统自动系统自动在在China后面加一个后面加一个0123第七章第七章 数数 组组三三、字符数组、字符数组5、字符数组的输入输出、字符数组的输入输出charstr15,str25,str35;scanf(%s%s%s,str1,str2,str3);Howareyou? str1str2str3124第七章第七章 数数 组组三三、字符数组、字符数组6、字符串处理函数、字符串处理函数pputs函数函数:输出字符串的函数输出字符串的函数作用是将一个字符串输出到终端作用是将一个字符串输出到终端(以以0结束结束)在输出时将字符串结束标志在输出时将字符串结束标志0转换成转换成n,即输出完字符串后换行,即输出完字符串后换行。puts(字符数组字符数组)charstr20=China;puts(str);Chinacharstr=chinanbeijing;puts(str);chinabeijing只能输出只能输出一个字符串一个字符串125第七章第七章 数数 组组三三、字符数组、字符数组6、字符串处理函数、字符串处理函数pgets函数函数:输入字符串的函数输入字符串的函数作用是输入一个字符串到字符数组作用是输入一个字符串到字符数组gets(字符数组字符数组)charstr20;gets(str);Computer Computer只能输入只能输入一个字符串一个字符串126第七章第七章 数数 组组三三、字符数组、字符数组6、字符串处理函数、字符串处理函数pstrcat函数函数:字符串连接函数字符串连接函数连连接接两两个个字字符符数数组组中中的的字字符符串串,把把字字符符串串2接接到到字字符符串串1的的后后面面,结结果果放放在字符数组在字符数组1中,函数调用后得到一个函数值中,函数调用后得到一个函数值字符数组字符数组1的地址的地址。strcat(字符数组字符数组1,字符数组字符数组2)charstr130=PeoplesRepublicof;charstr2=China;printf(%s,strcat(str1,str2);PeoplesRepublicofChina要足够大要足够大127第七章第七章 数数 组组三三、字符数组、字符数组6、字符串处理函数、字符串处理函数pstrcpy和和strncpy函数函数:字符串复制函数字符串复制函数将字符串将字符串2复制到字符数组复制到字符数组1中去中去strcpy(字符数组字符数组1,字符数字符数组组2)charstr110,str2=China;strcpy(str1,str2);要足够大要足够大数组名形式数组名形式数组名数组名或或字符串常量字符串常量str1数组名形式数组名形式128第七章第七章 数数 组组三三、字符数组、字符数组6、字符串处理函数、字符串处理函数pstrcpy和和strncpy函数函数:字符串复制函数字符串复制函数charstr110,str2=China;str1=China;str1=str2; 用赋值语句只能将一用赋值语句只能将一个字符赋给一个字符个字符赋给一个字符型变量或字符数组元型变量或字符数组元素素129第七章第七章 数数 组组三三、字符数组、字符数组6、字符串处理函数、字符串处理函数pstrcpy和和strncpy函数函数:字符串复制函数字符串复制函数将字符串将字符串2中中前面前面n个字符个字符复制到字符数组复制到字符数组1中去中去strcnpy(字符数组字符数组1,字符数字符数组组2,n)strncpy(str1,str2,2);n将将str2中中最前面最前面2个字符个字符复制到复制到str1中,取代中,取代str1中中原有的原有的最前面最前面2个字符个字符n复制的字符个数复制的字符个数n不应多于不应多于str1中原有的字符中原有的字符130第七章第七章 数数 组组三三、字符数组、字符数组6、字符串处理函数、字符串处理函数pstrcmp函数函数:字符串比较函数字符串比较函数比比较较字字符符串串1和和字字符符串串2:对对两两个个字字符符串串自自左左至至右右逐逐个个字字符符相相比比(按按ASCII码码值值大大小小比比较较),直直到到出出现现不不同同的的字字符符或或遇遇到到0为为止止。如如全全部部字字符符相相同同,则则认认为为相相等等;若若出出现现不不相相同同的的字字符符,则则以以第第一一个个不不相相同同的的字字符符的的比比较较结结果为准。果为准。strcmp(字符串字符串1,字符串字符串2)strcmp(str1,str2);strcmp(China,Korea);strcmp(str1,Beijing);AAcomputercomparethesethat1A$20CHINACANADADOG字符串字符串2,则函数值为,则函数值为一个正整数一个正整数如果字符串如果字符串1str2)printf(yes);if(strcmp(str1,str2)0)printf(yes); 132第七章第七章 数数 组组三三、字符数组、字符数组6、字符串处理函数、字符串处理函数pstrlen函数函数:测字符串长度的函数测字符串长度的函数函数的值为字符串中的函数的值为字符串中的实际长度实际长度也可以直接测试字符串常量的长度也可以直接测试字符串常量的长度charstr10=China;printf(%d,strlen(str);5strlen(字字符数组符数组)printf(%d,strlen(China);5133第七章第七章 数数 组组三三、字符数组、字符数组6、字符串处理函数、字符串处理函数pstrlwr函数函数:转换为转换为小写小写的函数的函数将字符串中大写字母换成小写字母将字符串中大写字母换成小写字母pstrupr函数函数:转换为转换为大写大写的函数的函数将字符串中小写字母换成大写字母将字符串中小写字母换成大写字母strlwr(字字符串符串)strupr(字字符串符串)#include134第七章第七章 数数 组组三三、字符数组、字符数组例7.8 输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。 分析分析:p解题思路解题思路:问题的关键是怎样确定问题的关键是怎样确定“出现一个新单词了出现一个新单词了”p从第从第1个字符开始逐个字符进行检查,判断此字符是否是新单词的开头,个字符开始逐个字符进行检查,判断此字符是否是新单词的开头,如果是,如果是,就使变量就使变量num的值加的值加1,最后得到的,最后得到的num的值就是单词总数的值就是单词总数p判断是否出现新单词,可以由是否有空格出现来决定判断是否出现新单词,可以由是否有空格出现来决定(连续的若干个空格连续的若干个空格作为出作为出现一次空格;现一次空格;一行开头一行开头的空格不统计在内的空格不统计在内)p如果测出如果测出某一个字符为非空格,而它的前面的字符是空格某一个字符为非空格,而它的前面的字符是空格,则表示,则表示“新的单词开新的单词开始了始了”,此时使,此时使num累加累加1p如果当前字符为非空格而其前面的字符也是非空格,则如果当前字符为非空格而其前面的字符也是非空格,则num不应再累加不应再累加1135第七章第七章 数数 组组三三、字符数组、字符数组例7.8 输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。 分析分析:p用变量用变量word作为判别当前是否开始了一个新单词的作为判别当前是否开始了一个新单词的标志标志,若,若word=0表示未出现表示未出现新单词,如出现了新单词,就把新单词,如出现了新单词,就把word置成置成1p前面一个字符是否空格可以从前面一个字符是否空格可以从word的值看出来的值看出来,若,若word等于等于0,则表示前一个字,则表示前一个字符是空格;如果符是空格;如果word等于等于1,意味着前一个字符为非空格,意味着前一个字符为非空格136第七章第七章 数数 组组Yc=空格空格word=0Nword=0Yword=1num+Nif(c=)word=0;elseif(word=0)word=1;num+;137第七章第七章 数数 组组138第七章第七章 数数 组组三三、字符数组、字符数组#includevoidmain()charstring81,c;inti,num=0,word=0;gets(string);for(i=0;(c=stringi)!=0;i+)if(c=)word=0;elseif(word=0)word=1;num+;printf(%dwordsn,num); 一定要设初始值一定要设初始值相当于相当于c=stringi;c!=0139第七章第七章 数数 组组三三、字符数组、字符数组例有3个字符串,要求找出其中最大者。 分析分析:p解题思路解题思路:设一个二维的字符设一个二维的字符数组数组str,大小为大小为310。每一行。每一行存放一个字符串存放一个字符串charstr310;p可以把可以把str0,str1,str2看作看作3个一维字符数组,可以把它们个一维字符数组,可以把它们如同一维数组那样进行处理如同一维数组那样进行处理str0str1str2for(i=0;i0)strcpy(string,str0);elsestrcpy(string,str1);if(strcmp(str2,string)0)strcpy(string,str2);141第七章第七章 数数 组组三三、字符数组、字符数组#include#includevoidmain()charstr310;charstring10;inti;for(i=0;i0)strcpy(string,str0);elsestrcpy(string,str1);if(strcmp(str2,string)0)strcpy(string,str2);printf(nthelargest:n%sn,string); 142第七章第七章 数数 组组习题 #includevoidmain()inta33;inti,j,sum=0;for(i=0;i3;i+)for(j=0;j3;j+)printf(请输入请输入3*3数组的元素:数组的元素:n);scanf(%d,&aij);for(i=0;i3;i+)for(j=0;j3;j+)if(i=j)sum+=aij;printf(此此3*3数组对角线元素之和为:数组对角线元素之和为:%dn,sum); 143第七章第七章 数数 组组习题 #includevoidmain()inti;charstr1100,str2100;gets(str1);for(i=0;str1i!=n;i+)if(str1i=65&str1i=97&str1i=122)str2i=219-str1i;elsestr2i=str1i;printf(%sn%sn,str1,str2); A-Za-z测绘测绘C语言程序设计语言程序设计第八章第八章145第八章第八章 函函 数数一、概述一、概述二、函数定义的一般形式二、函数定义的一般形式三、函数参数和函数的值三、函数参数和函数的值四、函数的调用四、函数的调用五、函数的嵌套调用五、函数的嵌套调用六、函数的递归调用六、函数的递归调用146第八章第八章 函函 数数一、概述一、概述1、为什么要用函数、为什么要用函数p问题:问题:如如果果程程序序的的功功能能比比较较多多,规规模模比比较较大大,把把所所有有代代码码都都写写在在main函函数数中中,就会使主函数变得庞杂、头绪不清,阅读和维护变得困难就会使主函数变得庞杂、头绪不清,阅读和维护变得困难有有时时程程序序中中要要多多次次实实现现某某一一功功能能,就就需需要要多多次次重重复复编编写写实实现现此此功功能能的的程程序代码,这使程序冗长,不精炼序代码,这使程序冗长,不精炼p解决的方法:用解决的方法:用模块化程序设计的思路模块化程序设计的思路采用采用“组装组装”的办法的办法简化简化程序设计的程序设计的过程过程事先编好一批实现各种不同功能的事先编好一批实现各种不同功能的函数函数把它们保存在把它们保存在函数库中函数库中,需要时直接用,需要时直接用147第八章第八章 函函 数数一、概述一、概述2、函数、函数p函数就是功能函数就是功能p每一个函数用来实现一个特定的功能每一个函数用来实现一个特定的功能p函数的名字应反映其代表的功能函数的名字应反映其代表的功能148第八章第八章 函函 数数一、概述一、概述3、C程序构成程序构成p在在设设计计一一个个较较大大的的程程序序时时,往往往往把把它它分分为为若若干干个个程程序序模模块块,每每一一个个模块包括一个或多个函数,每个函数实现一个特定的功能模块包括一个或多个函数,每个函数实现一个特定的功能p程序可由一个主函数和若干个其他函数构成程序可由一个主函数和若干个其他函数构成p主函数调用其他函数,其他函数也可以互相调用主函数调用其他函数,其他函数也可以互相调用p同一个函数可以被一个或多个函数调用任意多次同一个函数可以被一个或多个函数调用任意多次149第八章第八章 函函 数数一、概述一、概述3、C程序构成程序构成mainabcfghdeie150第八章第八章 函函 数数一、概述一、概述例8.1 输出以下的结果,用函数调用实现。#includevoidmain()voidprint_star();voidprint_message();print_star();print_message();print_star(); 分析分析:p用一个函数用一个函数print_star来实现输出一行来实现输出一行“*”号的功能。号的功能。p再写一个再写一个print_message函数来输出中间函数来输出中间一行文字信息一行文字信息p用主函数分别调用这两个函数用主函数分别调用这两个函数*Howdoyoudo!*voidprint_star()printf(“*n”);voidprint_message()printf(“Howdoyoudo!n”);输出输出16个个*输出一行文字输出一行文字声明函数声明函数定义函数定义函数151第八章第八章 函函 数数一、概述一、概述p一一个个C程程序序由由一一个个或或多多个个程程序序模模块块组组成成,每每一一个个程程序序模模块块作作为为一一个个源源程程序序文文件件。对对较较大大的的程程序序,一一般般不不希希望望把把所所有有内内容容全全放放在在一一个个文文件件中中,而而是是将将它它们们分分别别放放在在若若干干个个源源文文件件中中,由由若若干干个个源源程程序序文文件件组组成成一一个个C程程序序。这这样样便便于于分分别别编编写写、分分别别编编译译,提高调试效率。一个源程序文件可以为多个提高调试效率。一个源程序文件可以为多个C程序共用。程序共用。p一一个个源源程程序序文文件件由由一一个个或或多多个个函函数数以以及及其其他他有有关关内内容容(如如预预处处理理指指令令、数数据据声声明明与与定定义义等等)组组成成。一一个个源源程程序序文文件件是是一一个个编编译译单单位位,在在程程序序编编译译时时是是以以源源程程序序文文件件为为单单位位进进行行编编译译的的,而而不是以函数为单位进行编译的。不是以函数为单位进行编译的。152第八章第八章 函函 数数一、概述一、概述pC程程序序的的执执行行是是从从main函函数数开开始始的的,如如果果在在main函函数数中中调调用用其其他他函函数数,在在调调用用后后流流程程返返回回到到main函函数数,在在main函函数数中中结结束束整整个程序的运行。个程序的运行。p所所有有函函数数都都是是平平行行的的,即即在在定定义义函函数数时时是是分分别别进进行行的的,是是互互相相独独立立的的。一一个个函函数数并并不不从从属属于于另另一一个个函函数数,即即函函数数不不能能嵌嵌套套定定义义。函函数数间间可可以以互互相相调调用用,但但不不能能调调用用main函函数数。main函函数数是是被操作系统调用的被操作系统调用的。153第八章第八章 函函 数数一、概述一、概述p函数种类函数种类库函数,它是由系统提供的,用户不必自己定义而直接使用它们。库函数,它是由系统提供的,用户不必自己定义而直接使用它们。用户自己定义的函数。它是用以解决用户专门需要的函数。用户自己定义的函数。它是用以解决用户专门需要的函数。p函数的形式函数的形式无无参参函函数数。无无参参函函数数一一般般用用来来执执行行指指定定的的一一组组操操作作。无无参参函函数数可可以带回或不带回函数值,但一般以不带回函数值的居多。以带回或不带回函数值,但一般以不带回函数值的居多。有有参参函函数数。在在调调用用函函数数时时,主主调调函函数数在在调调用用被被调调用用函函数数时时,通通过过参参数数向向被被调调用用函函数数传传递递数数据据,一一般般情情况况下下,执执行行被被调调用用函函数数时时会会得到一个函数值,供主调函数使用。得到一个函数值,供主调函数使用。用用#include指令把有关的头文指令把有关的头文件包含到本文件模块中即可件包含到本文件模块中即可154第八章第八章 函函 数数二、函数定义的一般形式二、函数定义的一般形式pC语语言言要要求求,在在程程序序中中用用到到的的所所有有函函数数,必必须须“先先定定义义,后后使使用用”p指指定定函函数数名名字字、函函数数返返回回值值类类型型、函函数数实实现现的的功功能能以以及及参参数数的的个数与类型个数与类型,将这些信息通知编译系统。,将这些信息通知编译系统。按名调用按名调用在调用函数时向它在调用函数时向它们传递数据们传递数据155第八章第八章 函函 数数二、函数定义的一般形式二、函数定义的一般形式1、无参函数定义的一般形式为、无参函数定义的一般形式为:类型名类型名函数名函数名()函数体函数体类型名类型名函数名函数名(void)函数体函数体包括声明部分和语句部包括声明部分和语句部分分156第八章第八章 函函 数数二、函数定义的一般形式二、函数定义的一般形式2、有参函数定义的一般形式为、有参函数定义的一般形式为:类型名类型名函数名函数名(形式参数表列形式参数表列)函数体函数体157第八章第八章 函函 数数二、函数定义的一般形式二、函数定义的一般形式3、空函数、空函数:p先用空函数占一个位置,以后逐步扩充先用空函数占一个位置,以后逐步扩充p好好处处:程程序序结结构构清清楚楚,可可读读性性好好,以以后后扩扩充充新新功功能能方方便便,对对程程序结构影响不大序结构影响不大类型名类型名函数名函数名()158第八章第八章 函函 数数三、函数参数和函数的值三、函数参数和函数的值1、形式参数和实际参数、形式参数和实际参数p在调用有参函数时,主调函数和被调用函数之间有在调用有参函数时,主调函数和被调用函数之间有数据传递关系数据传递关系p定义函数时函数名后面的变量名称为定义函数时函数名后面的变量名称为“形式参数形式参数”(简称(简称“形参形参”)p主调函数名后面参数称为主调函数名后面参数称为“实际参数实际参数”(简称(简称“实参实参”)p实际参数可以是常量、变量或表达式实际参数可以是常量、变量或表达式159第八章第八章 函函 数数三、函数参数和函数的值三、函数参数和函数的值2、实参和形参间的数据传递、实参和形参间的数据传递p在在调调用用函函数数过过程程中中,系系统统会会把把实实参参的的值值传传递递给给被被调调用用函函数数的的形形参参,也也即形参从实参得到一个值即形参从实参得到一个值p实参值在实参值在函数调用期间有效函数调用期间有效,可以参加被调函数中的运算,可以参加被调函数中的运算160第八章第八章 函函 数数三、函数参数和函数的值三、函数参数和函数的值例8.2 输入两个整数,要求输出其中值较大者。要求用函数来找到大数。#includevoidmain()intmax(intx,inty);inta,b,c;printf(“twointegernumbers:);scanf(“%d,%d”,&a,&b);c=max(a,b);printf(“maxis%dn”,c); 说明说明:p函数名见名知意,名为函数名见名知意,名为maxp由于给定的两个数是整数,返回主调函由于给定的两个数是整数,返回主调函数的值(即较大数)应该是数的值(即较大数)应该是整型整型pmax函数应当有两个参数,从主函数接函数应当有两个参数,从主函数接收两个整数,参数的类型应当是整型收两个整数,参数的类型应当是整型intmax(intx,inty)intz;z=xy?x:y;return(z);实参可以是常量、变量或表达式实参可以是常量、变量或表达式161第八章第八章 函函 数数三、函数参数和函数的值三、函数参数和函数的值p在在定定义义函函数数中中指指定定的的形形参参,在在未未出出现现函函数数调调用用时时,它它们们并并不不占占内内存存中中的的存存储储单单元元。在在发发生生函函数数调调用用时时,函函数数max的的形形参参被被临临时时分分配配内内存存单单元。元。p调用结束,形参单元被释放调用结束,形参单元被释放;实参单元仍保留并维持原值,没有改变实参单元仍保留并维持原值,没有改变p如如果果在在执执行行一一个个被被调调用用函函数数时时,形形参参的的值值发发生生改改变变,不不会会改改变变主主调调函函数的实参的值数的实参的值2a3bxy23实参实参形参形参c=max(a,b);(main函数函数)intmax(intx,inty)(max函数函数)intz;z=xy?x:y;return(z);162第八章第八章 函函 数数三、函数参数和函数的值三、函数参数和函数的值3、函数的返回值、函数的返回值p函数的返回值是通过函数中的函数的返回值是通过函数中的return语句语句获得的。获得的。一个函数中可以有一个以上的一个函数中可以有一个以上的return语句,执行到哪一个语句,执行到哪一个return语语句,哪一个句,哪一个就就起作用起作用return语句后面的括号可以不要语句后面的括号可以不要p函数值的类型。应当在函数值的类型。应当在定义函数时指定函数值的类型定义函数时指定函数值的类型p在定义函数时指定的函数类型一般应该和在定义函数时指定的函数类型一般应该和return语句中的表达式类语句中的表达式类型一致型一致如果函数值的类型和如果函数值的类型和return语句中表达式的值不一致,则以语句中表达式的值不一致,则以函数类函数类型为准型为准163第八章第八章 函函 数数四、函数的调用四、函数的调用1、函数调用的一般形式为、函数调用的一般形式为p如果是调用无参函数,则如果是调用无参函数,则“实参表列实参表列”可以没有,但可以没有,但括号不能省略括号不能省略p如果实参表列包含多个实参,则各参数间用如果实参表列包含多个实参,则各参数间用逗号隔开逗号隔开函数名函数名(实参表列实参表列)164第八章第八章 函函 数数四、函数的调用四、函数的调用2、函数调用的方式、函数调用的方式p按函数调用在程序中出现的形式和位置分,有按函数调用在程序中出现的形式和位置分,有3种函数调用方式种函数调用方式:函函数数调调用用语语句句:把把函函数数调调用用单单独独作作为为一一个个语语句句,不不要要求求函函数数带带回回值值,只要求函数完成一定的操作只要求函数完成一定的操作函函数数表表达达式式:函函数数调调用用出出现现在在另另一一个个表表达达式式中中,要要求求函函数数带带回回一一个个确定的值以参加表达式的运算确定的值以参加表达式的运算函数参数函数参数:函数调用作为另一函数调用时的实参函数调用作为另一函数调用时的实参printf_star();c=max(a,b);mmax(a,max(b,c);165第八章第八章 函函 数数四、函数的调用四、函数的调用3、对被调用函数的声明和函数原型、对被调用函数的声明和函数原型p在一个函数中调用另一个函数需要具备如下条件在一个函数中调用另一个函数需要具备如下条件:被被调调用用函函数数必必须须是是已已经经定定义义的的函函数数(库库函函数数或或用用户户自自己己定定义义的的函函数数)如果使用库函数,应该在本文件开头加相应的如果使用库函数,应该在本文件开头加相应的#include指令指令如如果果使使用用自自己己定定义义的的函函数数,而而该该函函数数的的位位置置在在调调用用它它的的函函数数后后面面,应该声明应该声明166第八章第八章 函函 数数四、函数的调用四、函数的调用3、对被调用函数的声明和函数原型、对被调用函数的声明和函数原型p函数原型的一般形式有两种函数原型的一般形式有两种:p原型说明可以放在文件的开头,所有函数都可以使用此函数原型说明可以放在文件的开头,所有函数都可以使用此函数floatadd(floatx,floaty)floatadd(float,float);167第八章第八章 函函 数数四、函数的调用四、函数的调用例8.5 对被调用的函数作声明。#includevoidmain()floatadd(floatx,floaty);floata,b,c;printf(Pleaseenteraandb:);scanf(%f,%f,&a,&b);c=add(a,b);printf(sumis%fn,c); 分析分析:p用用add函数实现。函数实现。add函数为函数为float型,有型,有两个参数,也为两个参数,也为float型。型。p分别编写分别编写add函数和函数和main函数,它们组函数,它们组成成一个源程序文件一个源程序文件pmain函数的位置在函数的位置在add函数之前函数之前p在在main函数中对函数中对add函数进行声明函数进行声明对对add函数声明函数声明floatadd(floatx,floaty)floatz;z=x+y;return(z);求两个实数之和,求两个实数之和,函数值也是实型函数值也是实型只差一个分号只差一个分号168第八章第八章 函函 数数五、函数的嵌套调用五、函数的嵌套调用pC语言的函数定义是互相平行、独立的语言的函数定义是互相平行、独立的p函数不能嵌套定义函数不能嵌套定义p可以嵌套调用函数可以嵌套调用函数:调用一个函数的过程中,又可以调用另一个函数调用一个函数的过程中,又可以调用另一个函数169第八章第八章 函函 数数五、函数的嵌套调用五、函数的嵌套调用main函数函数调用用a函数函数结束束a函数函数调用用b函数函数b函数函数170第八章第八章 函函 数数五、函数的嵌套调用五、函数的嵌套调用例 输入4个整数,找出其中最大的数。用函数的嵌套调用来处理。 #includevoidmain()intmax4(inta,intb,intc,intd);inta,b,c,d,max;printf(4intergernumbers:);scanf(%d%d%d%d,&a,&b,&c,&d);max=max4(a,b,c,d);printf(max=%dn,max); 分析分析:pmain中调用中调用max4函数,找函数,找4个数中最大个数中最大者者pmax4中再调用中再调用max2,找两个数中的大者,找两个数中的大者pmax4中多次调用中多次调用max2,可找,可找4个数中的个数中的大者,然后把它作为函数值返回大者,然后把它作为函数值返回main函函数数pmain函数中输出结果函数中输出结果对对max4函数声明函数声明调用后肯定是调用后肯定是4个个数中最大者数中最大者171第八章第八章 函函 数数五、函数的嵌套调用五、函数的嵌套调用intmax4(inta,intb,intc,intd)intmax2(inta,intb);intm;m=max2(a,b);m=max2(m,c);m=max2(m,d);return(m);对对max2函数函数声明声明a,b中较大者中较大者a,b,c中较大者中较大者a,b,c,d中最大者中最大者intmax2(inta,intb)if(a=b)returna;elsereturnb;找找a,b中中较大者较大者intmax2(inta,intb)return(ab?a:b);ruturnmax2(max2(max2(a,b),c),d);172第八章第八章 函函 数数五、函数的嵌套调用五、函数的嵌套调用#includeintmain()max=max4(a,b,c,d); intmax4(inta,intb,intc,intd)intmax2(inta,intb);ruturnmax2(max2(max2(a,b),c),d);intmax2(inta,intb)return(ab?a:b);173第八章第八章 函函 数数六、函数的递归调用六、函数的递归调用p在在调调用用一一个个函函数数的的过过程程中中又又直直接接或或间间接接地地调调用用该该函函数数本本身身,称称为为函函数数的递归调用。的递归调用。f2函数函数调用调用f1函数函数f函数函数调用调用f函数函数f1函数函数调用调用f2函数函数直接调用直接调用本函数本函数间接调用间接调用本函数本函数intf(intx)inty,z;z=f(y);return(2*z); 应使用应使用if语句语句控制结束调用控制结束调用174第八章第八章 函函 数数六、函数的递归调用六、函数的递归调用例有5个学生坐在一起。问第5个学生多少岁?他说比第4个学生大2岁问第4个学生岁数,他说比第3个学生大2岁问第3个学生,又说比第2个学生大2岁,问第2个学生,说比第1个学生大2岁,最后问第1个学生,他说是10岁。分析分析:p要求第要求第5个年龄,就必须先知道第个年龄,就必须先知道第4个年个年龄龄p要求第要求第4个年龄必须先知道第个年龄必须先知道第3个年龄个年龄p第第3个年龄又取决于第个年龄又取决于第2个年龄个年龄p第第2个年龄取决于第个年龄取决于第1个年龄个年龄p每个学生年龄都比其前每个学生年龄都比其前1个学生的年龄大个学生的年龄大2175第八章第八章 函函 数数age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(2)=12age(3)=14age(4)=16age(5)=18age(1)=10回溯阶段回溯阶段递推阶段递推阶段结束递归的条件结束递归的条件176第八章第八章 函函 数数#includevoidmain()intage(intn);printf(No.5,age:%dn,age(5);intage(intn)intc;if(n=1)c=10;elsec=age(n-1)+2;return(c); 177第八章第八章 函函 数数age(5)输出输出age(5)mainc=age(4)+2age函数函数n=5c=age(3)+2age函数函数n=4c=age(1)+2age函数函数n=2c=age(2)+2age函数函数n=3c=10age函数函数n=1age(1)=10age(2)=12age(3)=14age(4)=16age(5)=1818178第八章第八章 函函 数数六、函数的递归调用六、函数的递归调用例8.8 用递归方法求n!。#includevoidmain()intfac(intn);intn;inty;printf(inputanintegernumber:);scanf(%d,&n);y=fac(n);printf(%d!=%dn,n,y);分析分析:p求求n!可以用递推方法:即从可以用递推方法:即从1开始,开始,乘乘2,再乘,再乘3一直乘到一直乘到n。p递推法的特点是从一个递推法的特点是从一个已知的事已知的事实实(如如1!=1)出发,按一定规律推出出发,按一定规律推出下一个事实下一个事实(如如2!=1!*2),再从这,再从这个新的已知的事实出发,再向下个新的已知的事实出发,再向下推出一个新的事实推出一个新的事实(3!=3*2!)。n!=n*(n-1)!。179第八章第八章 函函 数数六、函数的递归调用六、函数的递归调用intfac(intn)intf;if(n0)printf(n0,dataerror!);elseif(n=0|n=1)f=1;elsef=fac(n-1)*n;return(f);180第八章第八章 函函 数数七、数组作为函数参数七、数组作为函数参数八、局部变量和全局变量八、局部变量和全局变量九、变量的存储类别九、变量的存储类别十、内部函数和外部函数十、内部函数和外部函数181第八章第八章 函函 数数七、数组作为函数参数七、数组作为函数参数1、数组元素作函数实参、数组元素作函数实参p实实参参可可以以是是表表达达式式形形式式,数数组组元元素素可可以以是是表表达达式式的的组组成成部部分分,因因此此数数组元素当然可以作为函数的实参组元素当然可以作为函数的实参p单向传递,即单向传递,即“值传送值传送”方式。方式。182第八章第八章 函函 数数七、数组作为函数参数七、数组作为函数参数1、数组元素作函数实参、数组元素作函数实参例8.10 有两个数组a、b,各有10个元素,将它们对应地逐个相比,如果a数组中的元素大于b数组中的相应元素的数目多于b数组中元素大于a数组中相应元素的数目,则认为a数组大于b数组,并分别统计出两个数组相应元素大于、等于、小于的次数。 分析分析:p定义数组定义数组a、b,分别用来存放分别用来存放10个数个数p设计函数设计函数large,用来求两个数中的大者,用来求两个数中的大者p在主函数中定义变量在主函数中定义变量n、m、k,分别存,分别存放放a数组中的元素大于、等于、小于数组中的元素大于、等于、小于b数数组中的相应元素的数目组中的相应元素的数目p根据根据n、k两值大小判断两值大小判断a、b数组大小数组大小183第八章第八章 函函 数数七、数组作为函数参数七、数组作为函数参数1、数组元素作函数实参、数组元素作函数实参for(i=1;ibi%dtimesnai=bi%dtimesnaik)printf(arrayaislargerthanarraybn);elseif(ny)flag=1;elseif(xy)flag=-1;elseflag=0;return(flag);184第八章第八章 函函 数数七、数组作为函数参数七、数组作为函数参数2、数组名作函数参数、数组名作函数参数p除除了了可可以以用用数数组组元元素素作作为为函函数数参参数数外外,还还可可以以用用数数组组名名作作函函数数参参数数(包括实参和形参包括实参和形参)p用数组元素作实参时,向形参变量传递的是数组元素的用数组元素作实参时,向形参变量传递的是数组元素的值值p用数组名作函数实参时,向形参传递的是数组用数组名作函数实参时,向形参传递的是数组首元素首元素的地址的地址p实参数组与形参数组类型必须实参数组与形参数组类型必须一致一致185第八章第八章 函函 数数例有一个一维数组score,内放10个学生成绩,求平均成绩。#includevoidmain()floataverage(floatarray10);floatscore10,aver;inti;printf(input10scores:n);for(i=0;i10;i+)scanf(%f,&scorei);printf(n);aver=average(score);printf(%5.2fn,aver);分析分析:p用函数用函数average求平均成绩,用数组名作求平均成绩,用数组名作为函数实参,形参也用数组名为函数实参,形参也用数组名p在在average函数中引用各数组元素,求平函数中引用各数组元素,求平均成绩并返回均成绩并返回main函数函数定义实参数组定义实参数组floataverage(floatarray10)inti;floataver,sum=array0;for(i=1;i10;i+)sum=sum+arrayi;aver=sum/10;return(aver);定义形参数组定义形参数组相当于相当于score0相当于相当于scoreip形参数组可以不指定大小,形参数组可以不指定大小,floatarray186第八章第八章 函函 数数七、数组作为函数参数七、数组作为函数参数3、多维数组名作函数参数、多维数组名作函数参数187第八章第八章 函函 数数八、局部变量和全局变量八、局部变量和全局变量p定义变量有三种情况:定义变量有三种情况:在函数的开头定义在函数的开头定义在函数内的复合语句内定义在函数内的复合语句内定义在函数的外部定义在函数的外部定义局部变量局部变量全局变量全局变量188第八章第八章 函函 数数floatf1(inta)intb,c;charf2(intx,inty)inti,j;intmain()intm,n;return0;a、b、c仅在此函数内仅在此函数内有效有效x、y、i、j仅在此函仅在此函数内数内有效有效m、n仅在此函数内仅在此函数内有效有效189第八章第八章 函函 数数floatf1(inta)intb,c;charf2(intx,inty)inti,j;intmain()inta,b;return0;a、b也仅在此也仅在此函数内函数内有效有效intmain()inta,b;intc;c=a+b;c仅在此复合仅在此复合语句内语句内有效有效a、b在此函数在此函数内内有效有效190第八章第八章 函函 数数八、局部变量和全局变量八、局部变量和全局变量2、全局变量、全局变量p在在函函数数内内定定义义的的变变量量是是局局部部变变量量,而而在在函函数数之之外外定定义义的的变变量量称称为为外外部部变量,变量,外部变量是全局变量外部变量是全局变量(也称全程变量也称全程变量)p全局变量可以为全局变量可以为本文件本文件中中其他函数其他函数所共用所共用p有效范围为从有效范围为从定义定义变量的变量的位置位置开始开始到到本源文件结束本源文件结束191第八章第八章 函函 数数intp=1,q=5floatf1(inta)intb,c;charc1,c2;charf2(intx,inty)inti,j;intmain()intm,n;return0;intp=1,q=5floatf1(inta)intb,c;charc1,c2;charf2(intx,inty)inti,j;intmain()intm,n;return0;p、q、c1、c2为为全局变量全局变量p、q的有效范围的有效范围c1、c2的有效范围的有效范围192第八章第八章 函函 数数例8.15 有一个一维数组,内放10个学生成绩,写一个函数,当主函数调用此函数后,能求出平均分、最高分和最低分。#includefloatMax=0,Min=0;voidmain()floataverage(floatarray,intn);floatave,score10;inti;printf(Pleaseenter10scores:n);for(i=0;i10;i+)scanf(%f,&scorei);ave=average(score,10);printf(max=%6.2fnmin=%6.2fnaverage=%6.2fn,Max,Min,ave);分析分析:p调用一个函数可以得到一个函数调用一个函数可以得到一个函数返回值,现在希望通过函数调用返回值,现在希望通过函数调用能得到能得到3个结果。可以利用全局变个结果。可以利用全局变量来达到此目的。量来达到此目的。floataverage(floatarray,intn)inti;floataver,sum=array0;for(i=1;iMax)Max=arrayi;elseif(arrayiMin)Min=arrayi;sum=sum+arrayi;aver=sum/n;return(aver);相当于相当于score0相当于相当于scorei193第八章第八章 函函 数数avescore10MaxMinaverarraynMaxMinmain函数函数average函数函数194第八章第八章 函函 数数例8.16 外部变量与局部变量同名。#includeinta=3,b=5;voidmain()intmax(inta,intb);inta=8;printf(“max=%dn”,max(a,b);intmax(inta,intb)intc;c=ab?a:b;return(c);p全局变量在程序的全部执行过程中全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时都占用存储单元,而不是仅在需要时才开辟单元。才开辟单元。p它使函数的通用性降低了,因为函它使函数的通用性降低了,因为函数在执行时要依赖于其所在的外部变数在执行时要依赖于其所在的外部变量。量。p使用全局变量过多,会降低程序的使用全局变量过多,会降低程序的清晰性。清晰性。b为全局全局变量量a为为局局部部变量变量,仅,仅在此函数内有效在此函数内有效a、b为局局部部变量量,仅在此函数内有效在此函数内有效说明说明:p如果如果在同一个源文件中,外部变在同一个源文件中,外部变量与局部变量同名,则在局部变量与局部变量同名,则在局部变量的作用范围内,外部变量被量的作用范围内,外部变量被“屏蔽屏蔽”,即它不起作用。,即它不起作用。建议不在必要时不要使用全局变量建议不在必要时不要使用全局变量195第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别1、动态存储方式与静态存储方式、动态存储方式与静态存储方式p从变量的从变量的作用域作用域的角度来观察,变量可以分为的角度来观察,变量可以分为全局变量和局部变量全局变量和局部变量p从从变变量量值值存存在在的的时时间间(即即生生存存期期)观观察察,变变量量的的存存储储有有两两种种不不同同的的方方式式:静态存储方式静态存储方式和和动态存储方式动态存储方式静态存储方式是指在程序运行期间由系统分配静态存储方式是指在程序运行期间由系统分配固定的存储空间固定的存储空间的方式的方式动动态态存存储储方方式式是是在在程程序序运运行行期期间间根根据据需需要要进进行行动动态态的的分分配配存存储储空空间间的的方方式式196第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别1、动态存储方式与静态存储方式、动态存储方式与静态存储方式程序区程序区静态存储区静态存储区动态存储区动态存储区用户区用户区将将数数据存据存放在放在此区此区说明说明:p静态存储区静态存储区:全部全局变量。全部全局变量。程序程序开始执行开始执行时给全局变量分配存储时给全局变量分配存储区,区,程序执行完毕程序执行完毕就释放。在程就释放。在程序执行过程中占据固定的存储单序执行过程中占据固定的存储单元元p动态存储区动态存储区:函数函数形式参数形式参数自自动变量动变量:函数中定义的没有用关键函数中定义的没有用关键字字static声明的变量声明的变量函数调用时函数调用时的现场保护和返回地址等存放在的现场保护和返回地址等存放在动态存储区动态存储区.函数调用开始时分配函数调用开始时分配,函数结束时释函数结束时释放放。在程序执行过程中,这种分。在程序执行过程中,这种分配和释放是动态的配和释放是动态的197第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别1、动态存储方式与静态存储方式、动态存储方式与静态存储方式p每一个每一个变量变量和和函数函数都有两个属性:都有两个属性:数据类型数据类型和和数据的数据的存储类别存储类别数据类型数据类型:如整型、浮点型等如整型、浮点型等存储类别指的是数据在内存中存储的方式存储类别指的是数据在内存中存储的方式(如静态存储和动态存储如静态存储和动态存储)存存储储类类别别包包括括:自自动动的的(auto)、静静态态的的(static)、寄寄存存器器的的(register)、外外部部的的(extern)根据变量的存储类别,可以知道变量的作用域和生存期根据变量的存储类别,可以知道变量的作用域和生存期198第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别2、自动变量、自动变量(auto变量变量)p局局部部变变量量,如如果果不不专专门门声声明明存存储储类类别别,则则动动态态地地分分配配存存储储空空间间,为为自自动动变变量。量。p调调用用函函数数时时,系系统统会会给给局局部部变变量量分分配配存存储储空空间间,调调用用结结束束时时就就自自动动释释放放空空间。间。p自动变量用关键字自动变量用关键字auto作存储类别的声明作存储类别的声明intf(inta)autointb,c=3; 可以省略可以省略199第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别3、静态局部变量、静态局部变量(static局部变量局部变量)p用关键字用关键字static声明的局部变量为静态局部变量声明的局部变量为静态局部变量p静静态态局局部部变变量量在在函函数数调调用用结结束束后后不不消消失失而而继继续续保保留留原原值值,即即其其占占用用的的存存储储单单元元不不释释放放,在在下下一一次次再再调调用用该该函函数数时时,该该变变量量已已有有值值(就就是是上上一一次函数调用结束时的值次函数调用结束时的值)200第八章第八章 函函 数数例8.17 考察静态局部变量的值#includevoidmain()intf(int);inta=2,i;for(i=0;i3;i+)printf(“%dn”,f(a);p第一次调用第一次调用开始开始:intf(inta)autointb=0;staticintc=3;b=b+1;c=c+1;return(a+b+c);调用三次调用三次每调用一次,每调用一次,开辟新开辟新a和和b,但,但c不是不是03bcp第一次调用第一次调用期间期间:f(a)7a2a214bca2p第一次调用第一次调用结束结束:4bca201第八章第八章 函函 数数p第二次调用第二次调用开始开始:04bcp第二次调用第二次调用期间期间:f(a)8a2a215bca2p第二次调用第二次调用结束结束:5bcap第三次调用第三次调用开始开始:05bcp第三次调用第三次调用期间期间:f(a)9a2a216bca2p第三次调用第三次调用结束结束:6bcap整个程序结束整个程序结束:bcaa202第八章第八章 函函 数数intf(inta)autointb=0;staticintc=3;b=b+1;c=c+1;return(a+b+c);p在在函数调用函数调用时赋初值时赋初值p若不若不赋初值赋初值,不确定不确定p 仅在本函数内有效仅在本函数内有效p在在编译编译时赋初值时赋初值p若不赋初值,是若不赋初值,是0p仅在本函数内有效仅在本函数内有效203第八章第八章 函函 数数例8.18 利用静态变量输出1到5的阶乘值。#includevoidmain()intfac(intn);inti;for(i=1;i=5;i+)printf(%d!=%dn,i,fac(i);intfac(intn)staticintf=1;f=f*n;return(f);分析分析:p可以编一个函数用来进行连乘,如可以编一个函数用来进行连乘,如第第1次调用时进行次调用时进行1乘乘1,第,第2次调用次调用时再乘以时再乘以2,第,第3次调用时再乘以次调用时再乘以3,依此规律进行下去。,依此规律进行下去。p希望保留函数上一次调用结束的值,希望保留函数上一次调用结束的值,采用采用静态变量静态变量说明说明:p主函数用循环实现主函数用循环实现p若非必要,不要多用静态局部变量若非必要,不要多用静态局部变量:长期占用内存不释放,程序可读长期占用内存不释放,程序可读性差性差204第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别4、寄存器变量、寄存器变量(register变量变量)p一一般般情情况况下下,变变量量(包包括括静静态态存存储储方方式式和和动动态态存存储储方方式式)的的值值是是存存放放在在内存中的内存中的p寄存器变量允许将寄存器变量允许将局部变量局部变量的值放在的值放在CPU中的寄存器中的寄存器中中p现现在在的的计计算算机机能能够够识识别别使使用用频频繁繁的的变变量量,从从而而自自动动地地将将这这些些变变量量放放在在寄存器中,而不需要程序设计者指定寄存器中,而不需要程序设计者指定全局变量不可以全局变量不可以局部静态不可以局部静态不可以205第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别5、用、用extern声明外部变量声明外部变量p全全局局变变量量都都是是存存放放在在静静态态存存储储区区中中的的。生生存存期期是是固固定定的的,存存在在于于程程序序的的整个运行过程整个运行过程p全全局局变变量量的的作作用用域域是是从从变变量量的的定定义义处处开开始始,到到本本程程序序文文件件的的末末尾尾。在在此作用域内,全局变量可以为程序中各个函数所引用。此作用域内,全局变量可以为程序中各个函数所引用。p在在一一个个文文件件内内扩扩展展外外部部变变量量的的作作用用域域:用用关关键键字字extern对对某某变变量量作作“外外部变量声明部变量声明”,则可以从,则可以从“声明声明”处起,合法地使用该外部变量处起,合法地使用该外部变量206第八章第八章 函函 数数例#includevoidmain()intmax(int,int);externA,B;scanf(“%d%d”,&A,&B);printf(maxis%dn,max(A,B);intA,B,C;intmax(intx,inty)intz;z=xy?x:y;return(z);207第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别5、用、用extern声明外部变量声明外部变量p将外部变量的作用域扩展到其他文件将外部变量的作用域扩展到其他文件:如如果果一一个个程程序序包包含含两两个个文文件件,在在两两个个文文件件中中都都要要用用到到同同一一个个外外部部变变量量Num,不能分别在两个文件中各自定义一个外部变量不能分别在两个文件中各自定义一个外部变量Num应应在在任任一一个个文文件件中中定定义义外外部部变变量量Num,而而在在另另一一文文件件中中用用extern对对Num作作“外部变量声明外部变量声明”在在编编译译和和连连接接时时,系系统统会会由由此此知知道道Num有有“外外部部链链接接”,可可以以从从别别处处找找到到已已定定义义的的外外部部变变量量Num,并并将将在在另另一一文文件件中中定定义义的的外外部部变变量量num的的作作用域扩展到本文件用域扩展到本文件208第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别6、用、用static声明外部变量声明外部变量p外外部部变变量量的的作作用用域域限限制制在在本本文文件件中中:有有时时在在程程序序设设计计中中希希望望某某些些外外部部变变量量只限于被本文件引用只限于被本文件引用。这时可以在。这时可以在定义外部变量定义外部变量时加一个时加一个static声明声明p不不要要误误认认为为对对外外部部变变量量加加static声声明明后后才才采采取取静静态态存存储储方方式式,而而不不加加static的是采取动态存储的是采取动态存储p声声明明局局部部变变量量的的存存储储类类型型和和声声明明全全局局变变量量的的存存储储类类型型的的含含义义是是不不同同的的:对对于于局局部部变变量量来来说说,声声明明存存储储类类型型的的作作用用是是指指定定变变量量存存储储的的区区域域以以及及由由此此产产生生的的生生存存期期的的问问题题;而而对对于于全全局局变变量量来来说说,声声明明存存储储类类型型的的作作用是变量用是变量作用域的扩展问题作用域的扩展问题209第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别6、用、用static声明外部变量声明外部变量p用用static声明一个变量的作用是声明一个变量的作用是:对对局局部部变变量量用用static声声明明,把把它它分分配配在在静静态态存存储储区区,该该变变量量在在整整个个程程序序执执行期间不释放,其所分配的空间始终存在。行期间不释放,其所分配的空间始终存在。对对全全局局变变量量用用static声声明明,则则该该变变量量的的作作用用域域只只限限于于本本文文件件模模块块(即即被被声声明明的文件中的文件中)。210第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别7、关于变量的声明和定义、关于变量的声明和定义p一一般般为为了了叙叙述述方方便便,把把建建立立存存储储空空间间的的变变量量声声明明称称定定义义,而而把把不不需需要要建立存储空间的声明称为声明建立存储空间的声明称为声明p在函数中出现的对变量的声明在函数中出现的对变量的声明(除了用除了用extern声明的以外声明的以外)都是定义都是定义p注注意意:用用auto、register、static声声明明变变量量时时,是是在在定定义义变变量量的的基基础础上上加加上这些关键字,而不能单独使用。上这些关键字,而不能单独使用。inta;statica;编译时会被认为编译时会被认为“重新定义重新定义”211第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别8、存储类别小结、存储类别小结p对一个数据的定义,需要指定两种属性对一个数据的定义,需要指定两种属性:数据类型和存储类别,分别使用两个关键字数据类型和存储类别,分别使用两个关键字可以用可以用extern声明已定义的外部变量声明已定义的外部变量staticinta;/静态局部整型变量或静态外部整型变量静态局部整型变量或静态外部整型变量autocharc;/自动变量,在函数内定义自动变量,在函数内定义registerintd;/寄存器变量,在函数内定义寄存器变量,在函数内定义externb;/将已定义的外部变量将已定义的外部变量b的作用域扩展至此的作用域扩展至此212第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别8、存储类别小结、存储类别小结p从作用域角度分,有局部变量和全局变量从作用域角度分,有局部变量和全局变量:按作用域角度分按作用域角度分局部变量局部变量全局变量全局变量自动变量自动变量静态局部变量静态局部变量寄存器变量寄存器变量静态外部变量静态外部变量外部变量外部变量形式参数可以定义为自形式参数可以定义为自动变量或寄存器变量动变量或寄存器变量213第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别8、存储类别小结、存储类别小结p从变量生存期区分从变量生存期区分,有动态存储和静态存储两种类型有动态存储和静态存储两种类型:按生存期分按生存期分动态存储动态存储静态静态存储存储自动变量自动变量寄存器变量寄存器变量静态局部变量静态局部变量外部变量外部变量形式参数形式参数静态外部变量静态外部变量214第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别8、存储类别小结、存储类别小结p从变量值存放的位置来区分从变量值存放的位置来区分:按变按变量值量值存放存放的位的位置分置分内存中静态存储区内存中静态存储区内存中动态存储区内存中动态存储区静态局部变量静态局部变量静态外部变量静态外部变量自动变量和形式参数自动变量和形式参数寄存器变量寄存器变量外部变量外部变量CPU中的寄存器中的寄存器215inta;intmain()f2();f1();voidf1()autointb;f2();voidf2()staticintc;a的作用域的作用域b的作用域的作用域c的作用域的作用域程序执行过程程序执行过程mainf2f1mainf2f1maina生生存存期期b生生存期存期c生生存存期期216第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别8、存储类别小结、存储类别小结217第八章第八章 函函 数数九、变量的存储类别九、变量的存储类别8、存储类别小结、存储类别小结pstatic对局部变量和全局变量的作用不同对局部变量和全局变量的作用不同:局部变量局部变量:使变量由动态存储方式改变为静态存储方式使变量由动态存储方式改变为静态存储方式全局变量全局变量:使变量局部化使变量局部化(局部于本文件局部于本文件),但仍为静态存储方式,但仍为静态存储方式从从作作用用域域角角度度看看,凡凡有有static声声明明的的,其其作作用用域域都都是是局局限限的的,或或者者是是局局限限于本函数内于本函数内(静态局部变量静态局部变量),或者局限于本文件内,或者局限于本文件内(静态外部变量静态外部变量)218第八章第八章 函函 数数十、内部函数和外部函数十、内部函数和外部函数1、内部函数、内部函数p如果一个函数只能被如果一个函数只能被本文件中其他函数所调用本文件中其他函数所调用,它称为,它称为内部函数内部函数。p在定义内部函数时,在函数名和函数类型的前面加在定义内部函数时,在函数名和函数类型的前面加staticp内部函数又称内部函数又称静态函数静态函数,因为它是用,因为它是用static声明的声明的p通通常常把把只只能能由由本本文文件件使使用用的的函函数数和和外外部部变变量量放放在在文文件件的的开开头头,以以static使之局部化,其他文件不能引用,提高了程序的可靠性使之局部化,其他文件不能引用,提高了程序的可靠性static类型名类型名函数名函数名(形参表形参表)219第八章第八章 函函 数数十、内部函数和外部函数十、内部函数和外部函数2、外部函数、外部函数p定定义义函函数数时时,在在函函数数首首部部加加关关键键字字extern,则则此此函函数数是是外外部部函函数数,可可供供其他文件调用其他文件调用。p如果在定义函数时省略如果在定义函数时省略extern,则默认为外部函数,则默认为外部函数extern类型名类型名函数名函数名(形参表形参表)externintfun(inta,intb)220第八章第八章 函函 数数例8.22 有一个字符串,内有若干个字符,今输入一个字符,要求程序将字符串中该字符删去。用外部函数实现。 分析分析:p分别定义分别定义3个函数用来输入字符串、删除字符、个函数用来输入字符串、删除字符、输出字符串输出字符串p按题目要求把以上按题目要求把以上3个函数分别放在个函数分别放在3个文件中。个文件中。main函数在另一文件中,函数在另一文件中,main函数调用以上函数调用以上3个个函数,实现题目的要求函数,实现题目的要求221第八章第八章 函函 数数file1(文件1) #includevoidmain()externvoidenter_string(charstr);externvoiddelete_string(charstr,charch);externvoidprint_string(charstr);charc,str80;enter_string(str);scanf(“%c”,&c);delete_string(str,c);print_string(str);file2(文件2)voidenter_string(charstr80)gets(str);声明在本函数中将要声明在本函数中将要调用的已在其他文件调用的已在其他文件中定义的中定义的3个函数个函数file3(文件3)voiddelete_string(charstr,charch)inti,j;for(i=j=0;stri!=0;i+)if(stri!=ch)strj+=stri;strj=0;file4(文件4)voidprint_string(charstr)printf(%sn,str);非空非空I空空非空非空a非空非空m空空 非空非空h非空非空a非空非空p非空非空p非空非空y结束结束00i=0j=01122334 546576879810223谢谢 谢!谢!
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号