C语言 中的 选择语句:if 和 switch(第7篇)

慢慢来,比较快


推荐书籍:《高质量的 C++ / C 编程》 作者:林锐 博士(主要就是学习写代码的格式,要养成好的习惯)

必备常识

(1) 0 表示 假;非0 表示 真
(2) n 是变量,‘n’ 是 字符常量,即 整形常量(二-(1)-4-第二种 有介绍为什么强调这个知识点)


一、什么是语句?

C语句 可以分为以下 5类:

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

本章后面介绍的是 控制语句

控制语句用于控制程序的执行流程,以实现程序的各种结构方式(C语言支持三种结构:顺序结构、选择结构、循环结构),它们由特定的语句定义符组成,C语言有 九种 控制语句。

可以分成以下 三类:

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

二、if 语句

(1)知识点 1

if else 后面是可以带 “{ }” 的,如果不带,只能控制紧挨着的一条语句。

int main()
{
	int age = 20;
	
	if (age >= 18)
		printf("成年\n");
	else
		printf("未成年\n");
	printf("不能谈恋爱\n");         
	                         当age=20时,输出结果:成年,不能谈恋爱,(错误)
	return 0;                体现了:if else 只能控制紧挨着的一条语句
}

改正之后:

int main()
{
	int age = 20;
	
	if (age >= 18)
		printf("成年\n");
	else
	{
		printf("未成年\n");
		printf("不能谈恋爱\n");     输出结果:成年  (正确)
	}
	
	return 0;
}

(2)知识点 2

if ()
else if ()
else if ()
else

经典错误

int main()
{
	printf("请输入你的年龄:");
	int age = 0;
	scanf("%d",&age);
	if (age <= 18)
	{
		printf("少年");
	}
	else if(18<=age<=26)         错误点:18 <= age <= 26
	{                            原因:18 <= 50 结果为 1 
		printf("青年");                1< 26  恒成立,因此输出结果错误
	}                            改正:age >= 18 && age <= 26
	else
	{
		printf("你老了");        当输入 50 时,输出结果:青年  (错误)
	}                            
	return 0;
}

当输入 50 时,输出结果:青年 (错误)
错误点:18 <= age <= 26
原因:18 <= 50 结果为 1 ;1< 26 恒成立,因此输出结果错误
改正:age >= 18 && age <= 26

int main()
{
	printf("请输入你的年龄:");
	int age = 0;
	scanf("%d", &age);
	if (age <= 18)
	{
		printf("少年");
	}
	else if (age >= 18 && age <= 26)
	{                            
		printf("青年");           当输入 50 时,输出:你老了    (正确)    
	}                            
	else
	{
		printf("你老了");      
	}
	return 0;
}

(3)知识点 3 :悬空 else

应该养成好的代码风格;勤用 " { } "

int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
		if (a == 1)
			printf("hehe\n");
		else
			printf("haha\n");         输出结果:什么都不输出
	return 0;
}

请问:以上代码输出结果什么?
答:什么都不输出
原因:else 只和与之离得最近的 if 匹配

改正:

int main()
{
	int a = 0;
	int b = 2;
	if (a == 1)
	{
		if (a == 1)
			printf("hehe\n");         勤用 "{ }"
	}
	else
	{
		printf("haha\n");
	} 
	return 0;                         输出结果:haha
}

(4)知识点 4 :if 书写形式的对比

代码 1 (不建议这么写代码!)

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

当满足 condition 条件之后,会执行 return x , return x 之后的语句就不会再执行了

代码 2

if (condition)
	{
		return x;
	}
	else
	{
		return y;
	}
比较 代码 1 和 代码 2 ,得出结论

答:代码 1 和 代码 2 效果是 一样的
当满足 condition 条件之后,会执行 return x , return x 之后的语句就不会再执行了。

int test()
{
	if (1)
		return 0;
	printf("输出了吗\n");
	return 1;
}

int main()
{
	test();
	return 0;
}

当 按 F10 进行 逐过程 调试 的时候,行号左边黄色的箭头指向 test( ),紧接着按 F11 进行 逐语句 调试,见第二张图片 行号左边的 黄色箭头

在这里插入图片描述
发现,当程序进入 test( )函数内 进行 逐语句调试 的时候,
只执行了
if(1)
return 0;
这两条语句,后面的语句直接跳过了,也就是 printf(“输出了吗\n”); return 1;这两句话跳过了。
这证实了 代码1 的结论:当满足 condition 条件之后,会执行 return x , return x 之后的语句就不会再执行了。

在这里插入图片描述
printf(“输出了吗\n”);
return 1;
这两条语句不被执行。

在这里插入图片描述

根据 代码1 和 代码2 举例子
test()
{
	if (0)
		return 0;                  test() 只执行 return 1;
	return 1;
}
int main()
{
	printf("%d\n", test());        输出结果为:1
	return 0;
}

代码 3

int num = 1;
if (num == 5)                判断 num 的值 是否等于5
{
	printf("hehe\n");
}
代码 3 的 经典错误**
int main()
{
	int num = 1;
	if (num = 5)             错误之处:将 num 赋值为 5
	{                                 这使得 (num = 5)永远为 真 !!!
		printf("hehe\n");
	}
	return 0;                始终输出 hehe
}

错误原因:
(num = 5) ,将 num 赋值为 5 ,使得永远为真,这是错误的原因

代码 4(可以有效避免 代码 3 的错误)

int main()
{
	int num = 1;
	if (5 == num)            这么写,可以巧妙的避开 赋值
	{
		printf("hehe\n");
	}
	return 0;
}

if (5 == num)
这么写,可以巧妙的避开 赋值

(5)练习题

题目1:判断一个数是否为 奇数

方法一
void test(int x)
{
	if (x % 2 == 1)
	{
		printf("%d是奇数", x);
	}
	else
	{
		printf("%d是偶数", x);
	}
}

int main()
{
	int a = 0;
	scanf("%d",&a);
	test(a);
	return 0;
}
方法二
int main()
{
	int i = 0;
	for (i = 1; i <= 100; i += 2)
	{
		printf("%d\n", i);
	}
	return 0;
}

题目2:输出1~100之间的 奇数

void test(int x)
{
	if (x % 2 == 1)
	{
		printf("%d是奇数\n", x);
	}
	else
	{
		printf("%d是偶数\n", x);
	}
}

int main()
{
	int a = 1;
	while (1 <= a && a <= 100)
	{
		test(a);
		a++;
	}
	return 0;
}

遇到的困惑,记录如下

我想 多组输入 数据来判断 奇偶性。

我第一次写的程序
int test(int x)              这里有问题,而且,这个程序不是 多组输入,仅仅只是 单词输入
{
	if (x % 2 == 1)          要么有 返回值,要么改成 void
		printf("是奇数\n");
	else
		printf("偶数\n");
}

int main()
{
	int a = 0;
	scanf("%d", &a);
	test(a);
	return 0;
}

仅仅只是 单次输入,不满足 多组输入

在这里插入图片描述

第二次听取老师的批改,更改的代码如下:
void test(int x)
{
	if (x % 2 == 1)
		printf("是奇数\n");
	else
		printf("偶数\n");
}

int main()
{
	int a = 0;
	scanf("%d", &a);
	while (scanf("%d", &a) != EOF)
	{
		test(a);
	}
	return 0;
}

又出现问题,为什么 我的 第一组数据 输入12,程序不进行判断 奇偶性呢?

答:在这里插入图片描述
那是因为,我这块有两个输入,第一个12对应着第一个scanf(“%d”,&a);

第二个12对应着 while(scanf(“%d”,&a)!=EOF)中的scanf(“%d”,&a),这就是为什么我的第一个12,程序不进行判断。
在这里插入图片描述

正确的程序如下:

scanf函数 的注意点和 scanf函数 一样。值得好好学习。

总结:还是要多敲代码,多做题目,才能发现自己在学习这个知识点的短板在哪里!!!

void test(int x)
{
	if (x % 2 == 1)
		printf("是奇数\n");
	else
		printf("偶数\n");
}

int main()
{
	int a = 0;
	while (scanf("%d", &a) != EOF)             这个知识点跟 printf函数 一样
	{
		test(a);
	}
	return 0;
}

在这里插入图片描述

三、switch 语句

(1)switch 和 case

1、switch

switch(整型表达式)
{
语句项;
}

2、case

case 整形常量表达式;
语句;

没有 break
int main()
{
	int day = 0;
	printf("请输入数字:");
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		printf("礼拜1\n");               没有 break
	case 2:
		printf("礼拜2\n");
	case 3:
		printf("礼拜3\n");
	case 4:
		printf("礼拜4\n");
	case 5:                              输入的数字是几,就从这个数字开始
		printf("礼拜5\n");
	case 6:
		printf("礼拜6\n");
	case 7:
		printf("礼拜7\n");
	}
	return 0;
}

在这里插入图片描述

有 break
int main()
{
	int day = 0;
	printf("请输入数字:");
	scanf("%d", &day);
	switch (day)
	{
	case 1:
		printf("礼拜1\n");  
		break;break
	case 2:
		printf("礼拜2\n");
		break;
	case 3:
		printf("礼拜3\n");
		break;
	case 4:
		printf("礼拜4\n");
		break;
	case 5:
		printf("礼拜5\n");
		break;
	case 6:
		printf("礼拜6\n");
		break;
	case 7:
		printf("礼拜7\n");
		break;
	}
	return 0;
}

在这里插入图片描述

3、深刻理解switch (整形表达式)

第一种
int main()
{
	double day = 0;                注意:double  不满足 整形表达式 
	printf("请输入数字:");
	scanf("%lf", &day);
	switch (day)                   注意:double  不满足 整形表达式
	{
	case 1:
		printf("礼拜1\n");
		break;
	case 2:
		printf("礼拜2\n");
		break;
	case 3:
		printf("礼拜3\n");
		break;
	case 4:
		printf("礼拜4\n");
		break;
	case 5:
		printf("礼拜5\n");
		break;
	case 6:
		printf("礼拜6\n");
		break;
	case 7:
		printf("礼拜7\n");
		break;
	}
	return 0;
}

在这里插入图片描述

第二种

n 是变量,
‘n’ 是 字符常量,即 整形常量

int main()
{
	char day = 'a';
	printf("请输入字母:");
	scanf("%c", &day);
	
	switch (day)
	{
	case 'a':
		printf("礼拜1\n");
		break;
	case 'b':
		printf("礼拜2\n");
		break;
	case 'c':
		printf("礼拜3\n");
		break;
	case 'd':
		printf("礼拜4\n");
		break;
	case 'e':
		printf("礼拜5\n");
		break;
	case 'f':
		printf("礼拜6\n");
		break;
	case 'g':
		printf("礼拜7\n");
		break;
	}
	return 0;
}

在这里插入图片描述

4、深刻理解case (整形常量表达式)

第一种
int main()
{
	int day = 0;
	printf("请输入数字:");
	scanf("%d", &day);
	int a = 1;
	int b = 2;
	int c = 3;
	int d = 4;
	int e = 5;
	int f = 6;
	int g = 7;
	switch (day)
	{
	case a:
		printf("礼拜1\n");
		break;
	case b:
		printf("礼拜2\n");
		break;
	case c:
		printf("礼拜3\n");
		break;
	case d:
		printf("礼拜4\n");
		break;
	case e:
		printf("礼拜5\n");
		break;
	case f:
		printf("礼拜6\n");
		break;
	case g:
		printf("礼拜7\n");
		break;
	}
	return 0;
}

在这里插入图片描述

第二种

n 是变量,
‘n’ 是 字符常量,即 整形常量

int main()
{
	char day = 'a';
	printf("请输入字母:");
	scanf("%c", &day);
	
	switch (day)
	{
	case 'a':
		printf("礼拜1\n");
		break;
	case 'b':
		printf("礼拜2\n");
		break;
	case 'c':
		printf("礼拜3\n");
		break;
	case 'd':
		printf("礼拜4\n");
		break;
	case 'e':
		printf("礼拜5\n");
		break;
	case 'f':
		printf("礼拜6\n");
		break;
	case 'g':
		printf("礼拜7\n");
		break;
	}
	return 0;
}

在这里插入图片描述

(2) 在 switch 语句中的 break

1、“break” 只能跳出 ”一层循环“

举例:for 循环中嵌套 for 循环,则 break 只跳出一个 for 循环

2、"break 实际效果是:把语句列表划分成不同的部分

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

3、能最好的理解 break 的例子

题目要求:(1)输入 1~5 输出的是"weekday";(2) 输入 6~7输出"weekend"
int main()
{
	int a = 0;
	printf("请输入数字:\n");
	scanf("%d", &a);

	switch (a)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("weekday\n");
		break;
	case 6:
	case 7:
		printf("weekend\n");
		break;
	}
	return 0;
}

(3) switch 允许嵌套使用!!!也能更好的理解 break 这道题,我一开始是做错的!!! break 一次只能跳出 一层 switch 语句。

int main()
{
	int  n = 1;
	int m = 2;
	switch (n)
	{
	case 1:
		m++;
	case 2:
		n++;
	case 3:
		switch(n)
		{
		case 1:
			n++;
		case 2:
			m++;
			n++;
			break;                跳出第二个 switch 
		}
	case 4:
		m++;
		break;                    跳出第一个 switch
	default:
		break;
	}
	printf("m = %d,n = %d\n", m, n);
	return 0;
}

在这里插入图片描述

(4) default 子句

每个 switch 语句只能出现一条 default 语句
default: 写在任何一个 case 标签可以出现的地方
每个 switch 语句只能出现一条 default 语句,并且,它可以出现在语句列表的任何位置,而且语句会像贯穿一个 case 标签一样贯穿 default 子句。

int main()
{
	int a = 0;
	printf("请输入数字:\n");
	scanf("%d", &a);

	switch (a)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("weekday\n");
		break;
	case 6:
	case 7:
		printf("weekend\n");
		break;
	default:
		printf("请输入7以内的数字\n");
		break;
	}
	return 0;
}
int main()
{
	int a = 0;
	printf("请输入数字:\n");
	scanf("%d", &a);

	switch (a)
	{
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
		printf("weekday\n");
		break;
	default:                                     default 语句可以放在任何 case 可以放的地方
		printf("请输入7以内的数字\n");
		break;
	case 6:
	case 7:
		printf("weekend\n");
		break;
	
	}
	return 0;
}

在这里插入图片描述

1、 可以比较好理解 default 的例子

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

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值