循环结构梳理


前言

循环结构是C语言中极为重要的一部分,今天小萌新打算来给大家梳理一下三种循环结构。不足之处,欢迎大家在评论区补充。

一、for循环

标准版for循环

标准型:
for(表达式1;表达式2;表达式3)
{表达式4;
表达式5;
表达式6;

}
其中,大括号内的内容可以是一条语句,也可以是由分号隔开的多条语句。如果只有一条语句,大括号可以省略。
运行顺序:
先执行表达式1(初始化语句),再判断表达式2,如果成立,执行{}内的语句,之后再执行表达式3(修正语句),如果不成立,循环结束。(如下图)

Created with Raphaël 2.3.0 开始 表达式1 表达式2是否成立? 表达式4,5,6... 表达式3(修正) 结束 yes no

比如,我们现在有一个数组{1,2,3,4,5},我们希望依次输出它的五个元素。(由于循环体内只有一个表达式,故省略了大括号)

int a[5]={1,2,3,4,5};
int i;
for(i=0;i<5;i++)
	printf("%d ",a[i]);

输出如下:
输出结果
也可以写成:

int a[5]={1,2,3,4,5};
for(int i=0;i<5;i++)
	printf("%d ",a[i]);

C99标准允许程序员在for的小括号内定义变量,该变量只在for循环里有效,在循环结束时失效。

int a[5]={1,2,3,4,5};
int i=3;//这个i在整个main函数里有效
printf("i的值是%d\n",i);
for(int i=0;i<5;i++)//这个i只在for循环里面生效
	printf("a[%d]=%d\n",i,a[i]);
printf("i的值是%d",i);

运行结果
如果采用的是C90,编译器会报错:

[Error] ‘for’ loop initial declarations are only allowed in C99 or C11 mode

省略版for循环

对于for循环而言,
没有任何一个表达式是必须的。
但是,没有一个分号是可以省略的!

对于刚刚的例子,我们可以省略表达式1,写成:

int a[5]={1,2,3,4,5};
int i=0;
for(;i<5;i++)
		printf("%d ",a[i]);
	

也可以省略表达式2,写成:

int a[5]={1,2,3,4,5};
int i;
for(i=0;;i++)
	if(i<5)//if语句虽然占了四行,但是一个if...else...算一个语句,故此处不需要大括号
		printf("%d ",a[i]);
	else
		break;//break函数,指跳出该循环

也可以省略表达式3,写成:

int a[5]={1,2,3,4,5};
int i;
for(i=0;i<5;){//循环体内有两个语句,必须要大括号!
	printf("%d ",a[i]);
	i++;
}

或者:

int a[5]={1,2,3,4,5};
int i;
for(i=0;i<5;)
	printf("%d ",a[i++]);

表达式4也同样可以省略,比如我们希望找出比n小的完全平方数中最大的那个:(暂且让我们令n=99)

int n=99;
	int i;
	for(i=0;i*i<n;i++);//请不要省略这个分号!
	printf("%d",(i-1)*(i-1));

为什么输出i-1的平方而不是i的平方?
因为当i=9时,i的平方小于n,(表达式2成立)循环会再次进行,但循环体内没有任何语句,故直接执行表达式3,使i自增,此时i=10,表达式2不再成立,循环退出。循环结束时i=10,i的平方大于n。

二、while循环

标准版while循环

标准型:
while(表达式1){
表达式2;

}
运行顺序:先判断表达式1是否成立,如果不成立,结束循环;如果成立,执行大括号里的内容,然后再次判断表达式1。同样的,如果大括号里只有一条语句,大括号可以省略。

Created with Raphaël 2.3.0 开始 表达式1是否成立? 表达式2... 结束 yes no

再用刚刚的例子,我们希望依次输出数组{1,2,3,4,5} 的五个元素。那么可以写成:


int a[5]={1,2,3,4,5};
int i=0;
while(i<5)//只有一个语句,大括号省略
	printf("%d ",a[i++]);

不难发现:
for(表达式1;表达式2;表达式3){表达式4}

等价于:
表达式1;while(表达式2){表达式4;表达式3}

和for循环一样,while循环也可以省略其中任何一个表达式。
但在此之前,先介绍一下break语句和continue语句:

break语句

break指立刻跳出该循环,例子:

int a[5]={1,2,3,4,5};
int b[5]={1,2,2,4,5};
int i;
for(i=0;i<5;i++)
	if(a[i]!=b[i])
		break;
if(i==5) printf("a与b相同\n");
else printf("a与b不相同\n");

如果系统执行到break语句(即if判断成立)会立刻结束for循环,开始执行第八行语句,而不会进行i++运算。因此我们可以通过判断for循环结束时 i 的值来判断是否有中途break。(需要注意的是不能写成for(int i=0;…),不然for循环退出之后,变量 i 将不复存在,无法判断。)
注意:break只能跳出一个for循环,或者跳出一个while循环,如果有双层的for循环嵌套,是不能用一个break完全跳出的。只能用goto语句,或者别的方式实现。

continue语句

continue指立刻结束当前循环,开始下一个循环,例子:

int a[5]={1,2,3,4,5};
int b[5]={1,2,2,4,5};
int i;
for(i=0;i<5;i++){
	if(a[i]!=b[i])
		continue; 
	printf("a[%d]与b[%d]相等\n",i,i);
}

运行结果:在这里插入图片描述
当 i =2时,if判断成立,执行continue语句,跳过后面的print语句,直接执行i++语句,然后开始下一个循环;

但是,不可以写成:

int a[5]={1,2,3,4,5};
int b[5]={1,2,2,4,5};
int i;
while(i<5){
	if(a[i]!=b[i])
		continue; 
	printf("a[%d]与b[%d]相等\n",i,i);
	i++;
}

点击运行,系统死机:
在这里插入图片描述
这是因为当 i =2时,执行了continue,由于此处的while循环里没有修正语句,会直接开始下一个循环( i 依然等于2)。故系统会在 i 始终等于2的情况下无限循环。

省略版while循环

对于我们刚刚的例子,
可以省略表达式1,写成:

int a[5]={1,2,3,4,5};
int b[5]={1,2,2,4,5};
int i;
while(1){
	if(a[i]==b[i])
	printf("a[%d]与b[%d]相等\n",i,i);
	i++;
	if(i>=5) break;
}

表达式1即使省略,也要写一个“1”在小括号里。由于while会先判断小括号里表达式是否成立,再选择是否执行接下来大括号里的内容。而判断表达式是否成立,指的是计算它的值,非0为真,0为假。比如当a的值为5时,表达式a== 5的值为1(真),表达式a==1的值为0(假)。

而表达式“ 1 ”的值显然为1,因此这个式子必然为真。while会不断执行大括号里的内容,为了防止出现死循环,我们需要用break函数,goto函数或者return来跳出循环。

对于省略表达式2的情况,在这里介绍一种特殊用法:

while((c=getchar())='\n');

最后的分号表示该while循环的循环体内没有任何东西,当系统执行到这一行时,会首先getchar一个字符,赋值给c,然后与换行符判断,如果结果为真(即获得的字符不是换行符),那么就执行循环(实际上什么也不做)然后再次获取一个字符,赋值,判断,,,
借此可以删除所有之前输入的字符(即清空缓冲区),以便于后面的输入。例子:

int a;
printf("请输入a的值:\n"); 
scanf("%d",&a);
char c;
while((c=getchar())!='\n');
char b;
printf("请输入b的值:\n");
scanf("%c",&b);
printf("a=%d,b=%c",a,b);

运行结果:
在这里插入图片描述
但如果去掉4,5两行语句:

int a;
printf("请输入a的值:\n"); 
scanf("%d",&a);
//char c;
//while((c=getchar())!='\n');
char b;
printf("请输入b的值:\n");
scanf("%c",&b);
printf("a=%d,b=%c",a,b);

运行结果:
在这里插入图片描述
此时b为换行符。这是因为再输入213后键人了一个换行符(\n),这个换行符没有被前一个scanf语句拿走,留在了缓冲区。后一个scanf取走了这个换行符,赋值给了b。

goto语句

另外还有一个语句,像break与continue一样,能够帮助我们跳出循环,即goto语句,例子:

int a[5]={1,2,3,4,5};
int i=0;
	while(1){
		printf("%d",a[i++]);
		if(i==5) goto end;
	}
	end:
	printf("\n输出完毕\n");

当i=5时,第五行的判断成立,执行goto语句,程序立刻跳至语句标号end处(即第七行)从而做到了退出while循环。
当然,goto也可以往前跳,即语句标号在goto之前,但是,goto不可以跳到其它函数内,即如果goto语句在main函数里,语句标号也必须在main函数里。并且紧接着语句标号的语句不能定义变量。

三、do…while循环

do{
表达式1;
}
while(表达式2);

Created with Raphaël 2.3.0 开始 表达式1 表达式2是否成立? 结束 yes no

do…while循环与while循环类似,区别之处在于,无论表达式2是否成立,do…while都会先执行一次循环体。
比如我们想要求最大的n,使得数列An的前n项和小于sum。

int a[5]={1,2,3,4,5};
int sum=12;
int s=0;
int n=0;
do{//这个大括号是可以省略的
	s+=a[n++];
}while(s<sum);
printf("n最大是%d",n-1); 

输出:n最大是4

do…while循环与while循较为相似,但仍然需要注意的是,即使条件不成立,do…while循环也会执行一次循环体内的语句,而while则会直接跳过循环体。
比如:

int i=8;
while(i<7)
i++;
printf("i的值为%d",i);

输出:i的值为8

int i=8;
do
i++;
while(i<7);//不要漏掉这个分号!!!
printf("i的值为%d",i);

输出:i的值为9

结尾

这次小萌新主要为大家梳理了一下for,while,do…while三个循环。希望对大家能够有所帮助。如果有任何讲错的或者表述不当的地方,劳烦大家在评论区指出。每一条评论小萌新都会看呢。

//求一个点赞好不好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值