分支语句和循环语句详解
在我们的现实生活中,做事情可以分为三种结构:
顺序结构、选择结构、循环结构
C语句可分为以下五类:
- 表达式语句
- 函数调用语句
- 控制语句
- 复合语句
- 空语句
而在C语言中,控制语句用于控制程序的执行流程,以实现程序的各种结构方式。
C语言支持三种结构:顺序结构、选择结构、循环结构,也对应与我们的生活。
它们由特定的语句定义符组成,C语言有九种控制语句。
可分成以下三类:
- 条件判断语句也叫分支语句:if语句、switch语句;
- 循环执行语句:do while语句、while语句、for语句;
- 转向语句:break语句、goto语句、continue语句、return语句。
分支语句
很好理解,就是十字路口选哪条路的问题,只不过这里就不是实际路口了,而是好多路口,不同的选择不同的结果。
1.if语句
if语句的语法结构:
如果表达式的结果为真,则语句执行。
在C语言中:0表示假,非0表示真。(-1也算真)
if(表达式)
语句;
if(表达式)
语句1;
else
语句2;
//多分支
if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
这里要注意的是语句如果大于等于两句,就要加{ },不然就是语法错误。
如果只有一句,那么就可加可不加。
一对 { } 就是一个代码块。
上例子:
第一种的:
第二种的:
第三种的:
1.1悬空else
先看这个:
请问:这个输出结果是什么?
先别看答案,想好了再往下翻。
答案是什么也不输出
为啥呢?这是因为else总是和其相距最近的if相匹配的,这里else看上去是和if(a == 1)对齐的,但是这只不过是表面现象,要透过现象看本质🤔,记住就好,下次不许错了。
其实它实际上对其的话应该是这样的:
不过我们还可以再加上{}改进一下:
这样看上去就方便很多了。
不一样的代码风格给人的感受是完全不同的,好的代码风格能让人更容易理解,而代码风格比较烂的话就让人很费解。
1.2练习题
- 判断一个数是否为奇数
- 输出1-100之间的奇数
瞅一眼看看会不会?
2.switch语句
switch语句也是一种分支语句。常常用于多分支的情况。
比如:
输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六
输入7,输出星期日
那我们如果写成 if…else if …else if 的形式的话就太复杂了,那我们就得有不一样的语法形式。那就是switch语句。
switch(整型表达式)
{
语句项;
}
语句项是一些case语句
case 整形常量表达式:
语句;
2.1在switch语句中的 break
break是用来跳出当前所在的case语句的,若果没有break的话就没法跳出,就会沿着当前case下的所有case都执行一遍。就不是我们想要的结果了。如下所示:
这样就错误了。
2.2default子句
上面一个例子中也可以看到default这个东西,这个是用来当你所输入的信息与所有的case都不匹配时,就会执行default子句。
几个重要的点:
switch(整型表达式),括号内部一定要是整形表达式,不然是错误的,可以是int,short,long,long long,char,不能是浮点类型的。
case后面也要跟整形常量表达式,比如说1,‘1’等等
switch内部的case语句和default语句没有顺序要求,default也可放在最前面。
循环语句
由于我们发现生活中很多的实际的例子是:同一件事情我们需要完成很多次。所以就出现了循环语句。
1.while循环
while语句执行的流程:
给个例子:在屏幕上打印1-10的数字。
每次循环先判断i是否成立,再进去先打印,后i++,直到i<=10为止。
1.1while语句中的break和continue
break
上例子:
break是指直接跳出本次循环(break下方的语句也不会被执行),并不再进行之后的循环。
continue
这里程序直接进入了死循环,因为continue是跳过该语句下方的所有语句并且继续执行下次循环,这样的话这里的i就永远是5,不会改变。
continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,
而是直接跳转到while语句的判断部分。进行下一次循环的入口判断
1.2缓冲区
再看几个代码:
这里涉及到了缓冲区的芝士,我来讲讲。
对于scanf和getchar这样的输入函数,它们若想得到输入的内容,是这样进行的:
你先在键盘上将所输入的东西打到缓冲区中,然后再将缓冲区中的内容传递给了输入函数。也就是说还有一个缓冲区这个中间商。
上面的例子中getchar是输入一个字符,putchar是输出一个字符,我们来看一下运行结果:
可以看到,光标停在了3的下面,当我们输入1并按下回车之后getchar得到了a,然后进入循环中putchar输出了a,然后再次循环,判断条件中getchar得到了\n,putchar输出了\n。然后我们有输入了3并且按下回车,与上方的过程类似,就使得我们每一次输入时光标都是顶格的,这里需要注意的就是这一点。
当然,getchar还有别的用途,就是清空缓冲区,具体如下:
来个例子:
这里我们可以看到,当scanf输入时遇到了空格就会自动结束。那么缓冲区中就会有剩余的 dfs,这时候就需要用到getchar来清除缓冲区了。
如果不去清楚的话就会出现以下结果:
2.for循环
2.1 语法
for(表达式1; 表达式2; 表达式3)
循环语句;
表达式1
表达式1为初始化部分,用于初始化循环变量的。
表达式2
表达式2为条件判断部分,用于判断循环时候终止。
表达式3
表达式3为调整部分,用于循环条件的调整。
来个例子:使用for循环 在屏幕上打印1-10的数字。
我们可以和while做一下对比:
可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹;for循环使用的频率也最高。
2.2 break和continue在for循环中
我们发现在for循环中也可以出现break和continue,他们的意义和在while循环中是一样的。但是结果就不一样了。
上例子:
break
continue
前面我们了解到,continue在while循环中的打印结果是1 2 3 4后死循环,但在这里for循环中却没有,这是因为continue过后还会执行调整的语句,所以就不会出现死循环的情况。
2.3 for语句的循环控制变量
建议不要在循环体内部使用调整的语句,不然可能会出现以及想不到的后果。
好的代码风格:左闭右开
例如:
这里就是[0,10),此处就代表了循环10次,这样的话代码的可读性就会更高。
2.4 一些for循环的变种
for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题。
例如说:
这里省略掉了括号内的三个表达式,就导致了死循环。
这里如果粗心的话就可能以为代码打印的是九个hello,但是只打印了三个,因为i进去一次后,j循环了三次直接使得j变成了3,那么无论i再执行几次都会导致无法进行内部的循环。再来看一道题:
这道题一定要记住的一点是,判断相等是两个等号,不是一个等号,一个等号是赋值。
3 do…while()循环
3.1 do语句的语法
do
循环语句;
while(表达式);
3.2例子
使用do…while()循环 在屏幕上打印1-10的数字。.
3.3 do语句的特点
循环至少执行一次,使用的场景有限,所以不是经常使用。
3.4 do while循环中的break和continue
跟前面的while和for几乎是一样的,就不过多解释了,看下例子就行。
4.goto语句
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。
我们先来看一下怎么用的:
从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。
但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。
例如当我们需要跳出多层循环时。
这个时候就不需要搞好多个break来跳出循环了。
到此结束。