8. C 语言 -- 分支结构: switch 和 break 语句

本博客主要内容为 “小甲鱼” 视频课程《带你学C带你飞》【第一季】 学习笔记,文章的主题内容均来自该课程,在这里仅作学习交流。在文章中可能出现一些错误或者不准确的地方,如发现请积极指出,十分感谢。
也欢迎大家一起讨论交流,如果你觉得这篇文章对你有所帮助,记得评论、点赞哦 ~(。・∀・)ノ゙

1. switch 和 break 语句

  处理多分支结构,可以考虑使用语法更简便的 switch 语句,如下所示

…… // 其它语句
switch (表达式)
{
    case 常量表达式1: 语句或程序块
    case 常量表达式2: 语句或程序块
    ……
    case 常量表达式n:语句或程序块
    default: 语句或程序块 
}
…… // 其它语句

这里每个 case 后边的常量是匹配 switch 后边表达式的值,case 后边必须跟一个常量值,而不能是一个范围,如果所有的 case 均没有匹配的,那么执行 default 的内容,default 是可选的,如果没有 default,并且所有的 case 均不匹配,那么 switch 语句不执行任何动作。它与 if else 相比的好处在于它更简洁,会少些很多的大括号。

  但是直接像上面那么书写程序是容易出现问题的,因为switch 语句中的 case 和 default 事实上都是“标签”,用来标志一个位置而已。当 switch 跳到某个位置之后,就会一直往下执行,比如说它满足了 case 常量表达式1 的要求之后会自动执行剩下的所有的语句和程序块,而无需判断是否满足前面所对应的 case 。所以如果只希执行某一个 case 后面的语句和程序块,还需要配合一个 break 语句,让代码在适当的位置跳出 switch,即如下所示

…… // 其它语句
switch (表达式)
{
    case 常量表达式1: 语句或程序块1;  break;
    case 常量表达式2: 语句或程序块2;  break;
    ……
    case 常量表达式n:语句或程序块n;  break;
    default: 语句或程序块n+1;  break; 
}
…… // 其它语句

1.1 举例说明

  下面的例子实现了一个功能,输入成绩的评定结果(A,B,C)中的一个,返回其所对应的分数区间

#include 

int main()
{
	char ch;

	printf("请输入成绩:");
	scanf("%c", &ch);

	switch (ch){
		case 'A': printf("你的成绩在90分以上!\n"); break;
		case 'B': printf("你的成绩在80~90分之间!\n"); break;
		case 'C':printf("你的成绩在60分以下!\n"); break;
		default: printf("请输入有效的成绩评级!\n"); break;
	}

	return 0;
}

如果我们假定我们输出的是 B,程序输出的结果为

请输入成绩:B
你的成绩在8090分之间!

2. 分支结构的嵌套

  如下图所示,在一个 if 语句中包含另一个 if 语句,我们就称之为 if 语句的嵌套,也叫分支结构的嵌套。

8. C 语言 -- 分支结构: switch 和 break 语句_第1张图片

  比如说我们尝试编写下面的流程图的程序

8. C 语言 -- 分支结构: switch 和 break 语句_第2张图片

其中流程图所代表的含义很简单,首先判断输入的两个数 a b 是否相等,相等输出 a = b;否则判断 a 是否大于 b,如果大于 b 的话输出 a > b,否则输出 a < b,具体程序如下

#include 

int main()
{
	int a, b;

	printf("请输入两个数:");
	scanf("%d %d", &a, &b);

	if (a != b){
		if (a > b){
			printf("%d > %d\n", a, b);
		}
		else{
			printf("%d < %d\n", a, b);
		}
	}
	else{
		printf("%d = %d\n", a, b);
	}

	return 0;
}

3. 悬挂else

  在 C 语言中,else 始终与距离他最近的 if 相对应,考虑如下的代码

……
if (x == 0)
    if (y == 0)
        error();
else
    z = x + y;
……

这段代码中编程者的本意是应该有两种主要情况,x 等于 0 以及 x 不等于 0。对于 x 等于 0 的情形,除非 y 也等于 0(此时调用 error 函数),否则程序不作任何处理;对于 x 不等于 0 的情形,程序将 x 与 y 之和赋值给 z。

  然而,这段代码实际上所做的却与编程者的意图相去甚远。原因在于 C 语言中有这样的规则,else 始终与同一对括号内最近的未匹配的 if 结合。如果我们按照上面这段程序实际上被执行的逻辑来调整代码缩进,大致是这个样子:

……
if (x == 0)
    if (y == 0)
        error();
    else
        z = x + y;
……

也就是说,如果 x 不等于 0,程序将不会做任何处理。如果要得到原来的例子中由代码缩进体现的编程者本意的结果,应该这样写:

……
if (x == 0)
{
    if (y == 0)
    {
        error();
    }
}
else
{
    z = x + y;
}
……

现在,else 与第一个 if 结合,即使它离第二个 if 更近也是如此,因为此时第二个 if 已经被括号“封装”起来了。所以在编写多层循环嵌套的代码的时候,建议使用 {} 将对应的部分括起来,尤其是使用习惯了python 的同学,千万不要根据缩进来判断 else 与那部分相对应。

4. 等于号带来的问题

  在 C 语言中使用等号(=)作为赋值运算,使用连续两个等号(==)作为比较运算。一般而言,赋值运算相对于比较运算出现得更频繁,因此字符较少的 = 就被赋予了更常用的含义——赋值操作。此外,在 C 语言中赋值符号被作为一种操作符对待,因而重复进行赋值操作(如 a = b = c)可以很容易地书写,并且赋值操作还可以被嵌入到更大的表达式中。

  但是,这种使用上的便利性可能导致一个潜在的问题:当程序员本意是在作比较运算时,却可能无意中误写成赋值运算。比如下例,该语句本意似乎是要检查 x 是否等于 y :

if (x = y)
    break;

而实际上是将 y 的值赋给了 x ,然后检查该值是否为零。这样的判断距离我们原始想要的相差甚远。

  虽然判断两个变量是否相等只能靠程序员本身来注意,但是判断一个变量是否与一个常数值相等却可以有一个叫好的防范方法。比如说我们需要判断变量 a 的值是否等于 1,可以采用如下的写法

if (1 == a)
{
    prinft("Yes\n");
}

如果没有写成判断之是否相等,而是写成了赋值符号,那么一定会报错的,因为一个常量是没有办法被赋值的。

参考

[1] “小甲鱼” 视频课程《带你学C带你飞》【第一季】P12

欢迎大家关注我的知乎号(左侧)和经常投稿的微信公众号(右侧)
8. C 语言 -- 分支结构: switch 和 break 语句_第3张图片

你可能感兴趣的:(C,从零入门C语言!!!)