C语言——操作符(逻辑、条件、关系)
目录
- :one:逻辑操作符
- 1.1、逻辑取反运算符`!`
- 1.2、逻辑与运算符`&&`
- 1.3、逻辑或运算符`||`
- :pushpin:逻辑运算符的例题:
- :pushpin:附:短路
- :two:条件操作符
- :three:关系操作符
- 3.1、关系操作符`==`和赋值操作符`=`混淆问题
- 3.2、关系操作符:x:连用
📝学习预警:
- 本篇文章我们将学习操作符(逻辑、条件、关系)
- 逻辑操作符
!、&&、||
- 改变表达式真假、并且、或者
- 逻辑运算符是从左向右进行运算的,可能会出现 短路(只执行左边的操作数,右边的不进行运算) 现象
- 条件操作符
exp1 ? exp2 : exp3
- exp1为真,执行exp2,并输出exp2的结果
- 反之,执行exp3,并输出exp3的结果
- 关系操作符
>、<、>=、<=、==、!=
- 大于、小于、大于等于、小于等于、等于、不相等
==
等于运算符 和=
赋值运算符,要区分清楚- 关系操作符不可连用,结果大概率错误
在学习过程中会有使用选择结构(if语句),可以结合该篇文章理解(后期完善好该文章后会发布的)
1️⃣逻辑操作符
逻辑运算符是用来提供逻辑判断的,用来构建复杂的表达式,其主要有下面三个运算符:
!
:逻辑取反运算符(改变单个表达式的真假)&&
:逻辑与运算符,并且的意思(只有两侧的表达式均为真,结果才为真)||
:逻辑或运算符,而且的意思(只有两侧的表达式均为假,结果才为假)
1.1、逻辑取反运算符!
例如:(如果将a赋值为1,打印hhhh;原理一致)
#include<stdio.h>
int main()
{int a = 0;if (a)//a为0,表达式假,条件不满足,不执行该语句printf("hhhh\n");if (!a)//a为0,!a为真,表达式真,条件满足,执行该语句printf("wwww\n");return 0;
}
***************
打印:wwww
1.2、逻辑与运算符&&
&&
是双目操作符,有两个操作数。- 这个是需要
&&
两边的表达式同为真,整个表达式才为真; - 如果有一边的表达式为假,结果为假
- 这个是需要
例子:只有同时满足:month大于等于1,且小于等于12; 才可以正确输出。
#include<stdio.h>
int main()
{int month = 0;printf("请输入一个数字,判断该数字是否为月份数字:");scanf("%d", &month);if (month >= 1 && month <= 12)printf("该数字是月份数字\n");return 0;
}
1.3、逻辑或运算符||
- 逻辑或运算符
||
是双目操作符,有两个操作
数||
两侧表达式全为假,结果才为假- 只要两侧的表达式有一个是真的,结果都为真
例子:只要month等于1或2或12,都可以正确打印
#include<stdio.h>
int main()
{int month = 0;printf("请输入一个数字,判断该数字是否为冬天:");scanf("%d", &month);if (month == 1 || month == 2 || month ==12)printf("是冬天\n");return 0;
}
📌逻辑运算符的例题:
- 我们已经学习了逻辑操作符的基本应用,来练习一道题吧。
- 闰年判断: 输入一个年份,判断该年份是否为闰年
- 判断规则:
- 1、能被4整除 且 不能被100整除
- 2、能被400整除
例子1:
#include<stdio.h>
int main()
{long year = 0;printf("请输入一个年份,判断是否为闰年:");scanf("%ld", &year);//合起来写了if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))printf("%ld是闰年\n",year);elseprintf("%ld不是闰年\n", year);return 0;
}
*****************************************************
*****************************************************
例子2:
#include<stdio.h>
int main()
{long year = 0;printf("请输入一个年份,判断是否为闰年:");scanf("%ld", &year);//分开写了if (year % 4 == 0 && year % 100 != 0) printf("%ld是闰年\n", year);else if(year % 400 == 0)printf("%ld是闰年\n", year);elseprintf("%ld不是闰年\n", year);return 0;
}
📌附:短路
C语言逻辑运算符 总是先对左侧的表达式求值,再对右边的表达式求值
如果左边的表达式满足逻辑运算符的条件,就不会对右边表达式求值,该情况称为“短路”。
比如:if(month >= 1 && month <= 12)表达式中 && 的左操作数是 month>=1 ,右操作数是 month<=12当左操作数的结果为0,不用判断右操作数就已经可以得到最后结果为0了
- 所以,对于
&&
来说,左操作数结果为0,最终结果为0
那么对于操作符||
是如何呢?
例如:if(month == 1 || month == 2)表达式中 || 的左操作数结果为1,不用判断右操作数就可以得到最终结果为1
- 所以,对于
||
来说,左操作数结果为1,最终结果为1
像这样只用通过左操作数就可以直接判断最终结果的,不用对右操作数进行计算的运算时 短路求值
- 下面的这些代码中,请仔细阅读,计算输出结果。
//代码1:
#include<stdio.h>
int main()
{int a = 0;int b = 2;int d = 3;int k = a++ && ++b && d++;printf("a=%d\tb=%d\td=%d\tk=%d\n", a, b, d, k);
}
//输出结果:a=1 b=2 d=3 k=0
为什么会时这样的输出结果呢?
- 因为
&&
操作符时只要有一个操作数结果为0,最终结果为0- 并且运算法则是从左向右运算的,因为
a++
的结果为0,后面的操作数不用运算得到最终结果为0- 将整个表达式的最终结果0赋给
k
,得到k=0
- 其中
a=1
是因为a
自增,而b、d
值不变是因为被短路,不用进行运算那么如果将a的值改为1,最终结果会如何呢?
- 最终结果:
a=2 b=3 d=4 k=1
,其原理和上面的解释相同
//代码2:
#include<stdio.h>
int main()
{int a = 0;int b = 2;int d = 3;int j = a++ || b++ || d++;printf("a=%d\tb=%d\td=%d\tj=%d\n", a, b, d, j);return 0;
}
//输出:a=1 b=3 d=3 j=1
为什么会时这样的输出结果呢?
- 因为
||
操作符时只要有一个操作数结果为1,最终结果为1- 并且运算法则是从左向右运算的,因为
a++
的结果为0,执行下一个操作数b++
,b++ = 2
其返回结果为1,最终结果为1- 将整个表达式的最终结果1赋给
j
,得到j=1
- 其中
a=1,b=3
是因为a,b
自增,而d
值不变是因为被短路,不用进行运算那么如果将b、d的值改为0,最终结果会如何呢?
- 最终结果:
a=1 b=1 d=1 j=0
,其原理和上面的解释相同
2️⃣条件操作符
- 条件操作符也称为三目操作符,这是接受三个操作数的,格式:
exp1 ? exp2 : exp3
- 条件操作符的计算逻辑是:
- 如果
exp1
为真,则计算exp2
,exp2
的计算结果是整个表达式的结果; - 如果
exp1
为假,则计算exp3
,exp3
的计算结果是整个表达式的结果;
- 如果
- 条件操作符的计算逻辑是:
练习1:使用条件操作符表达下面代码的逻辑
#include<stdio.h>
int main()
{int a = 0;int b = 0;scanf("%d", &a);if (a > 2)b = 1;elseb = 0;printf("b=%d\n", b);return 0;
}
*******************************
练习2:使用条件表达式实现找出两个数中的较大值
答案:
1、
#include<stdio.h>
int main()
{int a = 0;int b = 0;scanf("%d", &a);b = (a > 2 ? 1 : 0);//或者(a > 2 )? (b=1) :(b= 0);
/*(a > 2 )? (b=1) :(b= 0);
这种写法是允许的,但要将每一个括起来*/printf("b=%d\n", b);return 0;
}
***************************************
2、写法不唯一的,下面只做参考。
#include<stdio.h>
int main()
{int a = 0;int b = 0;printf("请输入两个值:");scanf("%d%d", &a, &b);int c = 0;c = (a > b ? a : b);printf("%d\n", c);return 0;
}
3️⃣关系操作符
- 在C语言中用来比较的表达式,称为关系表达式,而在该表达式用到的运算符被称为关系操作符,主要有下面六个操作符:
>
:大于运算符<
:小于运算符>=
:大于等于运算符<=
:小于等于运算符==
:相等运算符!=
:不相等运算符
例如:
a > b; //a大于b
a < b; //a小于b
a >= b; //...
a <= b; //...
a == b; //a等于b
a != b; //a不等于b
关系表达式返回值通常为1(真)或0(假)
在C语言中,0表示假;非0表示真。
- 比如:
20>10
返回1,10>20
返回0- 关系表达式通常用在
if
,else if
,while
,do... while
等结构中
例如:
if(a ==3)
{printf("hh");
}
3.1、关系操作符==
和赋值操作符=
混淆问题
❗️注意:在我们学习中,我们刚开始可能常将 ==
相等操作符和=
赋值操作符混淆,可能会出现下面的错误,这种错误是可以运行的,但很容易出现一些出乎意料的结果。
if(a = 3)printf("hh");
******************
这个原本是为了a == 3,但写成了a = 3。
这就相当于把3赋值给a,返回值是3,所以if判断条件永远为真。
- 为了避免这种错误的发生,我们可以将
a==3
写出3==a
- 为什么可以这么改写呢?
- 是因为如果错写
3=a
,这个编译器是会报错的,而3==a
是可以的,这样可以避免错误的发生
- 是因为如果错写
3.2、关系操作符❌连用
i<j<k
这个是将两个小于运算符连用了。这个是合法的表达式,并不会报错,但是通常达不到理想结果。
- 我们是想表达
j
在i
和k
之间。 - 但关系操作符是从左到右计算的,则实际是执行的表达式为:
(i<j)<k
i<j
会先得到一个返回值(0或1),再将得到的返回值(0或1)和k
做对比,再最后得到一个返回值(0或1)
所以我们不一定可以得到预期结果,正确的做法是需要引入逻辑与操作符(&&),改写成:i<j && j<k
目前我们已经学习了关系操作符不可连用,
我们来做一道题检验是否掌握了这个知识点
例题:输入一个年龄,如果年龄在12~18之间,我们输出少年.
(1、会给一个错误的代码,请问这个输出原理是如何,输出结果是什么;
2、将错误代码改写正确)
********************************
********************************
错误代码:
#include<stdio.h>
int main()
{int age = 0;printf("请输入一个年龄:");scanf("%d", &age);if (12 <= age <= 18){printf("少年\n");}return 0;
}
********************************
代码改写:
#include<stdio.h>
int main()
{int age = 0;printf("请输入一个年龄:");scanf("%d", &age);if (12 <= age && age <= 18){printf("少年\n");}return 0;
}
对错误代码的解释:
以上是关于操作符的基本使用,在后面的使用中字面上是如何理解,就怎么写可以了
✒️小结:
本篇文章我们学习了逻辑、条件、关系操作符;
它们的基本使用和一些需要注意的地方都有讲解。
感谢大家的阅读🌹🌹