分支和循环(中)

4、逻辑操作符:&& ,|| !

逻辑操作符提供逻辑判断功能,逻辑操作符可用于构建更复杂的表达式,逻辑操作符主要有如下三个:

(1)!:逻辑取反运算符(改变单个表达式的真假)

(2)&&:与运算符,就是并且的意思(两侧的表达式只有都为真时,才为真;只要有一个为假,就为假)

(3)||:或运算符,就是或者的意思(两侧至少有一个表达式为真,则为真,否则为假)

注意:逻辑操作符的结果也是0或1

4.1逻辑取反运算符!

逻辑取反运算符!是一个单目操作符(即:只有一个操作数)

a !a

非0 0

0 1

逻辑取反运算符想要表达的意思是,如果一个表达式a为真,那么取反即:!a,则!a为假。

示例:有一个变量叫flag,如果flag为假,则输出I am a student,此时代码就可以这样写:

如果flag为真,!flag就是假;如果flag为假,则!flag为真

4.2 &&与运算符

a b a&&b

非0 非0 1

非0 0 0

0 非0 0

0 0 0
&&就是与运算符,是并且的意思,&&是一个双目运算符,使用的方式是:a&&b,&&两边的表达式都是真的时候,整个表达式才为真,只要有一个为假,则整个表达式为假。

示例:月份是3月到5月,是春季,代码实现为:

cpp 复制代码
//逻辑操作符:&&(与)
#include<stdio.h>
int main()
{
	int month = 0;
	scanf("%d", &month);
	if (month >= 3 && month <= 5)
	{
		printf("春季\n");
	}
	return 0;
}

上述代码表示的意思是:month既要大于等于3,也要小于等于5,二者必须同时满足。

4.3或操作符||

a b a ||b

非0 非0 1

非0 0 1

0 非0 1

0 0 0
||就是或运算符,是或者的意思,||也是一个双目操作符,使用的方式是:a||b

两边的表达式只要有一个是真,整个表达式就是真,两边的表达式都为假的时候,才为假

示例:月份是12月或者1月或者2月是冬季,代码实现为:

cpp 复制代码
//逻辑操作符:||(或)
#include<stdio.h>
int main()
{
	int month = 0;
	scanf("%d", &month);
	if (month ==12  || month==1 ||month==2)
	{
		printf("冬季\n");
	}
	return 0;
}

4.4短路

C语言逻辑运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是可以保证的。

如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值,这种情况称为"短路"。

如上面写的代码:

if(month>=3 && month<=5)

表达式中&&的左操作数是month>=3,右操作数为:month<=5.当左操作数month>=3的结果是0的时候,即使不判断month<=5,整个表达式的结果也是0(因为:对于&&,只有左操作数和右操作数同时为真的时候,结果才为真;左右操作数只要有一个为假,结果就为假)

因此,对于&&操作符来说,左边操作数的结果是0的时候,右边操作数就不再执行

对于||操作符同样也存在"短路"现象,

如上面写的代码:

if(month==12 ||month ==1 ||month==2)

如果month==12则不用再判断month是否等于1或者2,此时整个表达式的结果就是1(因为:对于||操作符而言,只要左右操作数有一个为真,则整个表达式结果就为真,只有左右操作数都为假的时候,整个表达式的结果才为假)

综合案例:

cpp 复制代码
//逻辑运算符的短路现象
#include<stdio.h>
int main()
{
	int i = 0;
	int a = 0;
	int b = 2;
	int c = 3;
	int d = 4;
	i = a++ && ++b && d++;
	printf("a=%d b=%d c=%d d=%d", a,b,c,d);
	return 0;
}

结果:

结果分析:

因为a++是后置++,所以是:先使用,后+1,则此时a++为0,为假,此时因"短路"现象,则表达式:a++ && ++b &&d++表达式的结果就是0,

所以该表达式的++b,d++就不会执行。于是结果如上图所示。

5、switch语句

C语言中,除了if语句实现分支结构外,还提供了switch语句来实现分支结构

switch语句是一种特殊形式的if...else结构,用于判断条件有多个结果的情况。它把多重的else if改成更易用、可读性更好的形式。

语法格式:

switch (expression){

case value1: statement

case value2:statement

...

default: statement

}

上面代码中,根据表达式expreesion不同的值,执行相应的case分支。如果找不到对应的值,就执行default分支

注意:

(1)switch后的expression必须是整型表达式

(2)case后的值,必须是整型常量表达式

switch只能用于整型和字符型数据(因为字符型数据都有ASCII码值)

5.1if语句和switch语句的对比

案例:输入一个int型数据,计算模3(即:%3)之后的余数

用if语句实现代码:

cpp 复制代码
//if语句实现:输入一个int型数据,计算模3(即:%3)之后的余数
#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	if (n %3== 0)
	{
		printf("余数为0\n");
	}
	else if (n % 3 == 2)
	{
		printf("余数为2\n");
	}
	else
	{
		printf("余数为1\n");
	}
	return 0;
}

结果举例:

用switch语句实现:

cpp 复制代码
//switch语句实现:输入一个int型数据,计算模3(即:%3)之后的余数
#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	switch (n % 3)
	{
	case 0:
		printf("余数为0\n");
		break;
	case 1:
		printf("余数为1");
		break;
	case 2:
		printf("余数为2");
		break;
	}
	return 0;
}

结果举例:

上述switch代码,我们需要注意:

(1)case和后边的数字之间必须有空格

(2)每一个case语句中的代码执行完成后,需要加上break,才能跳出switch语句

5.2switch语句中的break

如果去掉上述switch语句中的break会发生什么呢?如下述代码所示:

cpp 复制代码
//switch语句实现:输入一个int型数据,计算模3(即:%3)之后的余数
#include<stdio.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	switch (n % 3)
	{
	case 0:
		printf("余数为0\n");
		break;
	case 1:
		printf("余数为1");
	case 2:
		printf("余数为2");
		break;
	}
	return 0;
}

结果:

当输入7时,预期结果是:余数为1,那我什么结果是:余数为1余数为2呢?原因是:switch语句也是有分支效果的,只有在switch语句中使用break才能跳出switch语句,如果某一个case语句的后边没有break语句,代码会继续往下执行,这时有可能执行其他case语句中的代码,直到遇到break语句或者switch语句结束,比如上面的这个代码

所有在switch语句中break语句是非常重要的,能实现真正的分支效果。

具体来说,break也不是每一个case语句都要有,这就得根据实际情况来看。

比如:输入:1~5的数字,输出的是"工作日";输入:6~7的数字,输出"休息日"

代码:

cpp 复制代码
//输入:1~5的数字,输出的是"工作日";输入: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;
}

结果举例:

5.3switch语句中的default

在使用switch语句的时候,我们经常遇到一种情况,比如:switch语句后的表达式中的值无法匹配代码中的case语句的时候,这时候要不就不做处理,要不就得在switch语句中加入default子句。

switch (expression){

case value1: statement

case value2:statement

default: statement

}

switch后边的expression的结果不是value1,也不是value2的时候,就会执行default子句。

在这个案例"输入:1~5的数字,输出的是"工作日";输入:6~7的数字,输出"休息日""中,如果输入的day的值不在1~7之间,那我们可以这样提示:"输入错误,请输入1~7的数字"

代码:

cpp 复制代码
//输入:1~5的数字,输出的是"工作日";输入:6~7的数字,输出"休息日",使用default
#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("输入错误,请输入1~7的数字\n");
		break;
	}
	return 0;
}

结果示例:

5.4switch语句中的case和default的顺序问题

在switch语句中case子句和default子句有顺序要求吗?default只能放在最后吗?

其实在switch语句中case语句和default语句是没有顺序要求的,只要你写的顺序是满足实际要求的就可以。

我们通常是把default子句放在最后处理的

相关推荐
爱装代码的小瓶子1 小时前
【c++知识铺子】最后一块拼图-多态
java·开发语言·c++
认真敲代码的小火龙1 小时前
【JAVA项目】基于JAVA的超市订单管理系统
java·开发语言·课程设计
CryptoRzz1 小时前
对接墨西哥股票市场 k线图表数据klinechart 数据源API
开发语言·javascript·web3·ecmascript
yue0081 小时前
C# 实现电脑锁屏功能
开发语言·c#·电脑·电脑锁屏
chilavert3181 小时前
技术演进中的开发沉思-230 Ajax:Prototype.js 重构原生 DOM
开发语言·前端·javascript
csbysj20201 小时前
SVN 标签
开发语言
2501_930707781 小时前
如何在 C# 中分离饼图的某个区域
开发语言·c#
缺点内向1 小时前
如何在C#中添加Excel文档属性?
开发语言·数据库·c#·.net·excel
Howie Zphile1 小时前
做移动端的 Next.js 项目,可以选哪些 UI?
开发语言·javascript·ui