三篇文章让你彻底学会C语言中的分支和循环语句——(一)分支语句
文章目录
在我们正式开始学习分支语句之前,我们先来了解一下C语言中都有哪些语句,分支和循环语句又是属于其中哪一类的。
1. 语句和语句的分类
C语言的代码是由一条一条的语句构成的,在C语言中,语句可以分为以下五类:
- 空语句
- 表达式语句
- 函数调用语句
- 复合语句
- 控制语句
在这里我们要学习的分支和循环语句就属于控制语句。
这里我来简单的介绍一下控制语句:
控制语句用于控制程序的执行流程,以实现程序的各种结构方法(C语言支持的三种结构:顺序结构、选择结构、循环结构),它们由特定的语句定义符组成,C语言有九种控制语句。
可分为以下三类:
- 条件判断语句(也叫分支语句): if语句、switch语句
- 循环执行语句: do while语句、while语句、for语句
- 转向语句: break语句、goto语句、continue语句、return语句
好了,下面开始正式的分支语句的学习
2. if语句
首先,我们先来看一下if语句的执行流程图:
2.1 if
if语句的语法形式如下:
if (表达式)
语句
表达式成立(为真),则语句执行,表达式不成立(为假),则语句不执行
在C语言中,0为假,非0表示真,也就是表达式的结果如果是0,则语句不执行,表达式的结果如果不
为0,则语句执行。
下面给出一个例子来帮助你进一步理解if语句:
输入一个整数,判断是否为奇数
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num % 2 == 1)
printf("%d是奇数\n", num)
}
奇数判断的流程图:
2.2 else
如果⼀个数不是奇数,那就是偶数了,如果任意⼀个整数,我们要清楚的判断是奇数还是偶数怎么表示呢?
这里就需要if...else...
语句了,语法形式如下:
if (表达式)
语句1
else
语句2
例子:
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num % 2 == 1)
printf("%d是奇数\n", num);
else
printf("%d是偶数\n", num);
return 0;
}
2.3 分支中包含多条语句
默认情况下if
和else
语句中都只能控制一条语句
比如说下面的这串代码:
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18)
printf("成年了\n");
printf("可以谈恋爱了\n");
return 0;
}
运行上面的代码,你会发现输入的值不管是>=18 还是<18,“可以谈恋爱了” 都会打印在屏幕上。
这就是因为默认情况下if
和else
语句中都只能控制一条语句,那如果想要让if
和else
语句同时控制两条及以上条语句,怎么办呢?这里就要使用{}
将if
或者else
语句中的多条语句给括起来,使用{}
控制多条语句——这个块也叫:程序块,或者复合语句。
例如,上面的代码,就可以改为:
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age >= 18)
{
printf("成年了\n");
printf("可以谈恋爱了\n");
}
else
{
printf("未成年");
printf("禁止谈恋爱!");
}
return 0;
}
此时,运行结果如下:
2.4 嵌套if
有时候要进行连续多次的判断,这就需要用到嵌套if的方式来实现了。
例如:要求输入一个整数,判断输入的整数是0,还是正数还是负数。代码如下:
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num == 0)
printf("输入的数字是0\n");
else
{
if (num > 0)
printf("输入的数字是正数\n");
else
printf("输入的数字是负数\n");
}
return 0;
}
在这里else
语句中又嵌套了if
语句,并且在这里还有一个简化的写法,修改后的代码如下:
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num == 0)
printf("输入的数字是0\n");
else if (num > 0)
printf("输入的数字是正数\n");
else
printf("输入的数字是负数\n");
return 0;
}
将嵌套中的if
语句和上面的else合并,这样使得代码有更好的可读性,也更加美观。
除了在else
语句中嵌套if
语句外,还可以在if
语句中嵌套if
语句,比如:输入⼀个整数,如果是正数,再判断是奇数还是偶数,并输出;如果不是正数则输出:非正数。
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if(num > 0)
{
if (num % 2 == 0)
printf("偶数\n");
else
printf("奇数\n");
}
else
printf("非正数\n");
return 0;
}
以上就是嵌套if语句的语法,有了嵌套if语句,就可以完成更多复杂逻辑的判断。
2.5 悬空else问题——易错点
如果有多个 if
和 else
,可以记住这样⼀条规则, else
总是跟最接近的 if
匹配。
首先,先来看一串代码,请你想一想下面的代码的运行结果是什么?
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
此时,很多初学者可能会上来以判断 a 是 0,不等于 1 ,那就执行else 子句,打印 haha
。
但实际上当你去运行这段代码的时候,结果是:啥都没有。
有人这时候就想,这是为什么呢?
这就是悬空else
的问题,因此你可以记住这样一条规则,来防止你在这个上面出错,就是else
总是跟最近的if
匹配。
上面的代码排版,让 else
和第⼀个 if
语句对齐,让我们以为 else
是和第一个if匹配的,当 if
语句不成立的时候,自然想到的就是行else
子句,打印 haha
,但实际上 else
是和第二个 if
进行匹配的,这样后边的 if...else
语句是嵌套在第一个 if
语句中的,如果第一个 if
语句就不成立,嵌套 if
和 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;
}
只要带上适当的大括号,代码的逻辑就会更加的清晰,所以我们以后在写代码的时候要注意括号的使用,让代码的可读性更高。
3. switch语句
除了 if
语句外,C语言还提供了 switch
语句来实现分支结构。
switch
语句是⼀种特殊形式的 if...else
结构,用于判断条件有多个结果的情况。它把多重的 else if
改成更易用、可读性更好的形式。
语法形式如下:
switch (expression)
{
case value1: statement
case value2: statement
default: statement
}
上面代码中,根据表达式 expression
不同的值,执行相应的 case
分支。如果找不到对应的值,就执行 default
分支。
注:
- switch 后的 expression 必须是整型表达式
- case 后的值,必须是整形常量表达式
3.1 if 语句和 switch 语句的对比
例子:输入任意一个整数值,计算除3后的余数
使用if
语句:
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if(n % 3 == 0)
printf("整除,余数为0\n");
else if(n % 3 == 1)
printf("余数是1\n");
else
printf("余数是2\n");
return 0;
}
使用switch
语句:
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch(n % 3)
{
case 0:
printf("整除,余数为0\n");
break;
case 1:
printf("余数是1\n");
break;
case 2:
printf("余数是2\n");
break;
}
return 0;
}
使用switch语句的注意事项:
case
和后面的数字之间必须有空格- 每一个
case
语句中的代码执行完成后,需要加上break
,才能在执行完这条case
语句后直接跳出switch
语句
3.2 switch 语句中的break
如果我将刚才起那面代码中的break去掉会出现上面情况呢?
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch(n % 3)
{
case 0:
printf("整除,余数为0\n");
case 1:
printf("余数是1\n");
case 2:
printf("余数是2\n");
}
return 0;
}
当我输入9时,结果如下:
为什么会出现这种情况呢?
原因是 switch
语句也是分支效果的,只有在switch
语句中使用 break
才能在跳出 switch
语句,如果某⼀个 case
语句的后边没有 break
语句,代码会继续往下执行,有可能执行其他 case
语句中的代码,直到遇到 break
语句或者 switch
语句结束。就比如上面的代码就执行了 case1
和case2
中的语句。
所以在 switch
语句中break
语句是非常重要的,能实现真正的分支效果。
当然, break
也不是每个 case
语句都得有,这就得根据实际情况来看了。
例子:输入一个1~7的数字,打印对应的星期几
参考代码如下:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
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;
}
然后,上述代码可以变为:
输入1~7,输出的是“工作日”。输入6~7,输出的是“休息日”。
参考代码,如下:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");
break;
case 6:
case 7:
printf("休息日\n");
break;
}
return 0;
}
通过这个例子,我们可以发现在case
语句中是否使用break
应该根据实际情况来看。
3.3 switch语句中的default
在我们使用switch
语句的时候,我们可能经常会遇到一种情况,就是switch
后面的表达式的值无法和下面的case
后面的值匹配。这时候要么就不做处理,要么就可以加入default
子句。
比如前面打印星期的例子中,如果输入的值不在1~7这个范围内时,我们可以加入一个提示:输入错误
参考代码如下:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日\n");
break;
case 6:
case 7:
printf("休息日\n");
break;
default:
printf("输入错误\n");
break;
}
return 0;
}
3.4 switch语句中的case和default的顺序问题
在switch
语句中case
子句和default
子句有顺序要求吗?default
只能放在最后吗?
答案是:没有顺序要求,只要你的顺序是满足实际需求的就可以了。只不过我们通常把
default
子句放在最后。