分支语句与循环语句
什么是语句?
在C语言中,由一个分号;
隔开的一段代码就是语句,比如:
return 0;
/100 + 1 ;
/printf("a");
等都是语句.
分支语句
分支语句就是选择结构.其中最常见的关键词就是if.
那if语句的语法结构是什么样的呢?以下列举几种经常使用的结构:
1
结构1
if(表达式)
语句;
结构2
if(表达式)
语句1;
else
语句2;
结构三
if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
解释一下:
如果表达式的结果为真,则语句1执行,否则表达式2执行.
在C语言中如何表示真假呢?
0 表示假
非0表示真
这与逻辑认知下的0为假,1为真有些差池,在C语言中非0即为真.
#include <stdio.h>
int main()[
if(表达式){
语句列表1;
}
else{
语句列表2;
}
return 0;
]
这里是一个选择语句的"坑".并不是跟在if之后的else之前的所有语句都会雨露均沾的执行到.
if/else默认只执行紧接着其的第一行代码,也就是说像这样的语句列表并不会全部执行到.为了解决这个问题,我们引入代码块的概念.
这里的一对{ }
就是代码块;
用大括号{ }
包裹的一系列语句的列表就是一个代码块.
为了避免错误使用.建议读者就将代码块的使用加入平常选择结构的使用.这样习惯成自然,就完全不用纠结于到底有没有执行这个语句列表了.这也有利于好的编程习惯的养成.
悬空else
一起来看下面这行代码:
#include <stdio.h>
int main(){
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("bingo\n");
else
printf("failed\n");
return 0;
}
这里的else究竟和哪个if匹配的呢?
是不是很容易产生歧义?
这就是悬空else,难以直观的看出来if…else…结构究竟是如何配对的问题,这在C语言的初学阶段是很常见的.
- 解决方案:
1.适当的使用{ }
可以使代码的逻辑更加清晰,多用代码块.
2.代码风格的统一很重要.
以下演示一下:
#include <stdio.h>
int main(){
int a = 0;
int b = 2;
if(a == 1){
if(b == 2)
printf("bingo\n");
}
else{
printf("failed\n");
}
return 0;
}
结论:
else总是与最近的if配对.
多分支
#include <stdio.h>
int main(){
int coding = 0;
printf("你会好好敲代码吗?(选择1或0)");
if(coding == 1) {
printf("坚持,你会有好成绩");
}
else if(coding == 0){
printf("放弃回家睡大觉吧.");
}
else if(coding == -1){
printf("输入错误啦");
}
return 0;
}
简单的逻辑语句,就不多赘述了.
if书写形式的对比
- 代码一:
if(condition)
return x;
return y;
- 代码二:
if(condition){
return x;
}
else{
return y;
}
- 代码三:
int num = 1;
if(num = 5){
printf("goal");
}
- 代码四:
int num = 1;
if(5 == num){
printf("goal");
}
比较上面4个代码,其实各有利弊.
- 代码一利用了
if
不加大括号只执行紧接的第一句语句,代码看起来很整洁,但是有些新手会混淆. - 代码二就比代码一直观很多了,但是二者所陈述的内容都是一样的,加上了不必要的大括号,在实际使用上就会显得繁琐很多.
- 代码三是一串和预期效果不太相同的代码,通过分析得知
num = 5
这个语句,按寻常逻辑应该是num == 5
的比较语句,而这里因为少写了一个等号=
,就使它变成了一个赋值语句,那么这句语句再被if嵌套,他就成为了一定会判定成真的语句了.
所以一定要注意代码的严谨性. - 代码四中
5 == num
这样书写判断语句虽然可以一定程度上提升代码安全性,因为编译工具会自动检查出代码缺陷并警告,但是这样大大削减了代码的可读性,这一句"有违常理"的语句,会使人很难读懂其中的意思.
很不建议这么书写.
综上所述:
代码一 和 代码三 的书写方式建议使用
switch语句
switch语句与if语句不同的是:
switch用于多分支选择,而if适合单分支(甚至"无分枝"的简单判断)
switch(整形表达式){
语句项;
}
而什么是语句项?
是一些case语句.如下:
case 整型常量表达式:
语句;
在switch语句中,我们没法直接实现分支
搭配break使用才能实现真正的分支.这也是其精髓之处.
比如:
#include <stdio.h>
int main(){
int day = 0;
switch(day){
case 1:
printf("Monday");
break;
case 2:
printf("Tuesday");
break;
case 3:
printf("Wednesday");
break;
case 4:
printf("Thursday");
break;
case 5:
printf("Friday");
break;
case 6:
printf("Saturday");
break;
default:
printf("Sunday");
break;
}
return 0;
}
default语句就是之前的case语句都为命中时执行的语句.
循环语句
1. while
我们已经掌握了if选择语句,当条件满足的情况下,if语句后的语句执行,否则不执行.但是这个语句只会执行一次.
但是我们发现生活中很多实际的例子是:同一件事情我们要完成很多次.
那我们怎么做呢?
C语言中给我们引入了while语句,可以实现循环.
//while循环语法结构
while(表达式){
循环语句;
}
比如在屏幕上打印1-10的数字.
#include <stdio.h
int main(){
int i = 1;
while(i <= 10){
printf("%d ",i);
i++;
}
return 0;
}
break 语句
- break在循环中的作用:
其实在循环中只要遇到break,就停止后期所有的循环,直接跳出循环.
所以,while中的break是用于永久终止循环的.
continue 语句
- continue在循环中的作用:
本次continue后面的代码不会再执行,而是会直接跳转到while语句的判断部分,进行下一次循环的入口判断.
所以,while中的continue是用于终止本次循环的
2. for
我们已经知道了while循环,但是为什么还要一个for循环呢?
//for循环结构
for( 表达式1 ; 表达式2 ; 表达式3 )
循环语句;
- 表达式1为初始化部分,用于初始化循环变量的,在整个循环过程中只执行一次.
- 表达式2为条件判断部分,用于判断循环何时终止
- 表达式3为调整部分,用于更新循环变量.
[其实必要的情况下三个表达式都可省略]
用for循环在屏幕上打印1-10的数字
#include <stdio.h>
int main(){
int i = 0;
for(i = 1; i <= 10; i++){
printf("%d ",i);
}
return 0;
}
注:这里int i
写在for语句之前是C语言写法
我们看到过很多次在for语言中的写法for(int i = 0;xx;xx)
这样是C++写法
其实while中依然存在循环的三个必要条件,但是由于风格的问题使得三个部分偏离很远,这样查找修改就不够集中和方便,所以for循环更胜一筹.
for循环的使用频率也最高.
一些建议:
- 不要在for循环体内修改循环变量,防止for循环失去控制
- 建议for语句的循环控制变量的取值采用"前开后闭区间"的写法.[0 , 10)
3. do…while
//do...while语句格式
do
循环语句;
while(表达式);
特点: 循环至少执行一次,使用的场景很局限.这里就不过多讲解了.
4. goto语句
goto本来不是为了循环而诞生的,但是与标签配合标记跳转可以实现循环,实践中没有goto语句也可以很容易的写出代码,一般不会使用goto,除非一些"必要情况".
- 必要情况
->最常见的用法就是终止程序在某些深度嵌套的结构的处理过程,例如一次跳两层或多层循环.
这样的情况使用break是达不到目的的,它只能从最内层退出到上一层的循环.而goto就可以直接跳转出去.
for(...){
for(...){
for(...){
if(disaster)
goto error;
}
}
}
error:
if(disaster)
//处理错误情况
goto这样循环语句中的"旁门左道",还是建议大家尽量不要采纳,