C语言三种循环语句.docx
《C语言三种循环语句.docx》由会员分享,可在线阅读,更多相关《C语言三种循环语句.docx(41页珍藏版)》请在冰豆网上搜索。
C语言三种循环语句
三种基本的循环语句:
for语句、while语句和do-while语句。
一、循环语句
(一)、for循环它的一般形式为:
for(<初始化〉;<条件表过式〉;〈增量>)
语句;
初始化总是一个赋值语句,它用来给循环控制变量赋初值;条件表达式是一个关系表达式,它决定什么时候退出循环;增量定义循环控制变量每循环一次后按什么方式变化。
这三个部分之间用;分开。
例如:
for(i=1;i<=10;i++)
语句;
上例中先给i赋初值1,判断i是否小于等于10,若是则执行语句,之后值增加1。
再重新判断,直到条件为假,即i>10时,结束循环。
注意:
(1).for循环中语句可以为语句体,但要用{和}将参加循环的语句括起来。
(2).for循环中的初始化、条件表达式和增量都是选择项,即可以缺省,但;不能缺省。
省略了初始化,表示不对循环控制变量赋初值。
省略了条件表达式,则不做其它处理时便成为死循环。
省略了增量,则不对循环控制变量进行操作,这时可在语句体中加入修改循环控制变量的语句.
(3).for循环可以有多层嵌套。
例如:
for(;;)语句;
for(i=1;;i+=2)语句;
for(j=5;;)语句;
这些for循环语句都是正确的。
main()
{
inti,j;
printf(ij\n);
for(i=0;i〈2;i++)
for(j=0;j〈3;j++)
printf(%d%d\n,i,j);
}
输出结果为:
ij
00
01
02
10
11
12
用for循环求1+2+……+100的和:
main()
{
intsn=0,i;
for(i=1;i<=100;i++)
sn+=i;/*1+2+……+100*/
printf(%d\n,sn);
}
从程序可以看出,使用循环语句可以大大简化代码。
(二)、while循环它的一般形式为:
while(条件)
语句;
while循环表示当条件为真时,便执行语句。
直到条件为假才结束循环.并继续执行循环程序外的后续语句。
例如:
#includestdio。
h
main()
{
charc;
c=’\0’;/*初始化c*/
while(c!
=’\n')/*回车结束循环*/
c=getche();/*带回显的从键盘接收字符*/
}
上例中,while循环是以检查c是否为回车符开始,因其事先被初始化为空,所以条件为真,进入循环等待键盘输入字符;一旦输入回车,则c='\n’,条件为假,循环便告结束。
与for循环一样,while循环总是在循环的头部检验条件,这就意味着循环可能什么也不执行就退出。
注意:
(1)。
在while循环体内也允许空语句。
例如:
while((c=getche())!
=’\n');
这个循环直到键入回车为止。
(2).可以有多层循环嵌套。
(3).语句可以是语句体,此时必须用{和}括起来。
用while循环求1+2+……+100的和:
main()
{
intsn=0,i=0;
while(++i<=100)
sn+=i;/*求1+2+……+100*/
printf(%d\n,sn);
}
(三)、do——while循环它的一般格式为:
do
{
语句块;
}
while(条件);
这个循环与while循环的不同在于:
它先执行循环中的语句,然后再判断条件是否为真,如果为真则继续循环;如果为假,则终止循环.因此,do—while循环至少要执行一次循环语句。
同样当有许多语句参加循环时,要用{和}把它们括起来。
用do—-while循环求1+2+……+100的和:
main()
{
intsn=0,i=1;
do
sn+=i;/*求1+2+……+100*/
while(++i<=100);
printf(%d\n,sn);
}
从上面三个程序看出,使用for,while和do-—while求解同样的问题,基本思路都差不多,只是在第一次计算时,注意初值。
二、循环控制
(一)、break语句
break语句通常用在循环语句和开关语句中.当break用于开关语句switch中时,可使程序跳出switch而执行switch以后的语句;如果没有break语句,则将成为一个死循环而无法退出。
break在switch中的用法已在前面介绍开关语句时的例子中碰到,这里不再举例。
当break语句用于do—while、for、while循环语句中时,可使程序终止循环而执行循环后面的语句,通常break语句总是与if语句联在一起。
即满足条件时便跳出循环.
例如:
main()
{
intsn=0,i;
for(i=1;i〈=100;i++)
{
if(i==51)break;/*如果i等于51,则跳出循环*/
sn+=i;/*1+2+……+50*/
}
printf(%d\n,sn);
}
可以看出,最终的结果是1+2+……+50。
因为在i等于51的时候,就跳出循环了。
自己写写怎样在while和do——while循环中增加break语句.
注意:
1.break语句对if—else的条件语句不起作用。
2。
在多层循环中,一个break语句只向外跳一层.
例如:
main()
{
inti,j;
printf(ij\n);
for(i=0;i〈2;i++)
for(j=0;j〈3;j++)
{
if(j==2)break;
printf(%d%d\n,i,j);
}
}
输出结果为:
ij
00
01
10
11
当i==0,j==2时,执行break语句,跳出到外层的循环,i变为1。
(二)、continue语句
continue语句的作用是跳过循环本中剩余的语句而强行执行下一次循环。
continue语句只用在for、while、do—while等循环体中,常与if条件语句一起使用,用来加速循环.
例如:
main()
{
intsn=0,i;
for(i=1;i〈=100;i++)
{
if(i==51)continue;/*如果i等于51,则结束本次循环*/
sn+=i;/*1+2+……+50+52+……+100*/
}
printf(%d\n,sn);
}
从程序中可以看出,continue语句只是当前的值没有执行,也就是说当前的值跳过去了,接着执行下次循环。
main()
{
inti,j;
printf(ij\n);
for(i=0;i<2;i++)
for(j=0;j〈3;j++)
{
if(j==1)continue;
printf(%d%d\n,i,j);
}
}
输出结果为:
ij
00
02
10
12
(三)、goto语句
goto语句是一种无条件转移语句,与BASIC中的goto语句相似。
goto语句的使用格式为:
goto标号;
其中标号是TurboC2。
0中一个有效的标识符,这个标识符加上一个:
一起出现在函数内某处,执行goto语句后,程序将跳转到该标号处并执行其后的语句。
标号既然是一个标识符,也就要满足标识符的命名规则。
另外标号必须与goto语句同处于一个函数中,但可以不在一个循环层中.通常goto语句与if条件语句连用,当满足某一条件时,程序跳到标号处运行。
goto语句通常不用,主要因为它将使程序层次不清,且不易读,但在多层嵌套退出时,用goto语句则比较合理.
main()
{
intsn=0,i;
for(i=1;i<=100;i++)
{
if(i==51)gotoloop;/*如果i等于51,则跳出循环*/
sn+=i;/*1+2+……+50*/
}
loop:
;
printf(%d\n,sn);
}
可以看出,这儿的goto语句和break作用很类似.
这儿的loop:
;
printf(%d\n,sn);
也可以写成loop:
printf(%d\n,sn);
main()
{
intsn=0,i;
for(i=1;i〈=100;i++)
{
if(i==51)gotoloop;/*如果i等于51,则跳出本次循环*/
sn+=i;/*1+2+……+50+52+……+100*/
loop:
;
}
printf(%d\n,sn);
}
可以看出这儿的loop语句和continue的作用类似.
但是某些情况下又必须使用goto语句,否则会让程序大大臃肿。
如:
main()
{
inti,j,k;
printf(ijk\n);
for(i=0;i<2;i++)
for(j=0;j<3;j++)
for(k=0;k〈3;k++)
{
if(k==2)gotoloop;
printf(%d%d%d\n,i,j,k);
}
loop:
;
}
输出结果为:
ijk
000
001
如果不使用goto语句,而使用break,continue语句,应该这样
main()
{
inti,j,k;
printf(ij\n);
for(i=0;i〈2;i++)
{
for(j=0;j〈3;j++)
{
for(k=0;k〈3;k++)
{
if(k==2)break;
printf(%d%d%d\n,i,j,k);
}
if(k==2)break;
}
if(k==2)break;
}
}
输出结果为:
ijk
000
001
所以在同时跳出多层循环时,应该使用goto语句。
记住,所有的goto语句其实都是可以用break,continue代替的。
下面举几个例子:
1.求两个整数的最大公约数。
例如10和15的最大公约数是5。
分析:
最大公约数一定小于等于最小的那个数一半,同时能被两数整除。
main()
{
intnum1,num2,i,min;
scanf(%d%d,&num1,&num2);
min=num1
for(i=min/2;i〉0;i-—)
if(num1%i==0&&num2%i==0)break;
printf(最大公约数为%d\n,i);
}
2.求1!
+2!
+……+n!
(n〈10)
main()
{
intn,i;
longtemp=1,sn=0;/*从9!
以后,所得的值就超过了int范围*/
scanf(%d,&n);
for(i=1;i〈=n;i++)
{
temp*=i;
sn+=temp;/*如果没有这一步,求的就是n!
*/
}
printf(%ld\n,sn);
}
那么想想,如果求1!
+3!
+5!
+……+n!
应该怎么办?
3.判断一个整数是不是素数(素数就是只能被本身和1整除的数)。
#includemath。
h
main()
{
intnum,i,flag=0;
scanf(%d,&num);
for(i=2;i
{
flag=0;/*标志变量复位*/
if(num%i==0)
{
flag=1;
break;
}
}
if(flag==0)printf(是素数\n);
elseprintf(不是素数\n);
}
可以说,在所有的C语言书上,都有判断素数的例题.它的编程思想是:
把一个变量作为标志变量,用来标志是不是素数;循环体是从2到sqrt(num),因为如果一个数不是素数的话,一定能分解成num=num1*num2,它们中的最小值一定小于sqrt(num),所以循环的时候只要到sqrt(num)就可以了。
同时要注意变量复位的问题。
二、递归
递归,是函数实现的一个很重要的环节,很多程序中都或多或少的使用了递归函数。
递归的意思就是函数自己调用自己本身,或者在自己函数调用的下级函数中调用自己。
递归之所以能实现,是因为函数的每个执行过程都在栈中有自己的形参和局部变量的拷贝,这些拷贝和函数的其他执行过程毫不相干。
这种机制是当代大多数程序设计语言实现子程序结构的基础,是使得递归成为可能。
假定某个调用函数调用了一个被调用函数,再假定被调用函数又反过来调用了调用函数。
这第二个调用就被称为调用函数的递归,因为它发生在调用函数的当前执行过程运行完毕之前.而且,因为这个原先的调用函数、现在的被调用函数在栈中较低的位置有它独立的一组参数和自变量,原先的参数和变量将不受影响,所以递归能正常工作。
程序遍历执行这些函数的过程就被称为递归下降。
程序员需保证递归函数不会随意改变静态变量和全局变量的值,以避免在递归下降过程中的上层函数出错.程序员还必须确保有一个终止条件来结束递归下降过程,并且返回到顶层。
例如这样的程序就是递归:
voida(int);
main()
{
intnum=5;
a(num);
}
voida(intnum)
{
if(num==0)return;
printf(%d,num);
a(--num);
}
在函数a()里面又调用了自己,也就是自己调用本身,这样就是递归。
那么有些人可能要想,这不是死循环吗?
所以在递归函数中,一定要有return语句,没有return语句的递归函数是死循环。
我们分析上面的例子,先调用a(5),然后输出5,再在函数中调用本身a(4),接着回到函数起点,输出4,……,一直到调用a(0),这时发现已经满足if条件,不在调用而是返回了,所以这个递归一共进行了5次.如果没有这个return,肯定是死循环的。
虽然递归不难理解,但是很多在在使用递归函数的时候,问题多多.这里面一般有两个原因:
一是如何往下递归,也就是不知道怎么取一个变量递归下去;二是不知道怎么终止递归,经常弄个死循环出来。
下面看几个例子:
1。
求1+2+……+100的和
先分析一下。
第一递归变量的问题,从题目上看应该取1,2,……,100这些变量的值作为递归的条件;第二就是如何终止的问题,从题目上看应该是当数为100的时候就不能往下加了.那么我们试着写一下程序。
intadd(int);
main()
{
intnum=1,sn;
sn=add(num);
printf(%d\n,sn);
getch();
}
intadd(intnum)
{
staticintsn;
sn+=num;
if(num==100)returnsn;
add(++num);
}
分析一下程序:
前调用add
(1),然后在子函数中把这个1加到sn上面。
接着调用add
(2),再把sn加2上来。
这样一直到100,到了100的时候,先加上来,然后发现满足了if条件,这时返回sn的值,也就是1+2+……+100的值了.
这里有一个问题一定要注意,就是staticintsn;
有些人就不明白,为什么要使用static类型修饰符,为什么不使用intsn=0;?
如果使用intsn=0;这样的语句,在每次调用函数add()的时候,sn的值都是赋值为0,也就是第一步虽然加了1上来,可是第二次调用的时候,sn又回到了0。
我们前面说了,static能保证本次初始化的值是上次执行后的值,这样也就保证了前面想加的结果不会丢失。
如果你修改为intsn=0,最后结果一定是最后的100这个值而不是5050。
2。
求数列s(n)=s(n-1)+s(n-2)的第n项。
其中s
(1)=s
(2)=1。
可以看出,终止条件一定是s
(1)=s
(2)=1。
递归下降的参数一定是n。
inta(int);
main()
{
intn,s;
scanf(%d,&n);
s=a(n);
printf(%d\n,s);
getch();
}
inta(intn)
{
if(n<3)return1;
returna(n-1)+a(n-2);
}
这个题目主要说明的是,在函数中,不一定只有一个return语句,可以有很多,但是每次对归的时候只有一个起作用。
题目不难理解,这儿不分析了。
说了这些递归,其实它和函数的调用没有大的区别,主要就是一个终止条件要选好.递归函数很多时候都能用循环来处理.
main()
{
intn=20,array[20];
inti;
for(i=0;i〈N;I++)
{
if(i<2)array[i]=1;
elsearray[i]=array[i—1]+array[i—2];
}
printf(%d\n,array[19]);
getch();
}
上面的程序就是实现一模一样的功能的.但是它有一个缺陷,就是n的值不是通过键盘输入来得到。
如果想通过键盘来得到n,可以这样:
main()
{
intn,i;
ints1=1,s2=1,temp
scanf(%d,&n);
for(i=3;i<=n;i++)
{
temp=s2;
s2+=s1;
s1=temp;
}
printf(%d\n,s2);
getch();
}
(最高)()[]-〉。
自左向右
!
~++—-+—*&sizeof自右向左
*/%自左向右
+-自左向右
<〈〉〉自左向右
<<=〉〉=自左向右
==!
=自左向右
&自左向右
^自左向右
|自左向右
&&自左向右
||自左向右
?
:
自右向左
=+=-=*=/=%=&=^=|=<〈=〉>=自右向左
(最低),自左向右
一个表达式的返回值都可以用来判断真假,除非没有任何返回值的void型和返回无法判断真假的结构。
当表达式的值不等于0时,它就是“真”,否则就是假。
一样个表达式可以包含其他表达式和运算符,并且基于整个表达式的运算结果可以得到一个真/假的条件值.因此,当一个表达式在程序中被用于检验其真/假的值时,就称为一个条件.
一、if语句
if(表达式)语句1;
如果表达式的值为非0,则执行语句1,否则跳过语句继续执行下面的语句.
如果语句1有多于一条语句要执行时,必须使用{和}把这些语句包括在其中,此时条件语句形式为:
if(表达式)
{
语句体1;
}
例如:
if(x>=0)y=x;
if(a||b&&c)
{
z=a+b;
c+=z;
}
二、if-—else语句
除了可以指定在条件为真时执行某些语句外,还可以在条件为假时执行另外一段代码。
在C语句中利用else语句来达到这个目的。
if(表达式)语句1;
else语句2;
同样,当语句1或语句2是多于一个语句时,需要用{}把语句括起来。
例如:
if(x〉=0)y=x;
elsey=-x;
三、if--elseif-—else结构.
if(表达式1)
语句1;
elseif(表达式2)
语句2;
elseif(表达式3)
语句3;
.
.
。
else
语句n;
这种结构是从上到下逐个对条件进行判断,一旦发现条件满点足就执行与它有关的语句,并跳过其它剩余阶梯;若没有一个条件满足,则执行最后一个else语句n。
最后这个else常起着缺省条件的作用。
同样,如果每一个条件中有多于一条语句要执行时,必须使用{和}把这些语句包括在其中。
条件语句可以嵌套,这种情况经常碰到,但条件嵌套语句容易出错,其原因主要是不知道哪个if对应哪个else.
例如:
if(x>20||x〈-10)
if(y〈=100&&y〉x)
printf(Good);
else
printf(Bad);
对于上述情况,TurboC2。
0规定:
else语句与最近的一个if语句匹配,上例中的else与if(y〈=100&&y〉x)相匹配。
为了使else与if(x>20||x<-10)相匹配,必须用花括号。
如下所示:
if(x>20||x〈—10)
{
if(y<=100&&y〉x)
printf(Good);
}
else
printf(Bad);
下面举几个例子:
1.输入一个数,如果大于0,输出plus;如果是负数,输出negative;如果正好是0,则输出zero。
main()
{
floatnum;
scanf(%f,&f);
if(num>0)
printf(plus\n);
elseif(num<0)
printf(negative\n);
else
printf(zero\n);
}
先定义两个变量,然后输入一个数,然后判断这个数的范围,输出对应的字符串。
2.输入一个数x,输出y.其中y是x的绝对值。
main()
{
floatx,y;
scanf(%f,&x);
if(x〉=0)y=x;
elsey=-x;
printf(%f\n,y);
}
程序比较简单,这儿就不分析了。
其实TruboC2。
0把一些常用的功能都写好了,我们只需要使用就可。
例如求绝对值的功能在C的库里面就有。
看下面的:
#includemath.h
main()
{
floatx,y;
scanf(%f,&x);
y=fabs(x);/*求x的绝对值,然后赋值给y*/
printf(%f\n,y);
}
这个程序和上面的程序完成的功能是一模一样的,都是求绝对值。
可以看出,用下面这个方法比上面就要好一些。
由于fabs()是一个函数,系统自带的,所以在使用它的时候,我们必须把它所在的库文件math.h包含都程序中,即程序最前面一行。
类似的还有求开方sqrt(),求指数幂exp()等等,这些与数学方面有关的函数都在math.h里面。
具体哪些有哪些没有,在什么库里面,可以查看一些手册.
3.输入x,输出y,x和y满足关系:
x〈—5y=x;
—5〈=x<1y=2*x+5;
1<=x〈4y=x+6;
x>=4y=3*x-2;
程序如下:
main()
{
floatx,y;
scanf(%f,&x);
if(x<—5)
y=x;
elseif(—5〈=x&&x〈1)
y=2*x+5;
elseif(1<=x&&x<4)
y=x+6;
else
y=3*x-2;
printf(%f\n,y);
}
这里要说明两点:
(1)。
-5〈=x&&x<1不能写成-5<=x〈1;1<=x&&x〈4也不能写成1<=x<4;在C语言中,不能认识连续不等式。
(2).y=2*x+5不能写成y=2x+5;y=3*x—2也不能写成y=3x—2;这与我们平时所写的方法不一样。
4.输入三个数x,y,z,然后按从大到小输出。
main()
{
floatx,y,z;
scanf(%f%f%f,&x,&y,&z);
if(x>=y&&x〉=z)
{
printf(%f\t,x);
if(y〉=z)printf(%f\t%f\n,y,z);
elseprintf(%f\t%f\n,z,y);
}
elseif(y>=x&&y〉=z)
{
printf(%f\t,y);
if(x〉=z)printf(%f\t%f\n,x,z);
elsep