Bootstrap

【C语言分支语句】if & switch详解

上期把整个一块的初始C语言部分介绍完毕了,就是不知道大家有没有耐心看完,如果没有请认真看完,请戳:初始C语言三万字高质量,对构建C语言的知识体系帮助很大。


1.什么是语句

C语句可以分为五类

  1. 表达式语句
  2. 函数调用语句
  3. 控制语句
  4. 复合语句
  5. 空语句

控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。

结构方式:顺序结构、分支(选择)结构和循环结构。

可分为以下三类:

  1. 条件判断语句也叫分支语句:if和switch语句;
  2. 循环执行语句:for、while和do while语句;(下期介绍 )
  3. 转向语句:break、goto、continue和return语句。

2.分支语句

如果你好好学习,校招时拿一个好offer,走上人生巅峰。
如果你不学习,毕业等于失业,回家卖红薯。
这就是选择!
在这里插入图片描述

我们人生中处处面临着选择。

2.1 if语句

那if语句的语法结构是怎么样的呢?

写法和语法结构
第一种:

//如果表达式的值为真那么语句就要被执行
if(表达式)
{
	语句;
}

第二种:

//如果if表达式为真执行if
//否则就执行else
if(表达式)
{
	语句1;
}
else
{
	语句2;
}

第三种(多分支):

//有时候不光会有一种或两种选择
//当有多种选择的情况可采用这种结构
if(表达式)
{
	语句1;
}
else if(表达式)
{
	语句2;
}
else
{
	语句3}

注意:如果只跟着一条语句可以不加大括号,不加默认只跟着下面一条语句。但是只要超过一条语句就是代码块了这样就必须要加上大括号,避免bug的出现。
建议无论几条都加上大括号这样可以增加代码的可读性和养成良好的代码风格。

对每种情况进行举例说明。
第一种:

#include <stdio.h>
int main()
{
	//判断表达式
	if(3 == 5)
	{
		puts("打不打印这句话?");
	}
	return 0;
}
执行后控制台会输出这句话吗?

运行结果:
在这里插入图片描述
什么都没输出,原因不难看出,因为3不等于5,判断表达式为假,不执行if里的语句。如果把表达式改为3 == 3,表达式为真,将会执行if里的语句。

第二种:

int main()
{
	int age = 10;
	if(age >= 18)
	{
		puts("成年");
	}
	else
	{
		puts("未成年");
	}
	//会执行哪条语句?
}

把age的值带入if表达式,10 >= 18,表达式为假,执行else下的语句,所以屏幕会输出:未成年。

第三种:

int main()
{
 	int age = 0;
    scanf("%d", &age);
    if(age<18)
   {
        puts("少年");
   }
    else if(age>=18 && age<30)
   {
        puts("青年");
   }
    else if(age>=30 && age<50)
   {
          puts("中年");
   }
    else if(age>=50 && age<80)
   {
        puts("老年");
   }
    else
   {
        puts("老寿星");
   }
}

运行结果:
在这里插入图片描述
解释一下:
如果表达式的结果为真,则语句执行。
在C语言中如何表示真假?

0表示假,非0表示真。

注意:if语句里所有分支只会执行一个分支里的语句。

2.1.1 悬空的else

来看看下面这段你写的代码(doge) :

#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匹配的,是和第二个if匹配,这两个合起来才是一个if else语句。
在这里插入图片描述
所以应该是这样对齐的。这个时候再看a是0,第一个表达式0 == 1 为假,所以根本不会执行下面的if else语句,因此屏幕上什么都没打印

这样看这种代码还是很坑的,举这个例子是为了说明代码风格的重要性,如果刚开始就写成第二种的代码,就不容易看错了。

那还有没有更直观的写法?

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和第一个if匹配该怎么做?

int main()
{
    int a = 0;
    int b = 2;
    if(a == 1)
    {
        if(b == 2)
            printf("hehe\n");
    }
    else
        printf("haha\n");
    return 0;
}
这样就是和第一个if匹配了

代码风格问题不仅仅上面这些,还比如:变量的命名(有意义,规范)、空格、空行和换行等等

2.1.2 if书写形式的对比

下面这段代码的意思是条件满足返回x不满足返回y吗?

if (condition )
{
    return x;
}
return y;

.
.
.
.
.
答:是的
这中写法是不是在阅读上给你带来了一些困扰?如果是说明这段代码写的不好。

把上面这段代码改一下:

if(condition)
{
    return x;
}
else
{
   return y;
}

这样写起来就很容易来阅读。

2.1.3 练习

建议自己先想一想,敲一敲。

  1. 判断一个数的奇偶
  2. 输出1-100之间的奇数
    在这里插入图片描述

第一题:

int main()
{
	int a = 0;
	scanf("%d", &a);
	//判断条件想一下
	//奇数除以2会余一
	///所以取余运算符
	if(a % 2 == 1)
	{
		printf("%d是奇数\n", a);
	}
	else
	{
		printf("%d是偶数\n", a);
	}
	return 0;
}

第二题:
在上一期只介绍了while循环,那我们就用while。

int main()
{
	int i = 1;
	while(i <= 100)
	{
		if(i % 2 == 0)
		{
			printf("%d ", i);
		}
		i++;
	}
	return 0;
}
还可以优化代码吗

2.2 switch语句

switch语句也是一种分支语句。
常常用于多分支的情况。

如果:
输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六
输入7,输出星期日

那我没写成 if…else if …else if 的形式太复杂,那我们就得有不一样的语法形式。

因此便出现了switch语句。
写法和语法结构:

switch(整型表达式)
{
    case 整形常量表达式:
    语句;
}

把例子用switch来实现:

int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		puts("星期1");
	case 2:
		puts("星期2");
	case 3:
		puts("星期3");
	case 4:
		puts("星期4");
	case 5:
		puts("星期5");
	case 6:
		puts("星期6");
	case 7:
		puts("星期7");
	}
}

这样输出的结果是正确的吗?
在这里插入图片描述
确实打印了我们想要的数据,但为什么会把下面的日期也输出了呢?

注意:case只是决定了入口,并不能决定从哪出去,所以就一直往下面打印直到结束


2.2.1 switch中的break

解释下switch语句的原理:switch首先根据后面括号里表达式的值,决定它从哪个case语句进去一直往下执行,会一直执行到最后。如果想跳出去,是有一个专门的跳转语句:break,遇到break会直接跳出switch语句。
所以在每个case里都加上break在执行的结果:
在这里插入图片描述

注意:switch括号里必须为整形表达式。 case是整形常量表达式,也可以是字符,字符是以ASCII码值存储的也是整形。

这时要求变了:

  1. 输入1-5,输出的是“weekday”;
  2. 输入6-7,输出“weekend”;

想一想该怎么做?

在这里插入图片描述

int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		puts("weekday");
		break;
	case 6:
	case 7:
		puts("weekend");
		break;
	}
//应该有不少小伙伴都是把case1-5依次改成weekday吧
}

编程好习惯:

在最后一个 case 语句的后面加上一条 break语句。 (之所以这么写是可以避免出现在以前的最后一个 case 语句后面忘了添加break语句)。

2.2.2 default子句

上面的例子的值有效范围在1~7,那如果不小心输入了个8等无法和case的标签匹配的值,这该怎么办?

这时就可以使用default子句:当所有case无法匹配的时候,就会执行default语句。

还是拿上面的代码:

int main()
{
	int day = 0;
	scanf("%d", &day);
	switch (day)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		puts("weekday");
		break;
	case 6:
	case 7:
		puts("weekend");
		break;
	default:
		puts("输入错误");
		break;
	}

运行结果:
在这里插入图片描述

每个switch语句中只能出现一条default子句,但是它可以出现在语句列表的任何位置。

2.2.3 练习

结合所学仔细想想答案是什么:

int main()
{
    int n = 1;
    int m = 2;
    switch (n)
   {
    case 1:
            m++;
    case 2:
            n++;
    case 3:
            switch (n)
           {
             //switch允许嵌套使用
             case 1:
                    n++;
             case 2:
                    m++;
                    n++;
                    break;
           }
    case 4:
            m++;
            break;
    default:
            break;
   }
    printf("m = %d, n = %d\n", m, n);
    return 0;
}

在这里插入图片描述
答案是:m = 5,n = 3。画图解释:
在这里插入图片描述
仔细看,并且要注意break在switch里的作用(只能跳出当前switch语句)。


总结

以上就是对分支(选择)语句if和switch的探究和学习。本篇的目的是:理解分支语句的概念,掌握if和switch各自的代码格式和else、break分别在代码里的作用并且可以写出简单的代码。

里面很多的小坑也需要认真对待。

码字不易,兄弟们点赞支持一下,我们下期再见,拜~
在这里插入图片描述

下期预告:循环语句


;