分支与循环语句
1.什么是语句?
C语句可分为以下五类:
1.表达式语句
2.函数调用语句
3.控制语句
4.复合语句
5.空语句(空语句就是我需要这个语句,但不要这个语句做任何事)
后面介绍的是控制语句。
控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语
言有九种控制语句。
可分成以下三类:
条件判断语句也叫分支语句:if语句、switch语句;
循环执行语句:do while语句、while语句、for语句;
转向语句:break语句、goto语句、continue语句、return语句。
2.分支语句(选择结构)
如果不好好读书 你就回家种田,如果好好读书,你就可以找到好的工作,这个就是选择。
选择有二选一,也有三选一,还有多选一。
2.1if语句
if语句的语法结构:
//单分支:
if(表达式)
语句;
//双分支:
if(表达式)
语句;
else
语句;
//多分支:
if(表达式)
语句;
else if(表达式)
语句;
else if(表达式)
语句;
........
else
语句;
注意:
如果语句中为真则执行语句;为假就不执行语句,在c语言中规定0为假非0为真。
if括号里的表达式是指是一个有值的式子,像函数它会返回一个值。
如果条件成立,要执行多条语句,怎应该使用代码块。
#include <stdio.h>
int main()
{
if(表达式)
{
语句列表1;
}
else
{
语句列表2;
}
return 0;
}
这里的 { } 就是一个代码块。
2.1.1悬空else
当你写这个代码
#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;
}
这样写代码会有一种很模糊的感觉,这里的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;
}
这样我们一下就看出来else对应哪个if,所以代码的风格很重要,好的代码风格可以让你的逻辑更加清楚。
注意:
else是和它最近的if所配备。
2.1.2switch语句
switch语句也是一个分支语句,但它更适用多分支。
比如:
输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六
输入7,输出星期日
如果使用if …else if…的话那么就太复杂,太繁琐了。
switch语句的语法形式:
switch(整型表达式)
{
语句项;
}
什么是语句项呢?
case(整型常量表达式):
语句;
语句项就是这些case语句
我们把上面那个列子用switch语句来实现一下
#include <stdio.h>
int main()
{
int day = 0;
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;
}
在这里的break实现了在switch语句跳出分支的效果
如果没有break语句的话,他就会一直按着顺序一条一条语句执行。
#include <stdio.h>
int main()
{
int day = 0;
switch(day)
{
case 1:
printf("星期一\n");
case 2:
printf("星期二\n");
case 3:
printf("星期三\n");
case 4:
printf("星期四\n");
case 5:
printf("星期五\n");
case 6:
printf("星期六\n");
case 7:
printf("星期天\n");
}
return 0;
}
当我输入了一个1,在没有break语句情况下,它将后面的都打印出来
当我加了break之后,再输入1之后
那个case语句项就是但我输入什么就从什么进去,比如我输入1,那么就从case1:中进去。
编程好习惯:
在最后一个 case 语句的后面加上一条 break语句。
(之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加 break语句)。
default子句
如果表达的值与所有的case标签的值都不匹配怎么办?
其实也没什么,结构就是所有的语句都被跳过而已。
程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。
但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?
你可以在语句列表中增加一条default子句,把下面的标签
default:
写在任何一个 case 标签可以出现的位置。
当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。
所以,每个switch语句中只能出现一条default子句。
但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
编程好习惯:
在每个 switch 语句中都放一条default子句是个好习惯,甚至可以在后边再加一个 break 。
3.循环语句
在c语言中有三种循环语句:
while循环
if循环
do while 循环
3.1while循环
我们先看while循环的语法结构:
//与if语句很相似
while(表达式)
{
循环语句;
}
while循环的执行流程:While循环是先进入判断表达式判断为真,执行语句,然后循环变量加1,如果为假跳出循环,判断条件至少要执行一次。
我们举一个列子:
打印1-10的数字
#include <stdio.h>
int main()
{
int i=0;//定义一个初始变量
while(i<=10)//这是判断条件
{
printf("%d",i);
i++;//调整部分
}
return 0;
}
我们来看看break语句在while循环里的作用:
我们先写一个代码
#include <stdio.h>
int main()
{
int i=0;//定义一个初始变量
while(i<=10)//这是判断条件
{
if(i==5)
break;
printf("%d",i);
i++;//调整部分
}
return 0;
}
通过运行出来的结果可以推出break语句直接跳出循环。
我们也可以通过调试的方式来验证我们的结果
我们通过这些验证方式我们得出break语句在while语句的作用是永久的终止循环,只要遇到break循环,循环就终止。
接下来我们再探索一些continue对while循环的影响
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
continue;
printf("%d ", i);
i++;
}
return 0;
}
通过运行结果来看打印了1,2,3,4之后就死循环了,说明在执行continue语句之后的语句就没有被执行导致调整部分无法调整,才会出现死循环
经分析之后我总结continue语句对while循环的作用为跳过本次循环后面的代码,直接去判断部分,看是否进行下次判断。
总结一下:
continue在while循环中的作用:
跳过本次循环后面的代码,直接去判断部分,看是否进行下次判断
break在while循环中的作用:
永久的终止循环,只要遇到break循环,循环就终止
3.2for循环
先看for循环的语法结构
int main()
{
for(表达式1;表达式2;表达式3)
{
循环语句;
}
return 0;
}
for循环的执行过程:先执行初始化部分(只会被执行一次),再执行判断部分,然后执行循环语句,最后执行调整部分
我们还是以打印1-10在屏幕为例子
int main()
{
int i = 0;
for (i=1;i<=10;i++)
{
printf("%d ", i);
}
return 0;
}
我们对比一些for循环和while循环,可以明显看出for循环比while循环简单更高效
我们继续来探索break语句对for循环的影响
int main()
{
int i = 0;
for (i=1;i<=10;i++)
{
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
运行结果:
通过运行结果看出,break语句在for循环和while循环一样直接终止循环。
Break在for循环中的作用:
永久的终止循环,只要遇到break循环,循环就终止
我们再来探索一下continue语句在for循环的作用
int main()
{
int i = 0;
for (i=1;i<=10;i++)
{
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
运行结果:
根据运行结果来推断当i等于5时跳过了后面的语句,来到了调整部分。
得出结论:会跳过continue后面的语句,直接去调整部分
建议:
- 不要在for循环体内修改循环变量,防止for循环失去控制
- 建议for循环的循环控制变量采用“前闭后开区间”的写法
注意:
初始化,判断部分,调整部分都可以被省略,但是判断部分被省略的话意味判断部分恒为真,那么会进入死循环 - 3do while循环
do while循环的语法:
int main()
{
do
{
//循环语句;
} while (表达式);
return 0;
}
do while循环的执行流程:
先执行循环语句,之后在进入调整部分,最后进入判断语句,循环体至少要执行一次。循环体包括循环语句和调整部分
我们依然用上面那个列子来写一段代码
int main()
{
int i = 1;
do
{
printf("%d ", i);
i++;
} while (i<=10);
return 0;
}
break在do while循环的作用
int main()
{
int i = 1;
do
{
if (i == 5)
break;
printf("%d ", i);
i++;
} while (i<=10);
return 0;
}
运行结果:
根据运行结果可以看出breal语句在do while循环和前两种循环作用是一样的
break在do while循环中的作用:
永久的终止循环,只要遇到break循环,循环就终止
continue在do while循环的作用
int main()
{
int i = 1;
do
{
if (i == 5)
continue;
printf("%d ", i);
i++;
} while (i<=10);
return 0;
}
运行结果:
从运行结果看出continue语句在do while循环和while循环的作用是一样的。
continue在do while循环中的作用:
跳过本次循环后面的代码,直接去判断部分,看是否进行下次判断
4.goto语句
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。
从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。
但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过
程。
例如:一次跳出两层或多层循环。
多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。
我来举例一个使用goto语句的场景
一个关机程序
#include<stdlib.h>
int main()
{
char input[20] = { 0 };
system("shutdown -s -t 60");
again:
printf("本机器在1分钟之后关机,如果输入GGband就取消关机\n");
scanf("%s", &input);
if (strcmp(input, "GGband") == 0)
{
system("shutdown -a");
}
else
{
goto again;
}
return 0;
Goto语句:只能在同一个函数里跳转,不能跨函数。