C语言:循环语句

本文详细介绍了C语言中的三种循环语句——while、do-while和for,包括它们的语法结构、执行流程以及在不同情况下的应用。此外,还讨论了如何通过break、continue和goto语句来控制循环的退出和流程。文章强调了C99与C89在for循环声明中的差异,并给出了示例代码以帮助理解。
摘要由CSDN通过智能技术生成

C语言提供了重复执行某行代码的语句

分为三种

while、do、for三种语句

一、while语句

    while(/*逻辑表达式*/)//控制语句
    {
        //循环体;
    }

 while是最简单的循环,分为两个部分控制语句循环体

控制语句由while关键字和圆括号里的逻辑表达式共同组成

当程序执行到while语句时

会先判断while(/*逻辑表达式*/)中的表达式的结果

此时

1.表达式结果为1

执行一次循环体内容

如果循环体中的内容正常结束

则从重新从while(/*逻辑表达式*/)开始执行

2.表达式结果为0

不执行循环体内容,直接结束while语句

注意:

循环体不是非加{}不可

加{}执行整个{} 作用域中的内容

如果不加则只执行第一个;换行前的内容

二、do语句(do while语句)

    do
    {
        //循环体
    }
    while (/*逻辑表达式*/) ;//控制语句

do语句其实也是while循环语句,必须依赖while语句,我们知道while语句是先判断逻辑表达式根据判断结果判断是否执行循环体,如果while语句的控制语句未通过,循环体是一次也不会执行的。

但是do while语句就不一样了,程序第一次执行到do while时,直接先执行一次do中的循环体

我们可以用流程图来理解一下两种循环的区别

三、for语句

for语句的格式如下(C99)

for(声明或者表达式1;表达式2;表达式3)循环体 

为了理解for循环可以使用这个等价while循环

表达式1;

while(表达式2)

{

       {循环体}

       {表达式3;}

分析后可以了解for循环的作用

表达式1:初始化语句,一般用于初始化自增变量

表达式2:判断表达式,用于限制显示条件

表达式3:变化表达式,用于满足表达式2的动态变化

并有以下结论

for循环的执行顺序如等价中的while的顺序是相同的,也就是说,表达式1和表达式2必定被执行,表达式3不一定能执行到,但表达式1只会执行一次

for语句中的省略表达式

看了for等价while之后,可以发现,除了表达式2,剩下的表达式1、表达式3都可以省略掉

最精简可以精简到

    for(;1 ;)
    {
        printf("嗨害嗨!\n");
    }

这样相当于下方的while死循环

    while(1)
    {
        printf("嗨害嗨!\n");
    }

显然这个还不如直接是使用while循环看的清晰

for循环常用方法是可以较为方便的控制循环次数

    for(int i = 0 ;i < 5 ;i++)
    {
        printf("1111\n");
    }

这样代表循环从0开始循环,当i达到 5时直接结束循环

C89和C99的for循环是有区别的

我在这一部分上面写的for语句都是C的写法,C89和C99的for语句的区别在下面 

 首先C89的表达式1中不可存在声明语句,如果写了,编译会报错

C89错误写法(但C99中可以这样写)

    for(int i = 0 ;i < 5 ;i++)//此处会报错
    {
        printf("1111\n");
    }

C89正确写法(但C99中可以这样写)

int i;

    for(i = 0 ;i < 5 ;i++)//此处会报错
    {
        printf("1111\n");
    }

显然C99的for语句的语法更人性化一点 

C89不能兼容C99特有的写法,C99则可以使用两种写法,这就引申出了另一个问题:

上面两个引用框的i值作用域不一样

上面的i作用域只在for循环内,下面的i在最外侧作用域

 for(int i = 0 ;i < 5 ;i++)
{
    printf("1111\n");
}
printf("i = %d \n",i);//这样写直接报错 i会显示没有定义

 同样会引申出另一个问题

int i = 5; 

for(int i = 0 ;i < 5 ;i++)
{
    printf("1111\n");
}

//这么写是合法的,看似int i被定义了两次 但是表达式1的作用域比上面的作用域小,也就是说进入表达式后i的值只从0开始

进阶一些的理解就是

int i = 5;

{

        int i = 0;

        while(i<5)

        {

                //循环体

                i++;

        } 

}

逗号运算符在for循环中的作用

首先回顾一下“,”运算符的作用

一般作用:在多个一般表达式之间进行分割,为多个同种变量的声明省略类型,如下

int i = 0,j = 10 ;

可以连续定义两个int型变量但只需写一个int,并且可以继续追加

 我们利用,运算符做些什么呢?比如使用同时遍历两个条件的时候,我们可以使用,号追加条件

for(int i = 0,j = 10 ;i < 5 , j >6 ;i++,j--)
{
    printf("i == %d , j = %d \n",i,j);
}

输出为

i == 0 , j = 10

i == 1 , j = 9

i == 2 , j = 8

i == 3 , j = 7

 注意!!!!:这个判断表达式这个,号把两个显示条件连接起来时有点类似于&&的作用,当然最好是直接用&&更清晰一些

所有的的表达式都可以自由发挥,放飞自我的去写,即使简单如for语句也是可以玩出花儿的

四、结束循环的方式

退出循环除了等到控制表达式为false还有主动跳出循环的几种方式

1)break:

跳出当前循环或控制

如,现在军队里现在有20吨粮食,每天吃掉4吨,当前粮食能否坚持到6天时间,如果不行,能坚持几天?

分析问题粮食吃完了,在计算没有意义,以i为天 j为粮食数

    for(int i = 0,j = 20;i < 6;++i,j-=4)
    {
        printf("day i = %d  ,food j =  %d \n",i,j);
        if(0 >= j)
            break;
    }

输出

day i = 0 ,food j = 20

day i = 1 ,food j = 16

day i = 2 ,food j = 12

day i = 3 ,food j = 8

day i = 4 ,food j = 4

day i = 5 ,food j = 0

计算得出 第五天结束 粮食就吃完了 根本坚持不了6天

注意:只能跳出一层嵌套 也就是说,出现多层循环嵌套时,如果在内层循环跳出,只能跳出当前循环,外层循环仍然继续

2)continue:

结束当前循环体,注意,结束循环体和结束循环的区别,循环体是循环语句中被循环的部分

循环是整个循环,区别是什么呢?

    int a = 0;
    while(a < 10)
    {
        if(0 == (a%2))
            continue;
        printf("while = %d \n",a);
        a ++;
    }

    for(int i = 0;i < 10;++i)
    {
        if(0 == (i%2))
            continue;
        printf("for = %d \n",i);
    }

上方有两个循环 同样是打印10以内的奇数

while循环的变量自增我们写在循环体内,我们没有经过自增就重新进入判断语句上,这样就会导致出现死循环,导致程序阻塞或者崩溃

而for循环的自增是紧随循环体之后的,也就是说,即使循环体被continue中断,紧接着还是会正常自增的,因为这个自增一定会触发控制语句的false条件,所以单独运行下方for循环时不会崩溃

如果有傲娇的小伙伴表示自己就是想用while循环呢

使用以下代码

    int a = 0;
    while(++a < 10)
    {
        if(0 == (a%2))
            continue;
        printf("while = %d \n",a);
//        a ++;
    }

既然while循环循环体会被中断,那干脆在控制表达式中自增算了(注意:必须为前缀自增),当然,你不怕被师傅打爆头的情况下(狗头),但是,强烈不建议如此实现,与其如此,不如不使用continue 如下

    int a = 0;
    while(a < 10)
    {
        if(1 == (a%2))
        {
            printf("while = %d \n",a);
        }
        ++a;
    }

看到此是不是又觉得continue 作用不大?也并非如此,无论是哪种跳出,都是期待我们减少后续无用代码的运算,以提高程序的运行效率,减少无意义的计算,上面写的这种代码量很少,实际开发中又很多需要在循环中提前中断的地方

3)goto:(不建议使用)

语法

标签名:

goto 标签名;

 执行语句时,我们可以向任意标签跳转

    int a = 0;
n1:
    printf("ahahahah xian !!!\n");
    while(a < 10)
    {
        if(1 == (a%2))
        {
            printf("while = %d \n",a);
            ++a;
            goto n1;
        }
        printf("++while = %d \n",a);
        ++a;
    }

输出

ahahahah xian !!!

++while = 0

while = 1

ahahahah xian !!!

++while = 2

while = 3

ahahahah xian !!!

++while = 4

while = 5

ahahahah xian !!!

++while = 6

while = 7

ahahahah xian !!!

++while = 8

while = 9

ahahahah xian !!!

ahahahah !!!

我们甚至可以跳转到int a定义之前来把循环变为死循环(变态脸) 

这也是goto语句容易出问题的原因之一,很多变态的错误在等待我们踩坑(玩笑)

主要是不建议使用

因为break、continue、return本身就是受限制的goto,正常开发这些就已经能解决所有问题了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值