C语言程序设计(第二版)中160_第1页
C语言程序设计(第二版)中160_第2页
C语言程序设计(第二版)中160_第3页
C语言程序设计(第二版)中160_第4页
C语言程序设计(第二版)中160_第5页
已阅读5页,还剩155页未读 继续免费阅读

下载本文档

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

文档简介

C语言程序设计(第二版)中制作人:王敬华第6章循环结构程序设计第07章数组第08章函数第6章循环结构程序设计制作人:王敬华第6章:循环结构程序设计

学习的意义

语言程序设计教程第二版第六章循环结构程序设计C许多实际问题中往往需要有规律地重复某些操作,如菜谱中可以有:“打鸡蛋直到泡沫状〞这样的步骤,也就是说,在鸡蛋没有打成泡沫状时要反复地打。相应的操作在计算机程序中就表达为某些语句的重复执行,这就时所谓的循环。下面来思考一个问题:如何编程来计算1+2+3+…+100?程序如下:ints=0;s=s+1;s=s+2;s=s+3;……s=s+100;printf(“s=%d〞,s);重复100次,晕!!!有没有更好的方法来计算呢?有!就是用循环来编程。第4章已讨论程序结构顺序结构选择结构循环结构本章讨论第5章已讨论

While、do-while、for语句循环嵌套

Break、continue、goto语句

exit()函数循环结构类型的选择及转换循环结构程序设计举例本章小结学习目标

理解循环结构的含义;掌握C语言三种循环结构的特点;掌握while、do-while、for、goto、break、continue语句的使用方法;掌握不同循环结构的选择及其转换方法;掌握混合控制结构程序设计的方法。

学习内容

语言程序设计教程第二版第六章循环结构程序设计C6.1循环结构的程序设计

1.while语句一般形式:while(表达式)

循环体语句;执行流程:expr

T循环体Fwhile其中:while后面的括号〔〕不能省。while后面的表达式可以是任意类型的表达式,但一般是条件表达式或逻辑表达式。表达式的值是是循环的控制条件。语句局部称为循环体,当需要执行多条语句时,应使用复合语句。特点:先判断表达式,再执行循环体语言程序设计教程第二版第六章循环结构程序设计C【例】用while语句求1~100的累计和。

#include<stdio.h>voidmain(){inti=1,sum=0;

while(i<=100){sum+=i; i++; }printf("sum=%d\n",sum);}循环初值循环终值循环条件循环体循环变量增值运行结果:sum=5050语言程序设计教程第二版第六章循环结构程序设计C【例】显示1~10的平方#include<stdio.h>

voidmain(){inti=1;while(i<=10){printf("%d*%d=%d\n",i,i,i*i);i++;}}运行结果:1*1=12*2=43*3=94*4=165*5=256*6=367*7=498*8=649*9=8110*10=100语言程序设计教程第二版第六章循环结构程序设计C(1)如果while后的表达式的值一开始就为假,循环体将一次也不执行。(2)循环体中的语句可为任意类型的C语句。(3)遇到以下情况,退出while循环:表达式为假〔为0〕。循环体内遇到break、return或goto语句〔break和goto语句将在随后介绍〕。while语句本卷须知:inta=0,b=0;while(a>0)//a>0为假,b++不可能执行b++;intnum=0;//字符计数while(1){if(getche()=='\n')//如果输入的字符是回车符,那么返回return;num++;}语言程序设计教程第二版第六章循环结构程序设计C(4)在执行while语句之前,循环控制变量必须初始化,否那么执行的结果将是不可预知的。(5)要在while语句的某处〔表达式或循环体内〕改变循环控制变量,否那么极易构成死循环。(6)允许while语句的循环体又是while语句,从而形成双重循环。while语句本卷须知:例:计算10!#include<stdio.h>voidmain(){inti;//i应赋初始值10longs=1;while(i>=1)s*=i--;printf("10!=%ld\n",s);}i=1;while(i<100)//死循环,因为i的值没变化,永远小于100sum+=i;printf("sum=%d\n",sum);i=1;while(i<=9){j=1;

while(j<=9){printf("%d*%d=%d\n",i,j,i*j);j++;}i++;}语言程序设计教程第二版第六章循环结构程序设计C【例】求两个正整数的最大公因子。我们采用Euclid〔欧几里德〕算法来求最大公因子,其算法是:(1)输入两个正整数m和n。(2)用m除以n,余数为r,如果r等于0,那么n是最大公因子,算法结束,否那么(3)。(3)把n赋给m,把r赋给n,转(2)。#include<stdio.h>voidmain(){intm,n,r;printf("Pleaseinputtwopositiveinteger:");scanf("%d%d",&m,&n);while(n!=0){r=m%n;//求余数m=n;n=r;}printf("Theirgreatestcommondivisoris%d\n",m);}运行结果:Pleaseinputtwopositiveinteger:2456↙Theirgreatestcommondivisoris8语言程序设计教程第二版第六章循环结构程序设计C2.do_while语句一般形式:do

循环体语句;while(表达式);执行流程:其中:while后面的括号〔〕不能省。while最后面的分号;不能省。while后面的表达式可以是任意类型的表达式,但一般是条件表达式或逻辑表达式。表达式的值是是循环的控制条件。语句局部称为循环体,当需要执行多条语句时,应使用复合语句。expr循环体

TFdowhile特点:先执行循环体,再判断表达式语言程序设计教程第二版第六章循环结构程序设计C【例】用do_while语句求1~100的累计和。

#include<stdio.h>voidmain(){inti=1,sum=0;

do{sum+=i; i++; }while(i<=100);printf("sum=%d\n",sum);}运行结果:sum=5050语言程序设计教程第二版第六章循环结构程序设计Cdo_while语句本卷须知:inta=0,b=0;dob++;while(a>0);

(1)如果do-while后的表达式的值一开始就为假,循环体还是要执行一次。(2)在if语句、while语句中,表达式后面都不能加分号,而在do-while语句的表达式后面那么必须加分号,否那么将产生语法错误。(3)循环体中的语句可为任意类型的C语句。(4)和while语句一样,在使用do-while语句时,不要忘记初始化循环控制变量,否那么执行的结果将是不可预知的。(5)要在do-while语句的某处〔表达式或循环体内〕改变循环控制变量的值,否那么极易构成死循环。(6)do-while语句也可以组成多重循环,而且也可以和while语句相互嵌套。语言程序设计教程第二版第六章循环结构程序设计C3.for语句一般形式:for(表达式1;表达式2;表达式3)循环体语句;执行流程:其中:for后面的括号〔〕不能省。表达式1:一般为赋值表达式,给控制变量赋初值。表达式2:关系表达式或逻辑表达式,循环控制条件。表达式3:一般为赋值表达式,给控制变量增量或减量。表达式之间用分号分隔。语句局部称为循环体,当需要执行多条语句时,应使用复合语句。expr2T循环体forexpr1expr3Ffor语句很好地表达了正确表达循环结构应注意的三个问题:控制变量的初始化。循环的条件。循环控制变量的更新。语言程序设计教程第二版第六章循环结构程序设计C【例】用for语句求1~100的累计和。

#include<stdio.h>voidmain(){inti,sum=0;

for(i=1;i<=100;i++)sum+=i; printf("sum=%d\n",sum);}运行结果:sum=5050语言程序设计教程第二版第六章循环结构程序设计Cfor语句本卷须知:例:计算1*2+3*4+5*6+…+99*100。

inti,j;longsum=0;for(i=1,j=2;i<=99;i=i+2,j=j+2)sum+=i*j;printf("sum=%ld\n",sum);(1)表达式1、表达式2、和表达式3可以是任何类型的表达式。比方说,这三个表达式都可以是逗号表达式,即每个表达式都可由多个表达式组成。

逗号表达式逗号表达式语言程序设计教程第二版第六章循环结构程序设计C#include<stdio.h>voidmain(){inti,sum=0;i=1;for(;i<=100;i++)sum+=i;printf("sum=%d\n",sum);}#include<stdio.h>voidmain(){inti,sum=0;i=1;for(;i<=100;)sum+=i++;printf("sum=%d\n",sum);}for语句本卷须知:省掉表达式1,3省掉表达式1

(2)表达式1、表达式2、和表达式3都是任选项,可以省掉其中的一个、两个或全部,但其用于间隔的分号是一个也不能省的。#include<stdio.h>voidmain(){inti,sum=0;i=1;for(;;){if(i>100)break;sum+=i++;}printf("sum=%d\n",sum);}省掉表达式1,2,3语言程序设计教程第二版第六章循环结构程序设计Cfor语句本卷须知:for(a=1;;a++)printf("&d\n",a);(3)表达式2如果为空那么相当于表达式2的值是真。死循环!(4)循环体中的语句可为任意类型的C语句。(5)for语句也可以组成多重循环,而且也可以和while语句和do-while语句相互嵌套。(6)循环体可以是空语句。例:计算用户输入的字符数〔当输入是回车符时统计结束)。#include<stdio.h>voidmain(){intn=0;printf("inputastring:\n");for(;getchar()!='\n';n++);printf("%d",n);}表示循环体为空语句,并非表示for语句结束语言程序设计教程第二版第六章循环结构程序设计C三种循环可互相嵌套,层数不限外层循环可包含两个以上内循环,但不能相互交叉嵌套循环的执行流程(1)while(){……while(){……}…...}(2)do{……do{……}while();…...}while();(3)while(){……do{……}while();…….}嵌套循环的跳转禁止:从外层跳入内层跳入同层的另一循环向上跳转4.循环嵌套(4)for(;;){……do{……}while();……while(){……}…...}外循环内循环内循环语言程序设计教程第二版第六章循环结构程序设计C【例】循环嵌套,输出九九表1234567891234567892468101214161836912151821242791827364554637281……………..ij#include<stdio.h>voidmain(){inti,j;for(i=1;i<10;i++)printf("%4d",i);printf("\n---------------------------------------\n");for(i=1;i<10;i++)for(j=1;j<10;j++)printf((j==9)?"%4d\n":"%4d",i*j);}语言程序设计教程第二版第六章循环结构程序设计Ci<10printf假(0)真(非0)i=1j++j=1j<10真(非0)假(0)i++外循环内循环for(i=1;i<10;i++)for(j=1;j<10;j++)printf((j==9)?"%4d\n":"%4d",i*j);语言程序设计教程第二版第六章循环结构程序设计C5.break与continue语句

break语句功能:在循环语句和switch语句中,终止并跳出循环体或开关体说明:(1)break不能用于循环语句和switch语句之外的任何其它语句之中。(2)break只能终止并跳出最近一层的结构。while(表达式1){

……if(表达式2)break;……}语句……do{

……if(表达式2)break;……}while(表达式1);语句……for(;表达式1;){……if(表达式2)break;……}语句……语言程序设计教程第二版第六章循环结构程序设计C【例】将用户输入的小写字母转换成大写字母,直到输入非小写字母字符。

#include<stdio.h>voidmain(){charc;while(1){c=getchar();//读取一个字符if(c>='a'&&c<='z')//是小写字母putchar(c-'a'+'A');//输出其大写字母else//不是小写字母

break;

//循环退出}}运行结果:howareyou↙HOWAREYOU

语言程序设计教程第二版第六章循环结构程序设计C方法:通过设置一标志变量tag,然后在每层循环后加上一条语句:if(tag)break;其值为1表示跳出循环体,为0那么不跳出。for(…){while(…){……if(…)break;…}while循环后的第一条语句}inttag=0;for(…){while(…){……if(…){tag=1;break;}……}if(tag)break;……}for循环后的第一条语句

多重循环中,break的使用问:在嵌套循环的情况下,如何让break语句跳出最外层的的循环体?语言程序设计教程第二版第六章循环结构程序设计Ccontinue语句功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断。说明:(1)仅用于循环语句中。(2)在嵌套循环的情况下,continue语句只对包含它的最内层的循环体语句起作用。for(…){while(…){……if(…)continue;……}while循环后的第一条语句}语言程序设计教程第二版第六章循环结构程序设计C【例】求输入的十个整数中正数的个数及其平均值。#include<stdio.h>voidmain(){inti,a,num=0;floatsum=0;for(i=0;i<10;i++){scanf("%d",&a);//输入一整数if(a<=0)continue;//如果为负,那么输入下一个整数num++;//正数个数增1sum+=a;//正数和累加}printf("%dplusinteger'ssum:%.0f\n",num,sum);printf("averagevalue:%.2f\n",sum/num);}运行结果:8plusinteger'ssum:45averagevalue:5.63假设输入的10个整数为:123–45–678910

语言程序设计教程第二版第六章循环结构程序设计C5.goto语句

一般形式:goto语句标号;……语句标号:……语句标号:…………goto语句标号;或说明:

语句标号是按标识符规定书写的符号,放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto语句配合使用。

作用:goto语句的作用是在不需要任何条件的情况下直接使程序跳转到该语句标号所标识的语句去执行。

语言程序设计教程第二版第六章循环结构程序设计C

goto语句的应用:例:求1~100的累计和

#include<stdio.h>voidmain(){inti=1,sum=0;

loop:sum+=i++;if(i<=100)//如果i小于或等于100

gotoloop;

//转到标号为loop的语句去执行printf("sum=%d\n",sum);}(1)goto语句可与条件语句配合使用来实现条件转移,构成循环。(2)在嵌套循环的情况下,利用goto语句可以直接从最内层的循环体跳出最外层的循环体。

inttag=0;for(…){while(…){……if(…)gotostop;……}……}stop:for循环后的第一条语句

注意:在结构化程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难。语言程序设计教程第二版第六章循环结构程序设计C6.exit()函数

功能:说明:参数status为int型,status的值传给调用进程〔一般为操作系统〕。按照惯例,当status的值为0或为宏常量EXIT_SUCCESS时,表示程序正常退出;当status的值为非0或为宏常量EXIT_FAILURE时,表示程序出现某种错误后退出。终止整个程序的执行,强制返回操作系统。

调用形式:voidexit(intstatus);头文件

<stdlib.h>语言程序设计教程第二版第六章循环结构程序设计C程序设计分析:由数学知识可知,求三角形面积的公式是:其中,a、b、c是三角形的三个边长,s=(a+b+c)/2。因此,程序中应该有三个float型变量用来存放a、b、c的值,为了方便起见,还应有一个变量存放s,最后有必要设置一个变量来存放三角形的面积值。公式中存在求平方根的操作,这要用到C语言数学库函数sqrt。sqrt函数带有一个参数,它的功能是返回参数的平方根。程序在开始接受用户输入的三角形的三个边长后,首先要对这三边作合法性检查,如三边中有某一边长度小于或等于0,那么终止程序的执行,同样如果s*(s-a)*(s-b)*(s-c)为负,也要终止程序的执行。【例】

输入三角形的边长,求三角形面积。

#include<stdio.h>#include<stdlib.h>#include<math.h>voidmain(){floata,b,c;floats,area;printf("inputthelengthofthreeedgesoftriangle:");scanf("%f%f%f",&a,&b,&c);if(a<=0||b<=0||c<=0){printf("thelengthofthreeedgesoftriangleiserror!\n");

exit(-1);}

s=(a+b+c)/2;s=s*(s-a)*(s-b)*(s-c);if(s<0){printf("thelengthofthreeedgesoftriangleiserror!\n");

exit(-1);}area=(float)sqrt(s);printf("area=%.2f\n",area);}运行结果:inputthelengthofthreeedgesoftriangle:345↙area=6.00inputthelengthofthreeedgesoftriangle:3-45↙thelengthofthreeedgesoftriangleiserror!语言程序设计教程第二版第六章循环结构程序设计C6.2循环结构类型的选择及转换

1.循环结构类型的选择原那么如果循环次数在执行循环体之前就已确定,一般用for循环;如果循环次数是由循环体的执行情况确定的,一般用while循环或者do-while循环。当循环体至少执行一次时,用do-while循环,反之,如果循环体可能一次也不执行,选用while循环。2.循环结构类型之间的相互转换尽管上面对于循环结构的选择给出了原那么性指导意见,但是我们应注意到其实这三种循环结构彼此之间可以相互转换,象前面我们分别用while循环、do-while循环、for循环来求1~100的累计和的例子就说明了这一点。语言程序设计教程第二版第六章循环结构程序设计C【例】求1~100之间的所有素数

问题分析:素数是指除了能被1和它本身整除外,不能被其它任何整数整除的数。例如,17就是一个素数,除了1和17之外,它不能被2~16之间的任何整数整除。根据素数的这个定义,可得到判断素数的方法:把m作为被除数,把i=2~(m-1)依次作为除数,判断被除数m与除数i相除的结果,假设都除不尽,即余数都不为0,那么说明m是素数,反之,只要有一次能除尽〔余数为0〕,那么说明m存在一个1和它本身以外的另一个因子,它不是素数。事实上,根本用不着除那么屡次,用数学的方法可以证明:只需用2~之间〔取整数〕数去除m,即可得到正确的判定结果。这一思路的算法如下:从键盘输入一正整数m。计算k=i从2变化到k,依次检查m%i是否为0。假设m%i为0,那么判定m不是素数,并终止对其余i值的检验;否那么,令i=i+1;并继续对其余i值进行检验,直到全部检验完毕为止,这时判定m是素数。语言程序设计教程第二版第六章循环结构程序设计C#include<stdio.h>#include<math.h>voidmain(){intm,i,k;printf("inputanumber:“);scanf("%d",&m);

k=sqrt(m);i=2;

while(i<=k)

{if(m%i==0)break;i++;}if(i>k)printf("yes\n");elseprintf("no\n");}while循环#include<stdio.h>#include<math.h>voidmain(){intm,i,k;printf("inputanumber:“);scanf("%d",&m);k=sqrt(m);

for(i=2;i<=k;i++)if(m%i==0)break;if(i>k)printf("yes\n");elseprintf("no\n");}for循环#include<stdio.h>#include<math.h>voidmain(){intm,i,k;printf("inputanumber:“);scanf("%d",&m);

k=sqrt(m);i=2;

do

{if(m%i==0)break;i++;}while(i<=k);

if(i>k)printf("yes\n");elseprintf("no\n");}do_while循环语言程序设计教程第二版第六章循环结构程序设计C6.3循环结构程序设计举例

【例1】验证哥德巴赫猜测:任一充分大的偶数,可以用两个素数之和表示。例如:4=2+2,6=3+3,98=19+79这一思路的算法如下:读入大于3的偶数n。

p=1do{p=p+1;q=n-p;p是素数吗?

q是素数吗?

}whilep、q有一个不是素数。输出n=p+q。问题分析:读入一个偶数n,将它分成p和q,使n=p+q。怎样分呢?可以令p从2开始,每次加1,而令q=n-p,如果p、q均为素数,那么正为所求,否那么令p=p+1再试。flagp=1;for(j=2;j<=(int)sqrt(p);j++)if(p除以j的余数=0){flagp=0;break;}

flagq=1;for(j=2;j<=(int)sqrt(q);j++)if(q除以j的余数=0){flagq=0;break;}

设置两个标志量flagp和flagq,0—是素数,1—不是素数

}while(flagp*flagq==0);

语言程序设计教程第二版第六章循环结构程序设计C#include<stdio.h>#include<stdlib.h>#include<math.h>voidmain(){inti,n,p,q,flagp,flagq;printf("pleaseinputn:");scanf("%d",&n);//输入一偶数if(n<4||n%2!=0)//如果该数不是偶数{printf("inputdataerror!\n");exit(-1);//程序结束}p=1;

do{p++;q=n-p;flagp=1;for(i=2;i<=(int)sqrt(p);i++){if(p%i==0){flagp=0;break;}}flagq=1;for(i=2;i<=(int)sqrt(q);i++){if(q%i==0){flagq=0;break;}}}while(flagp*flagq==0);printf("%d=%d+%d\n",n,p,q);}判断p是否为素数

判断q是否为素数

运行结果:pleaseinputn:98↙98=19+79pleaseinputn:9↙inputdataerror!语言程序设计教程第二版第六章循环结构程序设计C【例】利用下面的公式求π的近似值,要求累加到最后一项小于10-6为止。问题分析:这是一个累加求和的问题,但这里的循环次数是预先未知的,而且累加项以正负交替的规律出现,如何解决这类问题呢?在本例中,累加项的构成规律可用寻找累加项通式的方法得到,具体表示为t=s/n;即累加项由分子和分母两局部组成,分子s按+1,-1,+1,-1,…交替变化,可用赋值语句s=-s;实现,s的初始值取为1,分母n按1,3,5,7,…变化,用n=n+2;语句实现即可,n的初始值取为1.0。#include<stdio.h>#include<math.h>voidmain(){ints=1;floatn=1.0,t=1,pi=0;while(fabs(t)>=1e-6){pi+=t;n+=2;s=-s;t=s/n;}pi*=4;printf("pi=%.6f\n",pi);}运行结果:pi=3.141594语言程序设计教程第二版第六章循环结构程序设计C【例】打印大小可变的菱形图案〔下面菱形的大小是7〕。

﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡问题分析:菱形的大小size其实就是中间行中*号的个数,也是整个菱形的行数,其值必须是奇数。问题的关键之一是如何确定每行中*号的个数。经过分析得知:当行数i〔假设最上面的一行为第1行〕≦(size+1)/2时,该行上的*号个数为n=2*i-1,否那么n=2*(size-i+1)-1。问题的关键之二是如何确定每行显示的第一个*号的位置,也就是显示第一个*号之前应显示多少个空格。经过分析得知:每行应显示的空格数为m=(size-n)/2个。#include<stdio.h>#include<stdlib.h>voidmain(){inti,j,k,m,n,size;printf("inputsize:");//输入大小提示scanf(“%d〞,&size);//输入大小//如果为小于或等于0的数或为偶数if(size<=0||size%2==0){printf("thesizeiserror!\n");exit(-1);//程序结束}

for(i=1;i<=size;i++)//控制行数{n=(i<=(size+1)/2)?i:size-i+1;//每行中"*"号的个数n=2*n-1;m=(size-n)/2+15;//每行打印"*"之前应打印的空格数for(k=1;k<=m;k++)//打印每行前面的空格printf("");for(j=1;j<=n;j++)//打印每行的"*"printf("*");printf("\n");//打印一行后,回车换行}}语言程序设计教程第二版第六章循环结构程序设计C【例】计算用户输入的两正整数之间的所有整数中0,1,2,…,9数码的个数。例如,101~104之间总共包含四个整数101,102,103,104,其中0的个数为4,1的个数为5,2、3、4的个数都为1,其余数码没出现都为0。问题分析:问题的关键是要计算某整数中包含的各个数码的个数,必须对该整数进行分解,求得所包含的各个数码,其方法可以通过每次除以10取余数得到,然后再对商进行同样的处理,直到商为0时为止。对所得到的数码进行计数,可采用switch语句来实现。#include<stdio.h>#include<stdlib.h>voidmain(){intnum1,num2;intn,s,r;intcount0=0,count1=0,count2=0,count3=0,count4=0;intcount5=0,count6=0,count7=0,count8=0,count9=0;printf("inputtwointeger:");scanf("%d%d",&num1,&num2);if(num1<0||num2<0||num1>num2){printf("inputerror!\n");exit(-1);}for(n=num1;n<=num2;n++){s=n;do{r=s%10;switch(r){case0:count0++;break;case1:count1++;break;case2:count2++;break;case3:count3++;break;case4:count4++;break;case5:count5++;break;case6:count6++;break;case7:count7++;break;case8:count8++;break;case9:count9++;break;}s=s/10;}while(s!=0);}//forprintf("0--%-4d1--%-4d2--%-4d3--%-4d\n",count0,count1,count2,count3);printf("4--%-4d5--%-4d6--%-4d7--%-4d\n",count4,count5,count6,count7);printf("8--%-4d9--%-4d\n",count8,count9);}运行结果:inputtwointeger:15003000↙0–4031–9002–14003–4014–4005–5006–5007–5008–5009–500语言程序设计教程第二版第六章循环结构程序设计C本章小结本章主要讨论了循环结构程序设计的有关方法,重点介绍了与C语言三种循环控制结构有关的while语句、do-while语句及for语句。本章所涉及到的主要关键字有:while、do、for、goto、break、continue。C语言提供了三种循环语句。for语句主要适用于循环次数确定的循环结构。循环次数及控制条件要在循环过程中才能确定的循环可用while或do-while语句。三种循环语句可以相互嵌套组成多重循环,循环之间可以并列但不能交叉。三种循环结构可以相互转换。可用转移语句把流程转出循环体外,但不能从外面转向循环体内。在循环程序中应防止出现死循环,即应保证循环控制变量的值在运行过程中可以得到修改,并使循环条件逐步变为假,从而结束循环。break、continue和goto语句都可用于流程控制。其中,break语句用于退出switch或一层循环结构,continue语句用于结束本次循环,继续执行下一次循环,goto语句无条件转移到标号所标识的语句处去执行。当程序需要退出多重循环时,用goto语句比用break语句更直接方便;当需要结束程序运行时,可以调用exit()函数来实现。习题:P167~P1731、2、3、4(1、3、4、6、8、12①)

语言程序设计教程第二版第六章循环结构程序设计C第7章数组制作人:王敬华第7章:数组

学习的意义

语言程序设计教程第二版第七章数组C到目前为止,我们已经讨论了C语言中的根本数据类型,如果用根本数据类型来定义某些变量,那么这些变量在内存中将占用各自的内存单元,变量之间的制约关系无法表达,不能表现出这些变量之间的关联性,看不出它们之间有任何的联系,我们把这些变量称之为“离散变量〞,对它们的访问只能通过变量名逐一进行。下面来思考一个问题:如何编程来实现对100个数进行排序呢?太复杂了!晕!!!解题思路:定义100个整型变量来分别存放这100个整数,然后再对这些变量的值进行比较、交换等操作。有没有更好的方法来解决呢?有!就是用数组来编程。构造数据类型之一数组:有序数据的集合,用数组名标识元素:属同一数据类型,用数组名和下标确定学习目标

学习内容

一维数组一维数组的定义和引用一维数组的赋值一维数组的应用举例二维数组二维数组的定义和引用二维数组的赋值二维数组的应用举例

字符串与数组字符串的本质字符及字符串操作的常用函数字符串数组数组综合应用举例本章小结理解数组变量在内存中的存放形式;掌握一维数组和二维数组变量的定义和数组元素的引用;掌握字符串与字符数组的区别;掌握各种字符串库函数的用法;语言程序设计教程第二版第七章数组C7.1一维数组

1、一维数组的定义定义方式:存储类型符数据类型符数组变量名[整型常量表达式];数组中各元素的存储类别数组元素的数据类型合法的标识符表示元素个数下标从0开始[]:数组运算符单目运算符左结合不能用()用分号结尾例如:inta[10];//定义了有10个数据元素的int型数组afloatf[20];//定义了有20个数据元素的float型数组fcharstr1[10],str2[20];//定义了有10个和20个数据元素的char型数组str1和str2语言程序设计教程第二版第七章数组C定义说明:(1)数组定义时,必须指定数组的大小〔或长度〕,数组大小必须是整型常量表达式,不能是变量或变量表达式。(2)数组定义后,系统将给其分配一定大小的内存单元,其所占内存单元的大小与数组元素的类型和数组的长度有关。数组所占内存单元的字节数=数组大小×sizeof〔数组元素类型〕(3)数组中每个数组元素的类型均相同,它们占用内存中连续的存储单元,其中第一个数组元素的地址是整个数组所占内存块的低地址,也是数组所占内存块的首地址,最后一个数组元素的地址是整个数组所占内存块的高地址〔末地址〕。例如,下面对数组的定义是错误的:intn=10;inta[n];//数组的大小不能是变量intb[10.3];//数组的大小不能是浮点常量intc[n+10];//数组的大小不能是变量表达式例如:shortinta[20];那么数组a所占内存单元的大小为:20*sizeof(short)=20*2=40〔字节〕。语言程序设计教程第二版第七章数组C2、一维数组的引用引用格式:数组变量名[下标]引用说明:(1)下标可以是整型常量、整型变量或整型表达式。C语言规定,下标的最小值是0,最大值那么是数组大小减1。占用的字节数为:10*sizeof(short)=10*2=20a[0]a[1]a[2]a[9]……内存地址2000200220042018a……第1个元素……第2个元素第3个元素第10个元素例:shortinta[10];

语言程序设计教程第二版第七章数组C引用说明:

(2)只能逐个引用数组元素,不能一次引用整个数组(3)数组定义以后,数组中的每一个元素其实就相当与一个变量,所以我们有时也把数组元素称为下标变量。对变量的一切操作同样也适合于数组元素。(4)数组引用要注意越界问题。(5)数组必须先定义,后使用例inta[10];printf(“%d〞,a);()必须for(j=0;j<10;j++)printf(“%d\t〞,a[j]);()例:inta[3];a[0]=2;//将数组a的第1个元素赋值为2a[1]=4;//将数组a的第2个元素赋值为4a[2]=a[0]+a[1];//将数组a的第1个元素的值与第2个元素的值相加赋给第3个元素〔值为6〕存储单元有效地址=数组的起始地址+下标×sizeof〔数组元素类型〕shortinta[10];shortx=a[10];//引用越界,a[10]的地址为:2000+10*2=2021,只能引用a[0]~a[9]例

intx=a[1];//错误,应先定义数组a,再引用

inta[10];语言程序设计教程第二版第七章数组C3、一维数组的赋值一维数组的初始化赋值数据类型符数组变量名[常量表达式]={表达式1,表达式2,…,表达式n};初始化赋值说明:(1)“=〞后面的表达式列表一定要用{}括起来,被括起来的表达式列表被称为初值列表,表达式之间用“,〞分隔;(2)表达式的个数不能超过数组变量的大小;例

inta[4]={1,2,3,4,5};//超出了数组的大小(3)表达式1是第1个数组元素的值,表达式2是第2个数组元素的值,依此类推;例

inta[5]={0,1,2,3,4};经过以上定义和初始化后,a[0]=0,a[1]=1,a[2]=2,a[3]=3,a[4]=4。

语言程序设计教程第二版第七章数组C初始化赋值说明:(4)如果表达式的个数小于数组的大小,那么未指定值的数组元素被赋值为0;例

inta[10]={0,1,2,3,4};

a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]a00112233440000000000(5)当对全部数组元素赋初值时,可以省略数组变量的大小,此时数组变量的实际大小就是初值列表中表达式的个数。例charstr[]={'a','b','c','d','e'};那么数组str的实际大小为5。注意:在定义数组时,如果没有为数组变量赋初值,那么就不能省略数组的大小。而且数组不初始化,其数组元素为随机值。语言程序设计教程第二版第七章数组C一维数组在程序中赋值C语言除了在定义数组变量时用初值列表对数组整体赋值以外,无法再对数组变量进行整体赋值。

inta[5];

a={1,2,3,4,5};a[]={1,2,3,4,5};a[5]={1,2,3,4,5};错误!数组定义后,如何对数组进行赋值呢?只能通过C语句对数组中的数组元素逐一赋值。使用赋值语句来逐一赋值例

inta[4];a[0]=1;a[1]=2;a[2]=3;a[3]=4;charstr[80];str[0]='b';str[1]='y';str[2]='e';str[3]='\0';

//将数组str赋值为一字符串"bye"

这种方法是一种简单而且行之有效的方法,它适用于长度较小的数组或对长度较大的数组局部元素赋值,而且可对每个数组元素赋不同的值。语言程序设计教程第二版第七章数组C一维数组在程序中赋值使用循环语句来逐一赋值例如,将数组a的各元素赋值成奇数序列。inta[10],i;for(i=0;i<10;i++)a[i]=2*i+1;例如,接受用户键盘输入赋值给数组各元素。inta[10],i;for(i=0;i<10;i++)scanf("%d",&a[i]);判断以下赋值是否正确?inta[3];scanf("%d%d%d",a);×这种方法是在编程中普遍使用的一种方法,它适用于对某数组元素进行有规律的赋值或接受用户通过键盘输入对数组元素的赋值

。语言程序设计教程第二版第七章数组C一维数组在程序中赋值使用memset函数来赋值memset函数原型:

void*memset(void*s,charch,unsignedn)

功能:就是将s为首地址的一片连续的n个字节内存单元都赋值为ch。例如,将数组str的每个数据单元赋值为'a'。charstr[10];memset(str,'a',10);例如,将数组a的每个数据单元赋值为0〔清0〕。inta[10];memset(a,0,10*sizeof(int));这种方法是适合于字节型数组的整体赋值,或对非字节型数组进行清0。语言程序设计教程第二版第七章数组C一维数组在程序中赋值使用memcpy函数实现数组间的赋值memcpy函数原型:

void*memcpy(void*d,void*s,unsignedn)

功能:将s为首地址的一片连续的n个字节内存单元的值拷贝到以d为首地址的一片连续的内存单元中

。例如,两个数组元素之间的赋值

。inta[5]={1,2,3,4,5},b[5],i;for(i=0;i<5;i++)b[i]=a[i];memcpy(b,a,5*sizeof(int));注意:在使用memset和memcpy函数时,源程序中要包含头文件“string.h〞。在TC或BC下头文件也可用“mem.h〞,在VC下,那么也可用“memory.h〞。语言程序设计教程第二版第七章数组C4、一维数组应用举例【例1】输入一行字符,统计其中各个大写字母出现的次数。#include<stdio.h>#include<memory.h>voidmain(void){charch;intnum[26],i;memset(num,0,26*sizeof(int));//初始化数组numwhile((ch=getchar())!='\n')//输入字符串,判断统计if(ch>='A'&&ch<='Z')//是否为大写字母num[ch-'A']++;for(i=0;i<26;i++)//输出结果{if(i%9==0)printf("\n");printf("%c(%d)",'A'+i,num[i]);}printf("\n");}运行结果:AABBCCxyYzEEE↙A(2)B(2)C(2)D(0)E(3)F(0)G(0)H(0)I(0)J(0)K(0)L(0)M(0)N(0)O(0)P(0)Q(0)R(0)S(0)T(0)U(0)V(0)W(0)X(0)Y(1)Z(0)语言程序设计教程第二版第七章数组C4、一维数组应用举例【例2】用冒泡排序法将10个整数按照从小到大的顺序排序排序过程:(1)比较第一个数与第二个数,假设为逆序a[0]>a[1],那么交换;然后比较第二个数与第三个数;依次类推,直至第n-1个数和第n个数比较为止——第一趟冒泡排序,结果最大的数被安置在最后一个元素位置上;(2)对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在第n-1个元素位置;(3)重复上述过程,共经过n-1趟冒泡排序后,排序结束语言程序设计教程第二版第七章数组C3849657613273097

第一趟38496513273076

第二趟384913273065第三趟3813273049

第四趟13273038

第五趟132730

第六趟1327

第七趟4938659776132730

初始关键字n=838497697979797132730137676762730136565652730134949492730133838382730冒泡排序图示效果语言程序设计教程第二版第七章数组Cforj=0toNUM–i–1输入NUM个数给a[0]到a[NUM-1]fori=1toNUM–1a[j]>a[j+1]真假a[j]a[j+1]输出a[0]到a[NUM–1]

#include<stdio.h>#defineNUM10voidmain(){inta[NUM],i,j,t;printf("input%dnumbers:\n",NUM);for(i=0;i<NUM;i++)//输入NUM个整数scanf("%d",&a[i]);for(i=1;i<NUM;i++)//趟数,共NUM-1趟for(j=0;j<NUM-i;j++)//实现一次冒泡操作if(a[j]>a[j+1])//交换a[j]和a[j+1]{t=a[j];a[j]=a[j+1];a[j+1]=t;}

//输出排好序的数据printf("thesortednumbers:\n");for(i=0;i<NUM;i++)printf("%d",a[i]);}运行结果:input10numbers:10127689345↙thesortednumbers:12345678910缺乏之处:对已排好序的序列仍然要进行9轮冒泡操作,尽管不会有任何数据交换操作。如何修改呢?语言程序设计教程第二版第七章数组C对冒泡排序的改进:当一次冒泡过程中发现没有交换操作时,说明序列已经排好序了,便终止冒泡操作。为了标记在比较过程中是否发生了数据交换,在程序中设立一个标志变量flag,在每趟比较前,把flag变量置为0,如果在这趟比较过程中发生了交换,把变量flag的值置为1。在这一趟比较结束后判断如果flag变量取值等于0表示可以结束排序过程,否那么进行下一趟比较。

#include<stdio.h>#defineNUM10

voidmain(){inta[NUM],i,j,t,flag;printf("input%dnumbers:\n",NUM);for(i=0;i<NUM;i++)//输入NUM个整数scanf("%d",&a[i]);for(i=1;i<NUM;i++)//轮次,共NUM-1次{flag=0;for(j=0;j<NUM-i;j++)//实现一次冒泡操作if(a[j]>a[j+1])//交换a[j]和a[j+1]{t=a[j];a[j]=a[j+1];a[j+1]=t;flag=1;}

if(flag==0)break;}printf("thesortednumbers:\n");//输出排好序的数据for(i=0;i<NUM;i++)printf("%d",a[i]);}语言程序设计教程第二版第七章数组C4、一维数组应用举例【例3】用选择排序法将10个整数按照从小到大的顺序排序排序过程:(1)首先通过n-1次比较,从n个数中找出最小的,将它与第一个数交换—第一趟选择排序,结果最小的数被安置在第一个元素位置上;(2)再通过n-2次比较,从剩余的n-1个数中找出关键字次小的记录,将它与第二个数交换—第二趟选择排序;(3)重复上述过程,共经过n-1趟排序后,排序结束。语言程序设计教程第二版第七章数组C初始:[493865

温馨提示

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

评论

0/150

提交评论