C语言基础——分支与循环结构(二)

2023-03-30 00:00:00 语句 执行 条件 循环 循环体
序文
欢迎阅读  霖海岛LHaisland  原创的C语言合集的第七篇文章,本文字数为4555字,全文阅读需要约15分钟。由于笔者能力有限,如有疏漏或错误的地方,希望读者朋友们不吝斧正,谢谢大家。
上篇文章地址:C语言基础——分支与循环结构(一)
本文开始我们介绍第二章——分支与循环结构中的循环结构

在前文中,我们介绍了C语言的分支(选择)结构,这里我们开始对循环结构进行详细介绍。

循环结构:
循环结构是指在程序中需要反复执行某个功能而设置的一种程序结构。它由循环体中的条件,判断继续执行某个功能还是退出循环。根据判断条件,循环结构又可细分为以下两种形式:先判断后执行的循环结构和先执行后判断的循环结构。
C语言中提供了三大循环结构,分别为while语句、do...while语句和for语句
循环三要素:循环变量的初值、循环变量的判断、循环变量的更新
循环结构的特点是:(重点)
  • 当条件成立的时候,执行循环体的代码,当条件不成立的时候,跳出循环,执行循环结构后面的代码。
  • 特别要注意在循环体内应包含趋于结束的语句(即循环变量的更新),否则就可能成了一个死循环,这是初学者的一个常见错误。
  • 给定的条件称为"循环条件",反复执行的程序段称为"循环体"。

循环结构while(当型循环)

语法:
while(循环控制条件){   循环体(中的语句);   使循环趋于结束的语句;   ....}

构成循环的条件:

  • 循环控制条件:循环退出的主要依据;来控制循环何时退出。

  • 循环体:循环过程中重复执行的代码块。

  • 使循环趋于结束的语句:例如递增、递减、真、假等使循环条件为假的依据,使得循环结束。

示例:输出0-9十个数字。

#include <stdio.h>int main(){  int i = ;  while (i < 10)      //循环控制条件  {    printf("%d\n", i);  //循环体    i++;          //使得循环趋于结束的语句  }  return ;}

while循环流程:

首先判定循环控制条件是否为真,如果为假则直接跳过循环。
如果循环控制条件为真,则执行一次循环体,再次判断循环控制条件是否为真,为真继续执行循环体,如果为假则跳出循环。
这里需要注意一件事,和之前我们所说的一样,任何数值都有真假性,while(1)为真,则一直循环,也是简单的死循环。死循环一般在操作系统级别的应用程序会较多使用,日常开发中很少用。

while语句中的break和continue

先来介绍一下break:

#include <stdio.h>int main(){  int i = ;  while (i < 10)  {    if (i == 5)      break;    printf("%d ", i);    i++;  }  return ;}
可以看到,对比之前打印0-9十个数字,这一次打印到4就停了下来。
简单解释一下:i=0,满足判断条件,进入循环,不满足i==5,没有进入if判断,然后对i进行了打印,然后i++(自增),再次循环,直到i++为5再次进入循环时,满足了if的i==5,进行了跳转语句break。
break在while循环中的作用:

在while循环中遇到break,则终止当前while循环。当出现循环嵌套时,break只能终止当前所在的while循环。

示例:

#include <stdio.h>int main(){  while (1)//死循环  {    printf("这是个死循环\n");
while (1)//死循环 嵌套 死循环 { break;//终止第二个死循环 printf("这是第二个死循环");//因为遇到break则终止当前循环 所以这一条不会打印出来。 }
} return ;}

所以刚刚break终止了本次循环,没有执行break下的printf,所以没有打印5,循环到此结束。
再来介绍一下continue:
#include <stdio.h>int main(){  int i = ;  while (i < 10)  {    if (i == 5)      continue;    printf("%d ", i);    i = i++;  }  return ;}

有些读者朋友看到这里觉得奇了怪了,这怎么和break一样呢?

别急,我们再来一段儿代码:

#include <stdio.h>int main(){    int i = ;    while (i < 10)    {        i = i++;        if (i == 5)            continue;        printf("%d ", i);    }    return ;}

这里我们对比上个代码,只是把i++挪到了if之前,效果却截然不同。

到这里有些读者朋友可能已经猜到continue的用法了,有些读者朋友可能还不确定。

这里我先摆出结论

continue在while循环中的作用是:

终止本轮次循环,也就是continue后边的代码不会运行,跟break相比,continue不是跳出循环,而是跳转到while语句的判断条件部分,进行下一次循环的入口判断。

这里笔者来解释的简单一些,不知道观察细致的读者朋友有没有发现,正常代码运行结束后是这样的。

上图是刚刚break的截图,
而我们continue的截图是这样的(如下图)。

读者朋友们可能发现不同点了:

这句话不见了。

说明代码还没有终止运行,换句话说,进入了死循环。

为什么进入了死循环呢?

因为当i++操作结束之后,i==5时,满足了if的判断条件,开始实现跳转语句continue,我们刚刚说过continue的作用:

终止本轮次循环,也就是continue后边的代码不会运行,跟break相比,continue不是跳出循环,而是跳转到while语句的判断条件部分,进行下一次循环的入口判断。

所以i等于5又一次重新进入循环,又满足if的判断条件,又一次执行continue,因为没有执行到i++,在这里陷入了死循环。

而另一段代码将i++挪到了if之前:


当i++令i等于5时,满足if判断条件,执行continue跳转语句,跳到while的判断入口(i<10)满足,则再一次进入循环,循环开始则对i进行自增,这样i等于6,避免了死循环。
再次总结一下while中break语句和continue语句的作用:
break在while循环中遇到break,则终止当前while循环。当出现循环嵌套时,break只能终止当前所在的while循环。

continue:终止本轮次循环,也就是continue后边的代码不会运行,跟break相比,continue不是跳出循环,而是跳转到while语句的判断条件部分,进行下一次循环的入口判断。

循环结构for(当型循环)
语法:
for(表达式1;表达式2;表达式3){    循环语句;}
表达式1为初始化表达式,用于初始循环变量。
表达式2为条件表达式部分,用于判断循环何时终止。
表达式3为循环后的调整部分,用于循环条件的调整。
for循环流程图:
示例:打印0-9十个数字:
#include <stdio.h>int main(){    int i = ;    for (i = ; i < 10; i++)        printf("%d ", i);    return ;}

简单解释:初始化i=0,满足i<10的判断条件,也就是流程图中的yes,进行次循环,进入循环体内执行语句,执行完成后继续执行表达式3,也就是i++,这时i=1,仍然满足判断条件,重复循环,直至i++令i=10,不满足循环条件,跳出循环。

for循环注意事项:

基本上与while一致,for(;;)是简单的死循环。

我们来对比一下for循环与while循环:

int i = ;
//实现相同的功能,使用whilei = 1;//初始化部分while (i <= 10)//判断部分{ printf("hehe\n"); i = i + 1;//调整部分}
//实现相同的功能,使用forfor (i = 1; i <= 10; i++){ printf("hehe\n");}
可以直观地看到:
在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中与方便。
所以,for循环的风格更胜一筹;for循环使用的频率也高。
while能做的for都能做, 所以企业开发中能用for就用for, 因为for更为灵活
而且对比while来说for更节约内存空间。

for语句中的break和continue

我们发现在for循环中也可以出现break和continue,他们的意义和在while循环中是一样的。
break在for语句中用法与while完全一致,用来跳出本层循环。
的一点小区别在于for中的continue,对于while来说为了避免死循环,我们将i++挪到了if之前。
在for循环中我们使用continue,在i==5时continue后面的代码不进行作用(printf("%d ",i); 不执行),但是for循环中的i++还是会执行.
示例:


回到这张流程图,即使使用continue,会跳过continue以下的未被执行语句,但不会跳过表达式3,也就是不会跳过调整部分

for语句的循环控制变量

建议:

1. 不可在 for 循环体内修改循环变量,防止 for 循环失去控制。

2. 建议 for 语句的循环控制变量的取值采用“前闭后开区间”写法。

int i = ;//前闭后开的写法for(i=; i<10; i++){}
//两边都是闭区间for(i=; i<=9; i++){}

for循环的省略

种:三条语句都省略,相当于for(;;)<==>while(1)


#include <stdio.h>int main(){  for (;;)//三个表达式全部省略 死循环  {    printf("坏习惯\n");  }  return ;}

第二种:判断条件语句省略(可以在循环体中对 i 进行条件判断)
#include <stdio.h>int main(){  for (int i =  ; ; i++)  {    printf("坏习惯\n");  }  return ;}

第三种:初始化语句省略(如果已赋初始值,for中的初始化语句就可省略)

#include <stdio.h>int main(){  int i = ;  for (; ;i++)  {    if (i == 3)      break;    printf("坏习惯\n");  }  return ;}

第四种:控制语句省略(可在循环体中解决,不解决仍然为死循环,i恒为初值)
#include <stdio.h>int main(){  for (int i =  ; i < 5 ; )  {    printf("坏习惯\n");  }  return ;}

循环结构do...while(直到型循环)(不经常使用)

语法:
do {    循环体中的语句;    使得循环趋于结束的语句;    ....} while (循环控制条件)
do-while循环执行流程:
  • 首先不管while中的条件是否成立, 都会执行一次"循环体"
  • 执行完一次循环体,接着再次判断while中的条件是否为真, 为真继续执行循环体,为假跳出循环。
  • 重复以上操作, 直到"循环控制条件"为假为止。

示例:直到型循环:


#include <stdio.h>int main(){  int i = 10;  do  {    printf("%d\n", i);  } while (i < 10);  return ;}

示例:打印0-9十个数字:

#include <stdio.h>int main(){  int i = ;  do  {    printf("%d\n", i);    i++;  } while (i < 10);  return ;}
应用场景:口令校验
示例:
#include<stdio.h>int main(){    int num = ;    do     {        printf("请输入密码\n");        scanf("%d", &num);    } while (200124 != num);    printf("登陆成功\n");}
while和do...while应用场景:
  • 绝大多数情况下while和do...while可以互换, 所以能用while就用while。
  • 无论如何都需要先执行一次循环体的情况, 才使用do...while。
  • do...while曾一度提议废除,但是它在输入性检查方面有优点。

goto语句
C语言中提供了可以滥用goto语句和标记跳转的标号
从理论上goto语句是没有必要的,实践中没有goto语句也可以很容易地写出代码。 goto会破坏结构化程序设计流程,它将使程序层次不清,且不易读,所以慎用。
但是某些场合下goto语句还是用得着的,常见的用法就是终止程序在某些深度嵌套的结构的处理过程。

例如:一次跳出两层或多层循环。

多层循环这种情况使用break是达不到的。

语法:
goto 语句标号;goto label;//示例  //可以理解为跳转到labellabel://也就是跳转到这里 开始执行label:后的代码段
示例:goto语言适合的场景:
#include<stdio.h>int main(){    for (;;)    {        for (;;)        {            for (;;)            {                for (;;)                    goto label;            }        }    }label:    printf("跳出\n");    return ;}


循环的嵌套:

在一个循环体语句中又包含另一个循环语句,称为循环嵌套。内嵌的循环中还可以嵌套循环,这就是多层循环。

循环嵌套需要注意的事项:

在多重循环中,如果有可能,应当将长的循环放在内层,短的循环放在外层,以减少 CPU 跨切循环层的次数
关于自增和自减
简单地说:

++i 和 i++ 在单独使用时,都表示i=i+1

--i 和 i-- 在单独使用时,都表示i=i-1


a=++i就相当于i=i+1 , a=i; 先运算再赋值

a=i++就相当于a=i , i=i+1; 先赋值再运算 

同理

a=--i就相当于i=i-1 , a=i; 先运算再赋值

a=i--就相当于a=i , i=i-1; 先赋值再运算 

对于自增和自减还有一点需要强调的是:只有“变量”才能进行自增和自减。

对于常量并没有这种写法,常量是不能自增和自减的。

至此我们已经了解分支与循环结构大致内容
由于篇幅有限,下一次内容我们将分享分支与循环结构的练习题目
如果您在阅读中发现内容错误或者有好的想法以及建议,欢迎在公众号内给我们留言,我将不胜感激!
感谢您能够阅读到这里,我们下次再会!
编辑:  霖海岛LHaisland
审核:           农场主假说
图文来源:  霖海岛LHaisland

相关文章