关于逻辑运算符和赋值运算符的优先级探讨
引言
今日在练习ctf基础题的时候,意外发现如下情况,代码如下:
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
if(!preg_match("/\;/", $v2)){
if(preg_match("/\;/", $v3)){
eval("$v2('ctfshow')$v3");
}
}
}
显然,v0
要做到v1
v2
v3
都为数字。结果查看wp的时候发现,只要v1
是数字就行了,后面两个完全不用在意。这就引起我的思考:由于最近大一学业要求我重拾C语言,我已经默认了赋值运算符的优先级非常低,甚至低于逻辑运算符。可是在这里根据wp,这一优先级反过来了。我开始查阅资料。
PHP的运算符优先级
以下是php的运算符优先级。
结合方向 | 运算符 | 附加信息 |
---|---|---|
无 | clone new | clone 和 new |
左 | [ | array() |
右 | ++ – ~ (int) (float) (string) (array) (object) (bool) @ | 类型和递增/递减 |
无 | instanceof | 类型 |
右 | ! | 逻辑运算符 |
左 | * / % | 算术运算符 |
左 | + – . | 算术运算符和字符串运算符 |
左 | << >> | 位运算符 |
无 | == != === !== <> | 比较运算符 |
左 | & | 位运算符和引用 |
左 | ^ | 位运算符 |
左 | | | 位运算符 |
左 | && | 逻辑运算符 |
左 | || | 逻辑运算符 |
左 | ? : | 三元运算符 |
右 | = += -= *= /= .= %= &= |= ^= <<= >>= => | 赋值运算符 |
左 | and | 逻辑运算符 |
左 | xor | 逻辑运算符 |
左 | or | 逻辑运算符 |
左 | , | 多处用到 |
可以看到,php有两套逻辑运算符,分别是||和&&、and和or,分别架在了赋值运算符的两端。和C语言一样的||和&&优先级比赋值高,而和英文表示的and和or优先级比赋值低。在使用途中,必须要注意。
其他语言优先级探讨
既然PHP的两套逻辑运算符架在赋值运算符两端,那么我们可以思考,其他各种语言的优先级是否也一样。
下面统计了一下主流语言的情况:
逻辑运算符类型 | 编程语言 | 和赋值运算符的关系 |
---|---|---|
只有一套||和&& | C/C++、Java、Rust、JavaScript、Go、Kotlin、C# | 比赋值高 |
只有一套and和or | Python、Lua | 比赋值高 |
两套都有 | Ruby、PHP | 分别架在赋值两边 |
特例1 | SQL | 两套都有,并且都比赋值高 (或者说&&和AND等价) |
综上所述,我们可以看出,在大部分采用||和&&配置的语言中,这俩的优先级始终比赋值高。而像python和Lua这样只有and和or的语言中,其优先级仍然比赋值高。最后就是部分两套系统都有的语言,那么很有可能分别架在赋值两边,但也有例外,还需具体分析。
总结
观察了各类语言的逻辑和赋值运算符优先级,我们发现各类语言的情况还是既有相同之处,又有一些特色。具体情况还需具体分析。在今后接触不熟悉的语言时,尤其是看到and和or的情况下,我们更要尤为关注其优先级,不要偷懒去查一查!
作者:Sxrhhh
转载请注明出处.
在个人网站持续更新中……