携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
前言
本文为C语言控制语句的第一篇,主要介绍了控制语句中的if...else和switch语句,内容不多,实际上关于控制语句的话还有循环语句和转向语句没讲,打算下一篇再讲讲,可以期待一下哦。
由于笔者水平有限,文章拙劣而纰漏难免,欢迎指正,希望于你有益。
C语句可分为以下五类:
表达式语句
函数调用语句
控制语句
复合语句
空语句
而本文主要讲讲控制语句。
控制语句总览
控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。
可分成以下三类:
1. 条件判断语句也叫分支语句:if语句、switch语句;
2. 循环执行语句:do while语句、while语句、for语句;
3. 转向语句:break语句、goto语句、continue语句、return语句。
分支语句
if语句
在C中非零为真,0为假。为什么叫分支语句呢?只要if()括号里的表达式为真,就会执行对应代码,如果还有else语句的话,表达式为假时就不执行if()后面语句,而执行else后面的语句,有点像是如果xxx就xxx不然就xxx,也就像是岔路口多条分支一次只能决定一条分支的路线。
if(exp1)//exp是表达式
{
//...可以是各种语句
}
else if(exp2)
{
//...可以是各种语句
}
//...还可以有多个else if语句,相当于树多个分支
else
{
//...可以是各种语句
}
例题剖析
例题1
为什么啥也不输出呢?
注意了,if…else…算一条语句,而且else与上面离得最近的if配对,但如果有花括号相隔的话就不一样了。
即使把缩进改了也没有影响,最多影响自己读程序罢了。
善用缩进让代码对齐,利于代码的阅读理解,是良好代码风格的体现,不过也要注意单单缩进不会影响程序运行。
例题2
看看哪一种写法更好一些。
代码1什么意思呢,如果condition为真就返回1否则返回0,其实执行起来和代码2没区别,但是在读代码的时候可能会觉得是无论if内是否执行最后都要执行return 0;,忽视了return直接结束当前函数的作用。
其实把return语句换掉就不一样了:
管你if执不执行都会执行x = 5;
所以代码2逻辑更加清晰明了,不需要去估测,是什么就是什么。
例题3
再看看下面代码,写哪个更好一些?
按代码3的写法,如果漏写了一个等号,程序有可能照常运行不报错,但是这个错误有可能会影响程序逻辑,产生语义错误(简单来说就是你想的逻辑和你写出来程序的运行逻辑出现差异),关键是编译器不报错找出问题的难度大大增加了,你有可能都不会想到是这一个地方的小问题影响到整个程序的逻辑,费时费力去纠错还不一定能解决问题。
而按代码4的写法,如果漏写了一个等号,编译器马上就给你报错,一下就找到问题所在,并且可以防微杜渐。莫要到为时晚已积重难返,明明有bug就是找不出来。
对于代码3和代码4的探讨针对的是左边是不是单个变量,选用代码4风格目的是为防止由逻辑表达式变成赋值表达式,并不是说if()内的条件都要把常数放左边。
如果待比较的值是常量,可以把该常量放在左侧有助于编译器捕获错误。
因为C语言不允许给常量赋值,编译器会把赋值运算符的这种用法作为语法错误标记出来,许多经验丰富的程序员在构建比较是否相等的表达式时,都习惯常量放在左侧,还不赶快用起来!
switch语句
当switch()括号内的表达式的值满足case时,执行case后面的语句,只要满足就执行,除非遇到break跳出switch(), 可以加上default语句,当所有case不满足时,会执行default语句。
switch(整型表达式)
{
语句项;
}
语句项就是一些case语句,比如:
switch(day)
{
case 1:
x = 10;
}
switch必须搭配break才能真正实现分支,没有break的话万一有两个及以上的case满足会把它们后面的语句都执行,压根起不到分支作用。
如果表达的值与所有的case标签的值都不匹配怎么办?
其实也没什么,结果就是所有的语句都被跳过而已。
程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。
但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢? 你可以在语句列表中增加一条default子句,把下面的标签 default: 写在任何一个 case 标签可以出现的位置。
当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。 所以,每个switch语句中只能出现一条default子句。 但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
在每个 switch 语句中都放一条default子句是个好习惯。
注意事项
switch可以嵌套。
case:后面非break语句可以不止一条。
break语句在switch一次只能跳出一层switch,而且只能是目前所在的switch。
switch()括号内整型变量,整型常量,整型表达式都可以,不过不要放入布尔表达式,也就是判断表达式,比如flag == 1之类的,因为这类表达式的值只有两种:0和1,而case取值可能有很多种。
多个case对应一条执行语句,也就是在多种取值情况下执行同一条语句。
int main() { int day = 6; switch (day) { case 1: case 2: case 3: case 4: case 5: printf("周内\n"); break; case 6: case 7: printf("周末\n"); break; default: printf("bug!\n"); break; } return 0; }
一般来说都要记得在case后面加上break语句,除非特意如此。
最好最后带上一个default语句,以便在所有条件都不满足的情况下进行响应或说明。
- 如果多个不同case匹配,想执行同一个语句,可以像上面的代码那样省掉一些break语句,不过其实也可以这样:
case 1: printf("星期一\n"); printf("星期一\n"); printf("星期一\n"); printf("星期一\n"); break;
把语句都放在一个case后面执行,因为case一旦满足会一直执行,遇见break则停下。
那你看这样行不行呢?
case 1: int a = 10; printf("星期一\n"); printf("星期一\n"); printf("星期一\n"); break;
不行!
注意:不能在case和break之间定义变量,除非放在代码块里面
比如:
case 1: { int a = 10; printf("星期一\n"); printf("星期一\n"); printf("星期一\n"); } break;
其实case后面要放入多条语句的话最好都封装到函数里面去。
- case后面必须得是整型的常量或常量表达式,那么case 语句后面是否可以是const修饰的只读变量呢?
答案是:不行
比如:
int main() { const int a = 10; int b = 10; switch (b) { case a: //不行 printf("hello\n"); break; default: break; } return 0; }
- 建议按执行频率排列case语句,把最常执行的情况放在前面而把最不常执行的情况放在后面。
最常执行的语句如果放在后面的话找起来可能会比较困难,而放在前面可以很快找到。
- 将default子句只用于检查真正的默认情况
有时候,你可能剩下了最后一种情况需要处理,于是就决定把这种情况用default子句来处理,这样也许会少写一些代码,但是这样不太明智。
因为这样将失去case语句的标号所提供的自说明功能,而且也丧失了使用default子句处理错误情况的能力。
应当把每一种预期的情况都用case语句来完成,而把真正的默认情况也就是错误情况的处理交给default子句。
比如:
原版
int main() { int day = 6; 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; default: printf("周日\n"); break; } return 0; }
修改版
int main() { int day = 6; 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; default: printf("输入有误,请重新输入!\n"); break; } return 0; }
总结
1.switch语法结构中,case完成判定功能,break完成分支功能,default处理异常情况
2.当一条case对应多条执行语句时(不能定义变量),可以放在代码块{}里,但最好放在函数里实现
3.当多条case语句对应一条执行语句时,多条case后面不写break
4.default可以出现在switch种任何地方,但推荐放在结尾
5.case后面不能跟const修饰的常变量,建议要有好的case的布局
综合实例
分析如图
以上就是本文的全部内容了,感谢观看,你的支持就是对我最大的鼓励~