跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

C语言逻辑运算符&&和||,一篇文章带你读懂逻辑表达式!

目录 逻辑运算符有哪些?

逻辑运算符的短路特性 逻辑运算符在表达式求值中的问题 逻辑运算符&&、||混合的不同情况 逻辑运算符有哪些?

C 语言提供了以下三种逻辑运算符。

一元:!

(逻辑非)。

二元:&&(逻辑与)、||(逻辑或)。

以上三种逻辑运算符中,逻辑非 ! 的优先级最高,逻辑与 && 次之,逻辑或  ||  优先级最低。

即算术、逻辑、赋值运算符的优先级顺序为: 逻辑非 ! > 算术 > 逻辑与 &&    >    逻辑或 ||    >    赋值= 逻辑表达式的值为逻辑值,即布尔型(bool),该类型为 C99 新增的,一些编译器可能还不支持该类型。

逻辑值分为逻辑真值和逻辑假值。

一般情况下,在判断时,仅有零值被判断为逻辑假值(false), 一切非零值 均可被判断为逻辑真值(true);在存储和表示时, 通常,使用 1 表示逻辑真值,0表示逻辑假值。

逻辑与 && 运算符的运算规则:只有两个操作数均为逻辑真时,结果才为真。

其余情况,结果均为假。

逻辑或 || 运算符的运算规则:只有两个操作数均为逻辑假时,结果才为假。

其余情况,结果均为真。

例如,设有定义语句 int a = 3 , b = 5 ; 则有: !a:由于 a 非零,为真,!a 为假,其值为 0。

a||b:由于 a 和 b 均非零,均为真,故逻辑或的结果为真,其值为 1。

a&&b:由于 a 和 b 均非零,均为真,故逻辑与的结果为真,其值为 1。

!a||b&&2:由于逻辑非 ! 优先级最高,首先与 a 结合,而 && 优先级高于 ||,相当于(!a)||(b&&2), 即 0||1 为真,其值为 1。

此外,&&和||还有 “短路”的特性 逻辑运算符的短路特性 逻辑与 &&、逻辑或 || 均有“短路”特性: 逻辑与&&“短路”:当逻辑与&&的左操作数为逻辑假时,就足以判断该逻辑运算的结果为假了,故右操作数就不再被执行。

逻辑或||“短路”:当逻辑或||的左操作数为逻辑真时,就足以判断该逻辑运算的结果为真了,故右操作数就不再被执行。

例如: int a = 1 , b = 2 , c ; c = a ||++ b ; printf ( "a=%d,b=%d,c=%d\n" , a , b , c ); 由于 a 为非零值,即为真,而当逻辑或 || 的左操作数为真时,就足以判断该逻辑操作的结果为真。

故发生“短路”,即右操作数 ++b 不被执行。

输出结果为:a=1,b=2,c=1。

注:我们在看|| &&的问题时  应该将问题看为 ■||■   ■&&■ 的问题 其中,■可以是a、b、x、y这样的一个变量也可以是1、2、’a’这样的整型常量,还可以是整体的一个表达式语句 例如(a+b)、++a,将表达式看成整体■ 更方便且更准确我们去区分“短路问题” 逻辑运算符在表达式求值中的问题 这是简单的逻辑短路,我们再看看复杂一点的问题

公布答案:

从结果我们可以看出,只有x的值发生了变化 疑问 : &&的优先级不是高于||吗 为什么不是先计算&&,所以按道理y和z的值都改变才对不是吗?

我们再看  将++y&&++z 用括号括起来

()的优先级够高吧,并且将整体括了起来,可是结果表明 括号里面完全没有计算啊?

由此看出 优先级 在逻辑表达式中并没有起到 优先的作用 即 在含有 逻辑 表达式 的表达式 求值中 , 运算符的优先级并不影响 逻辑运算符 求值顺序 其实,优先级只是改变了结合顺序,但并不改变运算顺序 引入谭浩强的 “短路法则” c把先计算哪部分的决定权留个设计者,但&&和||是例外,c语言保证&&和||的求值顺序是从左到右,一旦发现某个元素让表达式无效立即停止运算(短路法则)。

” 在上述问题中 表达式 相当于 :++x || (++y&&++z) &&优先级确实是高,所以,(++y&&++z)做为一个整体 ■ 。

而||的规则就是,左侧为true,右侧不执行。

所以,即便是++x || (),右面是括号,优先级最高,也是先执行||左侧的。

等同于   ■||■  的问题 有点感觉了吧!

趁热打铁,再看一个复杂的例子 分析以下程序,输出其运行结果。

int main(void)

{ int a=0,b=2,c; c=!a||++b&&a--; printf("a=%d,b=%d,c=%d\n",a,b,c); return 0; } 代码分析: 混合表达式 c=!a||++b&&a-- 中含有的运算符有逻辑非 !

、逻辑或 ||、逻辑与 &&、算术前缀 ++、算术后缀 --、赋值号 = 等6个运算符。

逻辑运算符、算术运算符、赋值运算符的优先级的关系为: 逻辑非!     >       算术     >      逻辑与&&    >     逻辑或 ||       >      赋值 = 由于该表达式中赋值运算符优先级最低,故最后赋值。

根据优先级的高低,表达式 !a||++b&&a--等价于(!a)||((++b)&&(a--)),而逻辑或 || 的左操作数 !a 为真,此时足以判断该表达式的值为真。

故发生“短路”,即 || 的整个右操作数 ((++b)&&(a--)) 不再被执行。

运行结果为: a=0,b=2,c=1

所以该问题实际上还是 短路法则 的问题,运算符优先级不影响。

到此,相信你已经对&& ||的运算问题已经有了很深刻的理解 逻辑运算符&&、||混合的不同情况 以下是对该类问题的不同类型区分结果 情况一:

#include

int main() { int a=1,b=2,c=3,ans; ans=a++&&++b&&++c; printf("ans=%d,a=%d,b=%d,c=%d\n",ans,a,b,c); return 0; }

注意 a虽然是后++ 但执行完也改变了哦!

情况二:

#include

int main() { int a=1,b=2,c=3,ans; ans=++a&&++b||++c; printf("ans=%d,a=%d,b=%d,c=%d\n",ans,a,b,c); return 0; }

ans=++a&&++b||++c; 相当于   ans=(++a&&++b)||++c; 所以c的值不变

情况三:

#include

int main() { int a=1,b=2,c=3,ans; ans=++a&&(++b||++c); printf("ans=%d,a=%d,b=%d,c=%d\n",ans,a,b,c); return 0; }

&&后半部分得到++b的值就可以了 所以c还是不变 情况四:

#include

int main() { int a=0,b=2,c=3,ans; ans=a&&(++b||++c); printf("ans=%d,a=%d,b=%d,c=%d\n",ans,a,b,c); return 0; }

和之前的问题一样,()并不改变&&运算顺序 所以得到a=0后就停止运算了 情况五:

#include

int main() { int a=0,b=2,c=3,ans; ans=a||(++b&&++c); printf("ans=%d,a=%d,b=%d,c=%d\n",ans,a,b,c); return 0; }

和之前不一样哦,这里a=0了,所以会判断&& ans=a||++b&&++c;  不加括号的结果也一样哦 但是注意 结合顺序并 不是 ans=(a||++b)&&++c;

!!这里虽然结果一样,但只是巧合!! 比如

#include

int main() { int a=1,b=2,c=3,ans; ans=++a||++b&&c++; printf("ans=%d,a=%d,b=%d,c=%d\n",ans,a,b,c); return 0; }

应该看作 ans=++a||(++b&&c++);   所以 a的值改变 b c都不会改变 但是如果看做 ans=(++a||++b)&&c++;   则a、c改变 b的值不会改变

牢记 优先级只是改变了结合顺序,但并不改变运算顺序 内容都是自己原创,属实不易,未经允许请勿擅自转载哦!

祝你学习进步,生活愉快~

相关文章