当前位置: 首页 > news >正文

分支和循环

        通常来说,C语言是结构化的程序设计语言,这里的结构包括顺序结构、选择结构、循环结构,C语言能够实现这三种结构,如果我们仔细分析,我们日常生活中所见的事情都可以拆分为这三种结构或者它们的组合。

        下面我会仔细讲解我们如何使用if、switch实现分支结构,使用for、while、do while实现循环结构。

# if语句

1 if

        if 语句的语法形式如下:
  if( 表达式 )
            语句;
        表达式成⽴(为真),则语句执⾏,表达式不成⽴(为假),则语句不执⾏。
        在C语⾔中,0为假,⾮0表⽰真,也就是表达式的结果如果是0,则语句不执⾏,表达式的结果如果不是0,则语句执⾏。
        例:输⼊⼀个整数,判断是否为奇数
#include <stdio.h>
int main()
{int num = 0;scanf("%d", &num);if(num % 2 == 1)printf("%d 是奇数\n", num);return 0;
}

        那么if语句流程是什么样的呢?

        下图即为if语句的执行流程图:

2 else 

        else是与if配合使用的,如果⼀个数不是奇数,那就是偶数了,如果任意⼀个整数,我们要清楚的判断是奇数还是偶数怎么表 ⽰呢?这⾥就需要 if...else... 语句了,语法形式如下:
if( 表达式 )
                语句1;
        else
                语句2;
例⼦:输⼊⼀个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印数偶数。
#include <stdio.h>
int main()
{int num = 0;scanf("%d", &num);if(num % 2 == 1)printf("%d 是奇数\n", num);elseprintf("%d 是偶数\n", num);return 0;
}
练习:输⼊⼀个年龄,>= 18岁就输出:成年,否则就输出:未成年
#include <stdio.h>
int main()
{int age = 0;scanf("%d", &age);if(age>=18)printf("成年\n");elseprintf("未成年\n");return 0;
}

 3 分⽀中包含多条语句

        在 if else 语句中,我们默认一个if / else语句都只控制⼀条语句,⽐如:
        对于当代学生来说非常重视的恋爱年龄问题
#include <stdio.h>
int main()
{int age = 0;scanf("%d", &age);if(age >= 18)printf("成年了\n");printf("可以谈恋爱了\n");return 0;
}
        如果你自己进行了上面代码的尝试,你会发现输⼊的值不管是>=18 还是⼩于18,"可以交⼥朋友了" 都会打印在屏幕上。
        原因是 if 语句只能控制⼀条语句,就是 距离这个if语句最近的下方的  printf(" 成年了 \n"); ,if语句为真,则打印成年了,if语句为假,则不打印,对于 printf(" 可以谈恋爱了 \n"); 是独⽴存在的,不管if语句的条件的真假,都会被执⾏。那如果我们要if语句同时控制2条语句,怎么办呢?那就要使⽤ {} 将代码括起来,else 后也可以跟上⼤括号。如下:
#include <stdio.h>
int main()
{int age = 0;scanf("%d", &age);if(age >= 18) //if 后使⽤{} 控制多条语句-这个块也叫:程序块,或者复合语句{printf("成年了\n");printf("可以交⼥朋友了\n");}return 0;
}

        这里复合语句已在之前的博客讲过了,如果还不跳了解,可以回去复习一下。

        上面的代码并不完整,我们进一步改写后,代码如下:

#include <stdio.h>
int main()
{int age = 0;scanf("%d", &age);if(age >= 18) //if 后使⽤{} 控制多条语句-这个块也叫:程序块,或者复合语句{printf("成年了\n");printf("可以交⼥朋友了\n");}else //else 后使⽤{}控制多条语句-这个块也叫:程序块,或者复合语句{printf("未成年\n");printf("不可以早恋哦\n");}return 0;
}

        了解之后,大家可以自己进行尝试编写。

4 if嵌套

        在上面的分支语句中,我们看到了双分支的情况,那么如果有多种分支的情况下,我们又该怎么解决呢?if else 语句中, else 可以与另⼀个 if 语句连⽤,构成多重判断。这样的连用方式,就成为if 嵌套。

        ⽐如:要求输⼊⼀个整数,判断输⼊的整数是0,还是正数或者负数。请看如下代码:

#include <stdio.h>
int main()
{int num = 0;scanf("%d", &num);if(num == 0)printf("输⼊的数字是0\n");else if(num > 0) //这⾥的if 相当于嵌套在els语句中,形成了嵌套结构printf("输⼊的数字是正数\n");elseprintf("输⼊的数字是负数\n");return 0;
}

        红圈中的部分就是嵌套在前⾯的 else ⼦句中的,构成了嵌套的if语句。

        再举个栗子:输⼊⼀个整数,如果是正数,再判断是奇数还是偶数,并输出;如果不是正数则输出:⾮正数。
#include <stdio.h>
int main()
{int num = 0;scanf("%d", &num);if(num>0){if(num%2 == 0)printf("偶数\n");elseprintf("奇数\n");}else{printf("⾮正数\n");}return 0;
}

        同上,上⾯红圈中的代码也是 if 嵌套语句,值得一提的是,两者的区别是前者嵌套在else 之后,后者则是嵌套在 if 之后。

        学会了嵌套if语句之后,我们就可以完成更多复杂逻辑的判断了。

练习:

输⼊⼀个⼈的年龄
如果年龄 < 18 岁,打印 " 少年 "
如果年龄在 18 岁⾄ 44 岁打印 " ⻘年 "
如果年龄在 45 岁⾄ 59 岁打印 " 中⽼年 "
如果年龄在 60 岁⾄ 89 岁打印 " ⽼年 "
如果 90 岁以上打印 "老寿星"
一般一道题会有许多种编写方式,下面我写了两种,共各位参考:
//⽅法1
#include <stdio.h>
int main()
{int age = 0;scanf("%d", &age);if(age<18)printf("少年\n");else if(age<=44)printf("⻘年\n");else if(age<=59)printf("中⽼年\n");else if(age<=90)printf("⽼年\n");elseprintf("⽼寿星\n");return 0;
}
//方法二
//带上⼤括号更容易看明⽩
#include <stdio.h>
int main()
{int age = 0;scanf("%d", &age);if(age<18){printf("少年\n");}else{if(age<=44){printf("⻘年\n");}else{if(age<=59){printf("中⽼年\n");}else{if(age<=90)printf("⽼年\n");elseprintf("⽼寿星\n");}}}return 0;
}

 5 悬空else问题

       在复杂的代码中, 多个 if else可能会把我们绕晕  ,我们可以记住这样⼀条规则, else 总是跟最接近的 if 匹配。
        我们⾸先从下⾯代码开始
#include <stdio.h>
int main()
{int a = 0;int b = 2;if(a == 1)if(b == 2)printf("hehe\n");elseprintf("haha\n");return 0;
}
        程序运⾏的结果是啥?很多初学者第一眼会判断 a 是 0,不等于 1 ,那就执⾏ else ⼦句,打印 haha,但是当你去运⾏代码,输出的结果是:啥都不输出。当然上面的代码中的else被我对齐了,如果你写的代码都被对其在同一行的话,这个代码就非常具有迷惑性了,同时这个问题也体现出了写代码的格式风格也是相当重要的,望各位注意!
        如果我们希望else确实和第⼀个if匹配,可以这样修改代码:
#include <stdio.h>
int main()
{int a = 0;int b = 2;if(a == 1){if(b == 2)printf("hehe\n");}else{printf("haha\n");}return 0;
}
        只要带上适当的⼤括号,代码的逻辑就会更加的清晰,所以⼤家以后在写代码的时候要注意括号的使⽤,让代码的可读性更⾼。

# 关系操作符 

       
        在C 语⾔⽤于⽐较的表达式,称为 “关系表达式”(relational expression),⾥⾯使⽤的运算符就称为“关系运算符”(relational operator),主要有下⾯6个。

 > ⼤于运算符

< ⼩于运算符

>= ⼤于等于运算符

<= ⼩于等于运算符

== 相等运算符

!= 不相等运算符

        关系表达式通常返回 0 1 ,表⽰真假。在C 语⾔中, 0 表⽰假,所有⾮零值表⽰真。⽐如, 20 > 12 返回 1 12 > 20 返回 0 。

        使用关系表达式最多的是if 或 while 语句,例如:

        if (x == 3 )
         {
        printf ( "x is 3.\n" );
          }
注意: 相等运算符 == 与赋值运算符 = 是两个不⼀样的运算符,不要混淆。有时候,可能会不⼩⼼写出下⾯的代码,写错的代码可以运⾏,但很容易出现意料之外的结果。
       
          if (x = 3 )
        上面if语句的 原意是 x == 3 ,但是不⼩⼼写成 x = 3 。这个式⼦表⽰对变量 x 赋值 3 ,它的返 回值为 3 ,所以 if 判断总是为真。为了防⽌出现这种错误,有的程序员喜欢将变量写在等号的右边,即  if ( 3 == x) ,这样写错的时候编译器会报错。
另⼀个需要避免的错误是:多个关系运算符不宜连⽤。如: i < j < k , 连续使⽤两个⼩于运算符。这是合法表达式,不会报错,但是通常达不到想要的结果,即不是保证变量 j 的值在 i 和 k 之间。因为关系运算符是从左到右计算,所以实际执⾏的是  (i < j) < k  。  i < j 返回 0 1 ,所以最终是 0 1 与变量 k 进⾏⽐较。如果想要判断变量 的值是否在 i k 之间,应该使⽤  i < j && j < k 这种写法。
         ⽐如:我们输⼊⼀个年龄,如果年龄在18岁~36岁之间,我们输出⻘年。如果我们按照上面的错误讲解写,代码展示为:
#include <stdio.h>
int main()
{int age = 0;scanf("%d", &age);if(18<=age<=36){printf("⻘年\n");}return 0;
}

        你会发现在运行时,无论你输入的是不是范围之内的数,都会打印青年。这是因为,我们先拿18和age中存放的10⽐较,表达式18<=10为假, 18<=age 的结果是0,再拿0和36⽐较,0<=36为真,所以打印了⻘年 ;如果你输入的大于18,表达式返回的为1,1<=36依旧成立。正确代码的演示:

#include <stdio.h>
int main()
{int age = 0;scanf("%d", &age);if(age>=18 && age<=36){printf("⻘年\n");}return 0;
}
        以上就是关于操作符中我们需要掌握的,剩下的只要按照字⾯意思理解使⽤即可。

# 条件操作符 

        条件操作符也叫三⽬操作符,需要接受三个操作数的,形式为: exp1 ? exp2 : exp3
        条件操作符的计算逻辑是:如果 exp1 为真, exp2 计算,计算的结果是整个表达式的结果;如果exp1 为假, exp3 计算,计算的结果是整个表达式的结果。
        练习1:使⽤条件操作符表⽰下⾯代码的逻辑
#include <stdio.h>
int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);if (a > 5)b = 3;elseb = -3;printf("%d\n", b);return 0;
}
//改造后
#include <stdio.h>
int main()
{int a = 0;int b = 0;scanf("%d", &a);b = a>5 ? 3:-3;printf("%d\n", b);return 0;
}
        练习2:使⽤条件表达式实现找两个数中较⼤值。
#include <stdio.h>
int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);int m = a>b ? a : b;printf("%d\n", m);return 0;
}

这里学会使用即可,作用与if语句等效。

# 逻辑操作符:&& , || , !  

    逻辑运算符提供逻辑判断功能,⽤于构建更复杂的表达式,主要有下⾯三个运算符。                   • ! :逻辑取反运算符(改变单个表达式的真假)。                                                                            • && :与运算符,就是并且的意思(两侧的表达式都为真,则为真,否则为假)。
 • || :或运算符,就是或者的意思(两侧⾄少有⼀个表达式为真,则为真,否则为假)。

1 逻辑取反运算符 !

   ⽐如,我们有⼀个变量叫 flag ,如果flag为假,要做⼀个什么事情,就可以这样写代码:
#include <stdio.h>
int main()
{int flag = 0;if(!flag){printf("do something\n");}return 0;
}
        如果 flag 为真, !flag 就是假,如果 flag 为假, !flag 就是真,所以上⾯的代码的意思就是 ! flag 为真,执⾏if语句中的代码。

2 与运算符 

        && 就是与运算符,也是并且的意思, && 是⼀个双⽬操作符,使⽤的⽅式是 a && b , && 两边的表达式都是真的时候,整个表达式才为真,只要有⼀个是假,则整个表达式为假。
        ⽐如:如果我们说⽉份是3⽉到5⽉是春天,那么代码就是:
#include<stdio.h>
int main()
{
int month = 0;
scanf("%d", &month);
if(month >= 3 && month <= 5)
{printf("春季\n");
}return 0;
}

3 或运算符  

        || 就是或运算符,也就是或者的意思, || 也是⼀个双⽬操作符,使⽤的⽅式是 a || b , || 两边的表达式只要有⼀个是真,整个表达式就是真,两边的表达式都为假的时候,才为假。⽐如:我们说⼀年中⽉份是12⽉或者1⽉或者2⽉是冬天,那么代码就是:
#include<stdio.h>
int main()
{int month = 0;scanf("%d", &month);if(month == 12 || month==1 || month == 2){printf("冬季\n");}return 0;
}

4 综合使用 

        练习:闰年的判断
闰年判断的规则为:
1. 能被4整除并且不能被100整除是闰年
2. 能被400整除是闰年
这里我也写了两种方法,供各位参考:
#include <stdio.h>
//代码1
int main()
{int year = 0;scanf("%d", &year);if(year%4==0 && year%100!=0)printf("是闰年\n");else if(year%400==0)printf("是闰年\n");return 0;
}//代码2
int main()
{int year = 0;scanf("%d", &year);if((year%4==0 && year%100!=0) || (year%400==0))printf("是闰年\n");return 0;
}

5 短路

        在C语⾔逻辑运算符的使用中,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。如果左边的表达式满⾜逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”。
        如前⾯的代码:  if (month >= 3 && month <= 5 )    表达式中&& 的左操作数是 month >= 3 ,右操作数是 month <= 5 ,当左操作数 month >= 3 结果是0的时候,即使不判断 month <= 5 ,整个表达式的结果也是0(不是春季)。所以,对于&&操作符来说,左边操作数的结果是0的时候,右边操作数就不再执⾏了。
        对于 || 操作符,我们结合前⾯的代码:
if (month == 12 || month== 1 || month == 2)   
如果month == 12,则不⽤再判断month是否等于1或者2,整个表达式的结果也是1(是冬季)。所以, || 操作符的左操作数的结果不为0时,就⽆需执⾏右操作数。
        这里为大家总结了口诀:&&全真才真,一假则假。
                                                ||   全家才假,一真则真。
        像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进⾏计算的运算称为短路求值。
        练习:阅读代码,计算代码输出的结果
#include <stdio.h>
int main()
{int i = 0,a=0,b=2,c =3,d=4;i = a++ && ++b && d++;//i = a++||++b||d++;printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);return 0;
}

        这道题可以帮助各位锻炼一下上面讲的知识点,在这里不再细讲,如果还有什么疑问的话,欢迎大家私信我。

#  switch 语句

        switch语句是除if语句之外的第二类分支结构语句。本质上讲,switch 语句是⼀种特殊形式的 if...else 结构,⽤于判断条件有多个结果的情况。它把多重的 else if 改成更易⽤、可读性更好的形式。形式为:

switch (expression) {
case value1: statement
case value2: statement
default : statement
}
        上⾯代码中,根据表达式 expression 不同的值,执⾏相应的 case 分⽀。如果找不到对应的值,就执⾏ default 分⽀。在这要注意:
switch 后的 expression 必须是整型表达式。
case 后的值,必须是整形常量表达式。

1 if语句和switch语句的对⽐

练习:输⼊任意⼀个整数值,计算除3之后的余数
        如果使⽤if语句完成,如下:
#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);if(n%3 == 0)printf("整除,余数为0\n");else if(n%3 == 1)printf("余数是1\n");elseprintf("余数是2\n");return 0;
}
        而如果使⽤switch语句改写,就可以是这样的:
#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);switch(n%3){case 0:printf("整除,余数为0\n"); break;case 1:printf("余数是1\n"); break;case 2:printf("余数是2\n"); break;}return 0;
}
        上述的代码中,我们要注意的点有:
1. case 和后边的数字之间必须有空格。
2. 每⼀个 case 语句中的代码执⾏完成后,需要加上 break ,才能跳出这个switch语句。

2 switch语句中的break

        前⾯的代码中,如果我们去掉case语句中的break,会出现什么情况呢?

#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);switch(n%3){case 0:printf("整除,余数为0\n"); case 1:printf("余数是1\n"); case 2:printf("余数是2\n"); }return 0;
}

        你会发现,7除以3本来余数是1,但是我们发现程序运⾏的结果多了⼀⾏“余数是2”的打印。 原因是 switch 语句也是分⽀效果的,只有在 switch 语句中使⽤ break 才能在跳出 switch 句,如果某⼀个 case 语句的后边没有 break 语句,代码会继续往下执⾏,有可能执⾏其他 case  语句中的代码,直到遇到 break 语句或者 switch 语句结束。就⽐如上⾯的代码就执⾏了 case  2 中的语句。 所以在 switch 语句中 break 语句是⾮常重要的,能实现真正的分⽀效果。 当然, break 也不是每个 case 语句都得有,这就得根据实际情况来看了。
练习:
输⼊⼀个1~7的数字,打印对应的星期⼏
例如:
输⼊:1 输出:星期⼀
输⼊:2 输出:星期⼆
输⼊:3 输出:星期三
输⼊:4 输出:星期四
输⼊:5 输出:星期五
输⼊:6 输出:星期六
输⼊:7 输出:星期天
代码展示:
#include <stdio.h>
int main()
{int day = 0;scanf("%d", &day);switch(day){case 1:printf("星期⼀\n");break;case 2:printf("星期⼆\n");break;case 3:printf("星期三\n");break; case 4:printf("星期四\n");break; case 5:printf("星期五\n");break;case 6:printf("星期六\n");break;case 7:printf("星期天\n"); break;}return 0;
}
如果需求发⽣变化,变为:   输⼊1-5,输出的是“⼯作⽇”;   输⼊6-7,输出“休息⽇”
那么代码可以修改为:
#include <stdio.h>
int main()
{int day = 0;scanf("%d", &day);switch(day){case 1:case 2:case 3:case 4:case 5:printf("⼯作⽇\n");break;case 6:case 7:printf("休息⽇\n");break;}return 0;
}

        因此你会发现在实际问题中应该根据实际的情况来处理,在代码中判断是否使⽤ break ,或者在哪⾥使⽤ break ,才能正确完成实际的需求。

3 switch语句中的default 

        在使用switch语句的时候,我们经常可能遇到一种情况,比如switch后的表达式中值无法匹配代码中的case语句时,这时候要不就不做处理,要不就得在switch语句中加入default子句。说白了,default的作用就是在case中没有对应分支语句时,default会承担case的责任,并继续执行下方语句。其结构是:

        switch (expression)
         {
                case value1:
                                 statement;
                case value2:
                                statement;
                default :
                                statement;
        }        
        如果switch 后边的 expression 的结果不是 value1 ,也不是 value2 的时候,就会执⾏
default ⼦句。 就⽐如前⾯做的打印星期的练习,如果 day 的输⼊不是1~7的值,如果我们要提⽰:输⼊错误,则可 以这样完成代码:
#include <stdio.h>
int main()
{int day = 0;scanf("%d", &day);switch(day){case 1:case 2:case 3:case 4:case 5:printf("⼯作⽇\n");break;case 6:case 7:printf("休息⽇\n");break;default:printf("输⼊错误\n");break;}return 0;
}

 4 switch语句中的case和default的顺序问题

        在 switch 语句中 case ⼦句和 default ⼦句有要求顺序吗? default 只能放在最后吗?其实,在 switch 语句中 case 语句和 default 语句是没有顺序要求的,只要你的顺序是满⾜实 际需求的就可以。不过我们通常是把 default ⼦句放在最后处理的。

 # while循环

        C语⾔一共提供了3种循环语句, while 就是其中⼀种,接下来就介绍⼀下 while 语句。while 语句的语法结构和 if 语句⾮常相似。

1 if 和 while的对⽐

if (表达式)                while(表达式)

        语句;                                语句;

//代码1
#include <stdio.h>
int main()
{if(1)printf("hehe\n"); //if后边条件满⾜,打印⼀次hehereturn 0;
}
//代码2
#include <stdio.h>
int main()
{while(1)printf("hehe\n"); //while后边的条件满⾜,死循环的打印hehereturn 0;
}
        这就是他们的区别,while语句是可以实现循环效果的。

 2 while语句的执⾏流程

        ⾸先上来就是执⾏判断表达式,表达式的值为0,循环直接结束;表达式的值不为0,则执⾏循环语句,语句执⾏完后再继续判断,是否进⾏下⼀次判断。

3 while循环的实践 

        练习:在屏幕上打印 1~10 的值
参考代码:
#include <stdio.h>
int main()
{int i = 1;while(i<=10){printf("%d ", i);i = i+1;}return 0;
}

4 while循环练习  

输⼊⼀个正的整数,逆序打印这个整数的每⼀位
例如:
输⼊:1234,输出:4 3 2 1
输⼊:521,输出:1 2 5
这道题是比较常见的题目,考察的是 % 和 / 在循环中的应用。
        要想得到n的最低位,可以使⽤n%10的运算,得到的余数就是最低位,如:1234%10得到4,   要想去掉n的最低位,找出倒数第⼆位,则使⽤ n=n/10 操作就可以去掉最低位的,n=1234/10得到123,123相较于1234就去掉了最低位,123%10就得到倒数第⼆位3。   循环1和2两个步骤,在n变成0之前,就能到所有的位。代码如下:
#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);while(n){printf("%d ", n%10);n /= 10;}return 0;
}

        如此while循环就讲完了,while循环的使用非常简单,相信各位在以后的使用中能够熟练掌握。

# for循环 

1 语法形式

​​​​​​​             接下来请各位注意,for循环是我们三种循环中使用最多的,for循环的语法形式如下: for(表达式1; 表达式2; 表达式3)

                        语句; // 如果循环体想 包含更多的语句,可以加上⼤括号
        表达式1 :⽤于循环变量的初始化
        表达式2 :⽤于循环结束条件的判断
        表达式3 :⽤于循环变量的调整

2 for循环的执⾏流程 

        ⾸先执⾏ 表达式1 初始化循环变量,接下来就是执行表达式 2 的判断部分,表达式 2的结果如果 == 0(即表达式为假),则循环结束;表达式 2 的结果如果!=0则执⾏循环语句,循环语句执⾏完后,再去执⾏表达式 3 ,调整循环变量,然后再去表达式 2的地⽅执⾏判断,表达式2 的结果是否为0,决定循环是否继续。整个循环的过程中,表达式1初始化部分只被执⾏1次,剩下的就是表达式2、循环语句、表达式3在循环。

 3 for循环的实践

练习:在屏幕上打印1~10的值
#include <stdio.h>int main()
{
int i = 0;
for(i=1; i<=10; i++)
{printf("%d ", i);
}return 0;
}

4 while循环和for循环的对⽐ 

        for 和 while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是 for 循环的三个部分⾮常集中,便于代码的维护,⽽如果代码较多的时候 while 循环的三个部分就⽐较分散,所以从形式上 for 循环要更优⼀些。

 5 for循环练习

练习1: 计算1~100之间3的倍数的数字之和
#include <stdio.h>
int main()
{int i = 0;int sum = 0;for(i=1; i<=100; i++){if(i % 3 == 0)sum += i;}printf("%d\n", sum);return 0;
}

        这是最常见的写法,但是如果能直接产⽣3的倍数的数字就省去了多余的循环和判断,思路有了就要立即实践。

#include <stdio.h>
int main()
{int i = 0;int sum = 0;for(i=3; i<=100; i+=3){sum += i;}printf("%d\n", sum);return 0;
}

‘        这样不仅简化了代码,还提高了运行效率,这也是我们在平常刷题的时候要去不断思考得到问题。

# do—while循环 

1 语法形式

        在循环语句中 do while 语句的使⽤最少,它的语法如下:
        do
        {
        语句;
         }
        while ( 表达式 )
         while for 这两种循环都是先判断,条件如果满⾜就进⼊循环,执⾏循环语句,如果不满⾜就跳出循环; do while 循环则是先直接进⼊循环体,执⾏循环语句,然后再执⾏ while 后的判断表达式,表达式为真,就会进⾏下⼀次,表达式为假,则不再继续循环。

2 do while循环的执行流程 

        在 do while 循环中先执⾏图上的“循环体”,执⾏完后,在去执⾏“条件”,条件的结果是!=0,则继续循环,执⾏循环语句;判断表达式的结果==0,则循环结束。所以在 do while 语句中循环体是⾄少执⾏⼀次的,这是 do while 循环⽐较特殊的地⽅。

3 do while循环的实例 

在屏幕上打印1~10的值
#include <stdio.h>
int main()
{int i = 1;do{printf("%d ", i);i = i + 1;}while(i<=10);return 0;
}
        ⼀般 do while 使⽤在循环体⾄少被执⾏⼀次的场景下,所以较少⼀些。

4 练习 

输⼊⼀个正整数,计算这个整数是⼏位数?
例如:      输⼊:1234         输出:4
                 输⼊:12             输出:2
#include <stdio.h>
int main()
{int n = 0;scanf("%d", &n);int cnt = 0;do{cnt++;n = n / 10;} while (n);printf("%d\n", cnt);return 0;
}
        这⾥并⾮必须使⽤do while 语句,但是这个代码就⽐较适合使⽤ do while循环,因为当n是0时,while和for循环打印都是0,而do while是1。

break和continue语句  

        在循环执⾏的过程中,如果某些状况发⽣的时候,需要提前终⽌循环,这是⾮常常⻅的现象。C语⾔中提供了 break continue 两个关键字,就是应该到循环中的。
        • break 的作⽤是⽤于永久的终⽌循环,只要 break 被执⾏,直接就会跳出循环,继续往后执​​​​​​​⾏。
        • continue 的作⽤是跳过本次循环 continue 后边的代码,在 for 循环和 while 循环中是有所差异的。

1 while循环中的break和continue 

1.1 break

        break 的作⽤就是永久的终⽌循环,只要 break 被执⾏, break 外的第⼀层循环就终⽌了。那以后我们在循环中,想在某种条件下终⽌循环,则可以使⽤ break 来完成我们想要的效果。

        break 执行代码展示:

#include <stdio.h>
int main()
{int i = 1;while(i<=10){if(i == 5)break;//当i等于5后,就执⾏break,循环就终⽌了printf("%d ", i);i = i+1;}return 0;
}

        打印了1,2,3,4后,当i等于5的时候,循环正 break 的地⽅终⽌,不再打印,不再循环。

1.2 continue

        而continue 是继续的意思,在循环中的作⽤就是跳过本次循环中 continue 后边的代码,继续进⾏下⼀次循环的判断。上⾯的代码,如果把 break 换成 continue 会是什么结果呢?
#include <stdio.h>
int main()
{int i = 1;while(i<=10){if(i == 5)continue;//当i等于5后,就执⾏continue,直接跳过continue的代码,去循环的判断的地⽅//因为这⾥跳过了i = i+1,所以i⼀直为5,程序陷⼊和死循环printf("%d ", i);i = i+1;}return 0;
}
        到这⾥我们就能分析出来, continue 可以帮助我们跳过某⼀次循环 continue 后边的代码,直接到循环的判断部分,进⾏下⼀次循环的判断,如果循环的调整是在 continue 后边的话,可能会造成死循环。

2 for循环中的break和continue 

2.1 break

        其实和 while 循环中的 break ⼀样, for 循环中的 break 也是⽤于终⽌循环的,不管循环还需要循环多少次,只要执⾏到了 break ,循环就彻底终⽌,我们上代码。
#include <stdio.h>
int main()
{int i = 1;for(i=1; i<=10; i++){if(i == 5)break;printf("%d ", i);}return 0;
}

       未来我们在某个条件发⽣的时候,不想再继续循环的时候,就可以使⽤ break 来完成。

2.2 continue

        上⾯的代码,如果把 break 换成 continue 会是什么结果呢?
#include <stdio.h>
int main()
{int i = 1;for(i=1; i<=10; i++){if(i == 5)continue;//这⾥continue跳过了后边的打印,来到了i++的调整部分printf("%d ", i);}return 0;
}

        所以在 for 循环中 continue 的作⽤是跳过本次循环中 continue 后的代码,直接去到循环的调整部分。未来当某个条件发⽣的时候,本次循环⽆需再执⾏后续某些操作的时候,就可以使⽤ continue 来实现。

 # goto语句

        在C语⾔中提供了⼀种⾮常特别的语法,就是 goto 语句和跳转标号, goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。
#include <stdio.h>
int main()
{printf("hehe\n");goto next:printf("haha\n");next:printf("跳过了haha的打印\n"); return 0;
}
        一般情况下,我并不推荐goto 语句如果使⽤的不当,就会导致在函数内部随意乱跳转,打乱程序的执⾏流程,所以我们的建议是能不⽤尽量不去使⽤;但是 goto 语句也不是⼀⽆是处,在多层循环的代码中,如果想快速跳出使⽤ goto 就⾮常的⽅便了。比如:
for(...)
{for(...){for(...){if(disaster)goto error;}}
}
error:
        本来 for 循环想提前退出得使⽤ break ,⼀个 break 只能跳出⼀层 for 循环,如果3层循环嵌套就得使⽤3个 break 才能跳出循环,所以在这种情况下我们使⽤ goto 语句就会更加的快捷。

到此,我们的分支和循环结构就都讲完了,如果能够给到大家一定的帮助,我也会非常荣幸,感谢观看。 

相关文章:

分支和循环

通常来说&#xff0c;C语言是结构化的程序设计语言&#xff0c;这里的结构包括顺序结构、选择结构、循环结构&#xff0c;C语言能够实现这三种结构&#xff0c;如果我们仔细分析&#xff0c;我们日常生活中所见的事情都可以拆分为这三种结构或者它们的组合。 下面我会仔细讲解我…...

MyBatis-xml版本

MyBatis 是一款优秀的持久层框架 MyBatis中文网https://mybatis.net.cn/ 添加依赖 <dependencies><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47<…...

在eclipse中安装python插件:PyDev

在eclipse中安装插件PyDev&#xff0c;就可以在eclipse中开发python了。 PyDev的官网&#xff1a;https://www.pydev.org/ 不过可以直接在eclipse中用Marketplace安装&#xff08;备注&#xff1a;有可能一次安装不成功&#xff0c;是因为下载太慢了&#xff0c;多试几次&…...

25、pytest的测试报告插件allure

allure简介 在这里&#xff0c;你将找到使用allure创建、定制和理解测试报告所需的一切。开始让你的测试沟通更清晰&#xff0c;更有影响力。 Allure Report是一个实用程序&#xff0c;它处理由兼容的测试框架收集的测试结果并生成HTML报告。 安装allure 1、确保安装了Java…...

从零开始学习 JavaScript APl(七):实例解析关于京东案例头部案例和放大镜效果!

大家好关于JS APl 知识点已经全部总结了&#xff0c;第七部部分全部都是案例部分呢&#xff01;&#xff01;&#xff08;素材的可以去百度网盘去下载&#xff01;&#xff01;&#xff01;&#xff09; 目录 前言 一、个人实战文档 放大镜效果 思路分析&#xff1a; 关于其它…...

使用Pytoch实现Opencv warpAffine方法

随着深度学习的不断发展&#xff0c;GPU/NPU的算力也越来越强&#xff0c;对于一些传统CV计算也希望能够直接在GPU/NPU上进行&#xff0c;例如Opencv的warpAffine方法。Opencv的warpAffine的功能主要是做仿射变换&#xff0c;如果不了解仿射变换的请自行了解。由于Pytorch的图像…...

Hello World

世界上最著名的程序 from fastapi import FastAPIapp FastAPI()app.get("/") async def root():return {"message": "Hello World"}app.get("/hello/{name}") async def say_hello(name: str):return {"message": f"…...

【Python】Python读Excel文件生成xml文件

目录 ​前言 正文 1.Python基础学习 2.Python读取Excel表格 2.1安装xlrd模块 2.2使用介绍 2.2.1常用单元格中的数据类型 2.2.2 导入模块 2.2.3打开Excel文件读取数据 2.2.4常用函数 2.2.5代码测试 2.2.6 Python操作Excel官方网址 3.Python创建xml文件 3.1 xml语法…...

c++--类型行为控制

1.c的类 1.1.c的类关键点 c类型的关键点在于类存在继承。在此基础上&#xff0c;类存在构造&#xff0c;赋值&#xff0c;析构三类通用的关键行为。 类型提供了构造函数&#xff0c;赋值运算符&#xff0c;析构函数来让我们控制三类通用行为的具体表现。 为了清楚的说明类的构…...

笔记64:Bahdanau 注意力

本地笔记地址&#xff1a;D:\work_file\&#xff08;4&#xff09;DeepLearning_Learning\03_个人笔记\3.循环神经网络\第10章&#xff1a;动手学深度学习~注意力机制 a a a a a a a a a a a...

面试官问:如何手动触发垃圾回收?幸好昨天复习到了

在Java中&#xff0c;手动触发垃圾回收可以使用 System.gc() 方法。但需要注意&#xff0c;调用 System.gc() 并不能确保立即执行垃圾回收&#xff0c;因为具体的垃圾回收行为是由Java虚拟机决定的&#xff0c;而不受程序员直接控制。 public class GarbageCollectionExample …...

操作系统的运行机制+中断和异常

一、CPU状态 在CPU设计和生产的时候就划分了特权指令和非特叔指令&#xff0c;因此CPU执行一条指令前就能断出其类型 CPU有两种状态&#xff0c;“内核态”和“用户态” 处于内核态时&#xff0c;说明此时正在运行的是内核程序&#xff0c;此时可以执行特权指令。 处于用户态…...

Python实战:批量加密Excel文件指南

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是彭涛&#xff0c;今天为大家分享 Python实战&#xff1a;批量加密Excel文件指南&#xff0c;全文3800字&#xff0c;阅读大约10分钟。 在日常工作中&#xff0c;保护敏感数据是至关重要的。本文将引导你通过…...

二叉树链式结构的实现和二叉树的遍历以及判断完全二叉树

二叉树的实现 定义结构体 我们首先定义一个结构来存放二叉树的节点 结构体里分别存放左子节点和右子节点以及节点存放的数据 typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right; }BTNode;…...

vue中的动画组件使用及如何在vue中使用animate.css

“< Transition >” 是一个内置组件&#xff0c;这意味着它在任意别的组件中都可以被使用&#xff0c;无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发&#xff1a; 由 v-if 所触发的切换由 v-show 所触…...

qt 5.15.2 网络文件下载功能

qt 5.15.2 网络文件下载功能 #include <QCoreApplication>#include <iostream> #include <QFile> #include <QTextStream> // #include <QtCore> #include <QtNetwork> #include <QNetworkAccessManager> #include <QNetworkRep…...

Wifi adb 操作步骤

1.连接usb 到主机 手机开起热点&#xff0c;电脑和车机连接手机&#xff0c;或者电脑开热点&#xff0c;车机连接电脑&#xff0c;车机和电脑连接同一个网络 因为需要先使用usb&#xff0c;后面切换到wifi usb 2.查看车机ip地址&#xff0c;和电脑ip地址 电脑win键r 输入cmd…...

湿货 - 231206 - 关于如何构造输入输出数据并读写至文件中

TAG - 造数据、读写文件 造数据、读写文件 造数据、读写文件//*.in // #include<bits/stdc.h> using namespace std;/* *********** *********** 全局 ********** *********** */ string Pre_File_Name; ofstream IN_cout; int idx;void Modify_ABS_Path( string& …...

EasyMicrobiome-易扩增子、易宏基因组等分析流程依赖常用软件、脚本文件和数据库注释文件

啥也不说了&#xff0c;这个好用&#xff0c;给大家推荐&#xff1a;YongxinLiu/EasyMicrobiome (github.com) 大家先看看引用文献吧&#xff0c;很有用&#xff1a;https://doi.org/10.1002/imt2.83 还有这个&#xff0c;后面马上介绍&#xff1a;YongxinLiu/EasyAmplicon: E…...

【Python百宝箱】漫游Python数据可视化宇宙:pyspark、dash、streamlit、matplotlib、seaborn全景式导览

Python数据可视化大比拼&#xff1a;从大数据处理到交互式Web应用 前言 在当今数字时代&#xff0c;数据可视化是解释和传达信息的不可或缺的工具之一。本文将深入探讨Python中流行的数据可视化库&#xff0c;从大数据处理到交互式Web应用&#xff0c;为读者提供全面的了解和…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...