在使用指针进行访问时,往往我们比较担心空指针访问崩溃。这时候我们可以通过逻辑与&&来直接短路这种异常情况。这是实际是用的是惰性运算,那什么是惰性运算,我们用怎么运用呢?各个语言间惰性运算又有什么区别呢?
一、C语言的惰性运算的定义
C语言的惰性运算(短路求值)仅针对逻辑&&、逻辑或||两个运算符
1、逻辑与A&&B的惰性规则
如果A表达式的结果为假(0),整个表达式必然为假,不会执行、计算右边的B,直接短路。
2、逻辑与A||B的惰性规则
如果A表达式的结果为真(非0),整个表达式必然为真,不会执行、计算右边的B,直接短路。
说明:+、-、、/、>、<、==等运算符没有惰性运算,两侧一定会完整求值。*
二、C语言的惰性运算的示例
1、逻辑与短路的惰性
#include<stdio.h>#include<windows.h>#include<math.h>intfunc(){printf("func()被执行了!\n");return1;}intmain(intargc,charconst*argv[]){/* code */SetConsoleOutputCP(65001);SetConsoleCP(65001);inta=0;if(a&&func()){printf("进入到if分支\n");}printf("程序结束\n");return0;}运行结果:
a=0时,a&&func():左侧为假,右侧的func()不执行
当a=1时,func()会被执行
2、逻辑或短路
当a=1时,不需要计算func,直接运行
当a=0时,执行func的判断
注意:短路导致自增等运算失效,在实际编码时,是需要注意的。
三、类C语法语言惰性运算的区别
共同点:都对&&(逻辑与)、||(逻辑或)做短路惰性,规则和C一致(A&&B:A假则B不执行,A||B:A真则B不执行)
不同点:
| 语言 | 与C不同的地方 | 备注 |
|---|---|---|
| C++ | 新增重载运算符 | 如果重载operator与或operator或,短路特性会消失,两侧一定全求值 |
| java | 多出非短路版本 | 与、或是完整求值,无论左边真假,左右都算 |
| JavaScript | 短路逻辑和C一致,但是返回值规则不同 ;空值合并??也支持短路惰性,c没有这个运算符 | JS会直接返回原始表达式的值,常用来做默认值 |
| Go | 严格布尔类型,只能放布尔表达式 | C可以放任意数字、指针当真假 |