目录
控制语句及其分类
控制语句用于控制程序的执行流程,以实现程序的各种结构方式,(c语言支持3种结构:顺序结构、选择结构、循环结构),它们由特定的语句定义符组成,c语言有九种控制语句。
可分为以下三类:
- 条件判断语句也叫分支语句:if语句,switch语句
- 循环执行语句:do while语句,while语句,for语句
- 转向语句:break语句,goto语句,continue语句,return语句
一、分支语句(选择结构)
1.1 ❥ if语句
if可理解为是如果的意思。
例如:如果(if)小明7点之前起床,他就可以得到三朵小红花。
单分支
语法结构如下:
if(表达式)
语句;
注意:
- 表达式为真,则语句执行,表达式为假,则语句不执行
- 在c语言中,0为真,非0为假
接下来我们可以看一个例子:判断一个整数是否为奇数?
#include <stdio.h>
int main()
{
int a = 10;//定义一个变量a
if (a % 2 == 0)//判断a是否为奇数
{
printf("奇数\n");//如果是奇数,则执行该括号里的语句
}
return 0;
}
双分支(引入else关键字)
如果一个数不是奇数,那就是偶数了,如果任意一个整数,我们要判断是奇数还是偶数怎么表示呢?
我们用if...else...进行表示
else可理解为否则的话。
例如:如果(if)小明7点之前起床,他就可以得到三朵小红花;否则(else)他只能得到1朵小红花。
语法结构如下:
if(表达式)
语句1;
else
语句2;
例子:输入一个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印数偶数。
#include <stdio.h>
int main()
{
int a = 10;
if (a % 2 == 0)
{
printf("奇数\n");
}
else
{
printf("偶数\n");
}
return 0;
}
多分支
语法结构如下:
if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
........
嵌套if
在 if else 语句中, else 可以与另⼀个 if 语句连用,构成多重判断。
例如:要求输入一个整数,判断输入的整数是0,还是正数或者负数。
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if (num == 0)
printf("输出的数字是0\n");
else
if (num > 0)
//这里的if相当于嵌套在else语句中,形成了嵌套结构
printf("输出的数字是正数\n");
else
printf("输出的数字是负数\n");
return 0;
}
悬空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");
else
printf("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;
}
大括号的作用{ }
- 当if或else表达式后面执行多条语句的时候,一定要加上大括号,否则只会执行表达式后面的一条语句。
- 在写代码的时候要适当的加上大括号,代码的逻辑就会变得更加清晰,让代码的可读性更高。
- 一对{ }就是一个代码块。
注意事项
1、if...else语句只能执行其中的一个,不能多个执行。例如多分支语句那里,只能执行其中的一条(即只能执行语句1,或者语句2,或者语句3)。
2、当有多个if语句的时候,每一条if语句都执行。
if(...)
if(...)...
3、if括号里不能连续写操作运算符。
例如下面代码:
if (18 <= age < 28)
{
printf("青年\n");
}
因为18<=10为假,所以为0,0<28,所以结果为真,执行语句。
正确写法应该是:(age>=18 && age<28)
if (18 <= age &&age< 28)
{
printf("青年\n");
}
1.2 ❥ switch
除了if语句外,c语言还提供了switch语句来实现分支结构。
switch也叫开关语句,它是一种特殊形式的if...else结构,用于判断条件有多个结果的情况。
它把多重的 else if 改成更易用、可读性更好的形式。
语法结构如下:
switch (整型表达式)
{
case 整型常量表达式:语句;
case 整型常量表达式:语句;
}
switch的执行方式
会根据switch后面表达式的值,决定它匹配哪个表达式,然后从该处依次往下执行。
如果找不到对应的值,就执行default 分支。
如果不想继续往下执行,就可以使用break关键字,意思是中止。
break
只有在 switch 语句中使用break ,才能在跳出 switch 语句,如果某一个 case 语句的后边没有 break 语句,代码就会继续往下执行,有可能执行其他 case语句中的代码,直到遇到 break 语句或者 switch 语句结束。
所以在 switch 语句中用到 break,能够实现真正的分支效果。
但是break 不是每个 case 语句都得有,这就得根据实际情况来看是否需要。
注意:switch可以嵌套,但break只能跳出本层循环。
default
所有case语句不能匹配的,都会走到default这里。
每个switch语句中只能出现一条default子句。若有多个default,代码将会报错提醒。
记得default后加上break,否则会出现以下现象:
注意事项:
- switch后面括号内的表达式可以是整型(int)、字符型(char)或者布尔型(bool)。
- case后必须是整型常量表达式,可以是字符,字符本质上是个整型,因为字符存储的时候存的是它的ASCII值。
- case 与常量表达式之间必须有空格,否则无法区分关键词。
- case只是决定了入口。
- 在最后一个case语句后最好加上break ( 防止之后再写case语句,造成错误 ),最终是否需要还得看逻辑是否需要。
- 每个case语句后面的常量表达式的值必须是互不相同,否则就会出现错码。
- 每个case和default语句中可以包含多个执行语句,可以不用大括号括起来,即不需要写成{XX“和”XX}的形式。
- 如果每个case和default子句中都有break语句,则他们出现的次序不影响程序的执行结果。
- default子句可以省略,若default放在最后,则语句末尾可以不写break。
编程好习惯:在每个switch语句中都放个default语句是个好习惯,还可以再在default后面加上一个break。
case和default顺序问题
在 switch 语句中 case 语句和 default 语句是没有顺序要求的,只要你的顺序是满足实
际需求的就可以。
通常是把 default 子句放在最后处理的。
二、循环语句
2.1 ❥ while
语法形式如下:
while(表达式)
语句; //如果循环体想包含更多的语句,可以加上大括号
表达式为真执行,为假结束。
while循环中的break和continue
break
while循环遇到break的作用:终止整个循环,永久的终止循环。
如下代码:
打印了0,1,2,3,4后,当i等于5的时候,循环在 break 的地方结束循环。
所以 break 的作用就是永久的终止循环,只要 break 被执行, break 外的第一层循环就结束了。
在以后的循环中,想在某种条件下终止循环,则可以使用break 来完成我们想要的效果。
continue
while循环遇到continue的作用:跳过本次循环后面的代码,直接去判断部分,进行下一次的循环。
当i等于5时,执行continue,直接跳过continue的代码,去循环的判断的地方。因为跳过了i++,所以i一直为5,程序陷入死循环。
所以continue 可以帮助我们跳过某一次循环 continue 后边的代码,直接到循环的判断部分,进行下一次循环的判断,如果循环的调整是在 continue 后边的话,可能会造成死循环。
所以说:while循环遇见continue,变量的位置不一样,结果也不一样。
2.2 ❥ for循环
语法结构如下:
for(定义初始循环变量;循环条件;循环条件调整)
{
循环语句块;
}
for循环与while循环对比
for 和 while 在实现循环的过程中都有初始化、判断、调整这三个部分,但是 for 循环的三个部分非常集中,便于代码的维护。当代码较多的时候, while 循环的三个部分就比较分散,所以从形式上 for 循环要更好一些。
注意:for循环中表达式后面跟的是分号,最后一个表达式后面不用跟分号。
for语句的循环控制变量
建议:
1. 不可在循环体内修改循环变量,防止for循环失去控制。
如下代码:
变量i的值每次会变成5,5<10,所以就会一直跳不出循环。
2. 建议for语句的循环控制变量的取值采用【前闭后开区间】的写法。
如下图所示:
左边代码的可读性比右边强,但也要看具体应用场景来决定用什么方式。
for循环中的break和continue
break
和 while 循环中的 break 用法一样。
break的作用是:终止整个循环,永久的终止循环。
continue
在 for 循环中 continue 的作用是:跳过本次循环中 continue 后的代码,直接去到循环的调
整部分。
对比while和for中的continue
for循环中continue是跳过本次循环到调整部分。
而while循环中continue是跳过本次循环到判断部分。
for循环的变种
for( ; ; )
{
printf("hehe\n");
}
for循环中的初始化部分,判断部分,调整部分是可以省略的,但不建议初学时省略,容易导致问题。
for循环【判断部分】省略意味着判断会恒成立(死循环)。
建议不要随便省略任何一条语句。
打印3个hehe的原因是:for外层循环了一次,内层循环了三次。
原因:for外层循环第二次的时候,内层的j初始化的值为上一次的3,所以不进入循环。
2.3 ❥ do-while
语法结构如下:
do
{语句;
}while(表达式);
执行方式
do while 循环则是先直接进入循环体,执行循环语句,然后再执行 while 后的判断表达式。
表达式为真,就会进行下一次,表达式为假,则不再继续循环。
特点:该循环至少要循环一次,使用的场景有限,所以不是经常使用。
注意:while语句后要加 分号;
do-while循环中的break和continue
do while 语句中的 break 和 continue 的作用和 while 循环中几乎相同。
代码如下:
三、转向语句
3.1 ❥ goto
goto 语句可以实现在同一个函数内跳转到设置好的标号处。
代码如下:
死循环。它类似于传送点,到again那里。
最常见的用法就是:终止程序在某些深度嵌套的结构的处理过程。但不建议使用goto语句,容易出现bug。
例如:一次跳出两层或多层循环。
多层循环这种情况使用break达不到目的,它只能从内层循环退到上一层循环。
注意:goto语句不能跨函数进行goto,它只能在函数内部进行跳转。
goto适用如下场景:
for(...)
{
for(...)
{
for(...)
{
if(disaster)
goto error;
}
}}
error:
//...