前言:
现在兄弟们对“c语言中三种逻辑运算符”大概比较重视,咱们都需要剖析一些“c语言中三种逻辑运算符”的相关内容。那么小编同时在网上收集了一些对于“c语言中三种逻辑运算符””的相关知识,希望姐妹们能喜欢,我们快快来学习一下吧!逻辑运算符的短路,是C语言的一个基本语法。
在逻辑与运算&&连接的2个表达式里,只要第1个表达式为false,那么总结果就为false,后续的其他表达式就不需要计算了。
在逻辑或运算||连接的2个表达式里,只要第1个表达式为true,那么总结果就为true,后续的其他表达式也不需要计算了。
这就是逻辑运算符的短路。
与运算的短路,可以用于结构体指针取成员时的判断。
例如:
if (f && f->ops && f->ops->read && (ret = f->ops->read()) > 0)
return ret;
这2行代码里的与运算,是判断函数指针有关的成员变量是否为NULL,以避免空指针的使用。
当f为NULL时,第1个逻辑表达式的结果就是false,程序会自动跳过后面的各个表达式,避免因空指针而导致程序死掉。
if (king->x + king->y == queen->x + queen->y || king->x - king->y == queen->x - queen->y)
return 1;
上面的代码,是国际象棋里判断king与queen在不在同一条斜线上。
在同一条斜线上时,xy坐标的和或者差相同,2个条件里只需要1个成立就行。
如果第一个表达式成立,就会触发||运算符的短路。
scf编译器框架里,&&和||的短路是在中间代码生成时处理的。
&&运算的短路处理,首先计算第一个表达式,并且获取它的比较运算符。
&&运算在比较条件为false时短路,所以它的跳转条件与比较运算符本身是反着的。
if (a ==b && b == c) {}
这种比较,当a != b时才会越过后面的b == c。
比较两个数是否相等,在汇编里是做减法,然后看结果是不是0。
也就是说,if (a == b)在汇编里是 if (a - b == 0)。
所以,当a == b时,cpu会设置零标志:eflags寄存器的ZF标志位为1。
所以,短路跳转条件是jnz,a - b != 0时做短路跳转。
对于浮点数的大于和小于的比较,在x64里与整数不同。
浮点数使用above和below,而整数使用greater和less,
所以:
浮点数的 >= 是jae,<= 是jbe;
整数的 >= 是jge,小于等于是jle。
如果是逻辑非运算,或者直接比较一个数是不是0,需要使用test指令。
if (!p) 和 if (p) 的比较都是 test p,p,然后根据结果是不是0来跳转。
test指令,在汇编里使用按位与运算。
当p == NULL的时候,它与它自己的按位与运算的结果肯定是0。
这个运算,可以被用来判断指针是不是NULL。
||运算符的短路跳转条件,跟它的第一个表达式的比较条件是一致的,因为它是条件为true时短路。
总的来说,||和&&的处理过程一样,除了跳转条件有点区别(不再细说)。
短路跳转的添加,如上图,跳转到第2个表达式的后面。
如果第2个表达式后面还有逻辑运算符的话,它同时也是这个运算符的第1个表达式,会触发级联的短路跳转。
接下来3张图,是生成的中间代码,已经划分了基本块:
对于级联跳转,我没有做进一步的跳转优化。
最后2张图,是或运算符的处理代码,不再细说了。
标签: #c语言中三种逻辑运算符