C语言中的逻辑短路

为了减少程序的计算量,在进行逻辑运算时,C语言采用了在保持原逻辑运算正确性的同时,通过在已确定表达式的确切值的情况下,不计算其后式子的方式来削减运算量,这就是所谓“逻辑短路”

为何要进行逻辑短路

& 和 | 运算的法则

  • 我们都知道 0 & 1 == 0, 0 | 1 == 1,其实在这个过程中,无论是&还是|,符号两边的式子都被计算了一次,但对于第一个式子来说,只要第一个式子的结果是false,在进行&运算时,不管其后的结果如何,最后的结果一定为true,相应的,对于|,只要第一个式子是true,其后的结果一定为true.如果将这个性质放在日常代码实现中,我们可以看到
#include<stdio.h>
int a[4];
int main(){
	++a[0] | ++a[1] | ++a[2] | a[3];
	for(int i=0;i<4;++i) printf("a[%d]==%d ",i,a[i]);
	puts("");
	return 0;
}
  • 运行结果:
    在这里插入图片描述

注:
前置++:先进行自增,再将自增后的结果加入逻辑运算中
后置++:先加入逻辑运算,结果完成后再进行自增

  • 但是对于整个式子来说,其实我们只要知道第一个是true,这个表达式的结果便已经显而易见,为了实现这种所谓“逻辑短路”的做法,C语言为我们提供了相应的运算符:&&||

&&和||运算

  • &&运算规律和&相同,||运算规律和|相同
  • 可视为二者的“加强版”
  • 同样的式子,我们依然用代码举例
#include<stdio.h>
int a[4];
int main(){
	++a[0] || ++a[1] || ++a[2] || a[3];
	for(int i=0;i<4;++i) printf("a[%d]==%d ",i,a[i]);
	puts("");
	return 0;
}
  • 运行结果:
    在这里插入图片描述
  • 另外的版本:
#include<stdio.h>
int a[4];
int main(){
    ++a[0] && 0 && ++a[2] && ++a[3];
    for(int i=0;i<4;++i) printf("a[%d]==%d ",i,a[i]);
    puts("");
    return 0;
}
  • 运行结果:
    在这里插入图片描述
  • 在上面的代码中,a[0]的运算结果为1&&不进行短路,这时候进行一次运算得到0,在第二个&&时因为前面的式子结果为0,其后的式子一律不参与计算,即a[2]a[3]的自增无意义

更复杂些的式子

  • 现在你已经掌握了对逻辑短路最基本的认识,为了方便以后样例的解释,我先贴出C语言中常用的运算符优先级表在这里插入图片描述
  • 我们可以举别的更加有趣的例子:
  • 下面式子的值是多少?
#include<stdio.h>
int a[4];
int main(){
    a[1]=4,a[2]=1,a[3]=0;
    a[0]= a[1]++==4 || a[2]++&&a[3]++;
    a[0]== ? a[1]==? a[2]==? a[3]==?
    return 0;
}
  • 显然不用理睬最后的取值符号,即使++的优先级高于==,在进行逻辑运算的时候原则一定优先进行逻辑判断,在这个式子中a[1]==4结果为true,随后a[1]自增为5,前面的语句结束
  • 这时候||的前面结果为true,在存在逻辑短路的情况下,依旧不用管高于它优先级的++&&,直接整个式子判断为true,后续的自增运算符全部作废,显然易得答案
  • a[0]==1 a[1]==5 a[2]==0 a[3]==0
  • 按照相似的原理,自然可以依旧举出一个类似的简单例子
#include<stdio.h>
int a[6];
int main(){
    a[0]++ && a[1]++ || a[2]++ && a[3]++ || a[4]++ && a[5]++;
 	//各个变量的值分别是多少?
    return 0;
}
  • 在逻辑表达式中&&||并存时,一方面要注意二者的优先级关系,另一方面要注意逻辑短路的情况,而这类式子谨遵一个重要原则:
    只要能确定表达式的结果,还没有进行的运算不再继续
  • 如何理解?
  • 来看示例中已经给出的例子
  • 首先进行逻辑运算a[0]&&,前面的值为0,其后的a[1]++忽略,a[0]自增,接着到||,因为前面的值为0无法进行短路,故执行a[2]&&,值为0,其后a[3]++忽略,a[2]自增,最后二者0 || 0 == 0,无法进行短路,执行a[4]&&,结果以此类推,最后结果为
    a[0]==1 a[1]==0 a[2]==1 a[3]==0 a[4]==1 a[5]==0
  • 真的要造这类无意义又笨蛋的一长串式子很简单,如果真的喜欢钻研建议读者自己造并运行代码进行验证,下课!
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值