运算符优先级
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=OpPrecedence
- 最后更新: 2022-05-29
当单个表达式中出现多个运算时,每个运算都按预定顺序求值和解析。这称为运算顺序或运算符优先级。
如果表达式中某个运算符的优先级更高,它会在优先级较低的运算符之前求值。
如果运算符优先级相同,则按其结合性顺序求值。结合性可以是从左到右或从右到左。
一般规则是,二元运算符(如 +、^)和一元后缀运算符(如 ()、->)从左到右求值,一元前缀运算符(如 Not、@)从右到左求值。
结合性为"N/A"的运算符表示在表达式中使用该运算符时,不需要通过优先级或结合性来检查其运算顺序。类似函数的运算符(如 Cast)由于其语法中需要括号,总是最先求值。赋值运算符总是最后求值。
括号可用于覆盖运算符优先级。括号内的运算先于其他运算执行。括号内使用正常的运算符优先级。
下表按从高到低的顺序列出了运算符优先级。表格中的分隔符标记了优先级相同的运算符组。
最高优先级
| 运算符 | 说明 | 结合性 |
|---|---|---|
| CAST | 类型转换 | N/A |
| PROCPTR | 过程指针 | N/A |
| STRPTR | 字符串指针 | N/A |
| VARPTR | 变量指针 | N/A |
| [] | 字符串索引 | 从左到右 |
| [] | 指针索引 | 从左到右 |
| () | 数组索引 | 从左到右 |
| () | 函数调用 | 从左到右 |
| . | 成员访问 | 从左到右 |
| -> | 指针成员访问 | 从左到右 |
| @ | 取地址 | 从右到左 |
| * | 取值 | 从右到左 |
| New | 分配内存 | 从右到左 |
| Delete | 释放内存 | 从右到左 |
| ^ | 幂运算 | 从左到右 |
| - | 取负 | 从右到左 |
| * | 乘法 | 从左到右 |
| / | 除法 | 从左到右 |
| \ | 整除 | 从左到右 |
| MOD | 取模 | 从左到右 |
| SHL | 左移 | 从左到右 |
| SHR | 右移 | 从左到右 |
| + | 加法 | 从左到右 |
| - | 减法 | 从左到右 |
| & | 字符串连接 | 从左到右 |
| Is | 运行时类型信息检查 | N/A |
| = | 等于 | 从左到右 |
| <> | 不等于 | 从左到右 |
| < | 小于 | 从左到右 |
| <= | 小于或等于 | 从左到右 |
| >= | 大于或等于 | 从左到右 |
| > | 大于 | 从左到右 |
| NOT | 按位取反 | 从右到左 |
| AND | 逻辑与 | 从左到右 |
| OR | 逻辑或(包含) | 从左到右 |
| EQV | 逻辑等价 | 从左到右 |
| IMP | 逻辑蕴含 | 从左到右 |
| XOR | 逻辑异或 | 从左到右 |
| ANDALSO | 短路逻辑与 | 从左到右 |
| ORELSE | 短路逻辑或(包含) | 从左到右 |
| =[>] | 赋值 | N/A |
| &= | 连接并赋值 | N/A |
| += | 加并赋值 | N/A |
| -= | 减并赋值 | N/A |
| *= | 乘并赋值 | N/A |
| /= | 除并赋值 | N/A |
| = | 整除并赋值 | N/A |
| ^= | 幂运算并赋值 | N/A |
| MOD= | 取模并赋值 | N/A |
| AND= | 逻辑与并赋值 | N/A |
| EQV= | 逻辑等价并赋值 | N/A |
| IMP= | 逻辑蕴含并赋值 | N/A |
| OR= | 逻辑或(包含)并赋值 | N/A |
| XOR= | 逻辑异或并赋值 | N/A |
| SHL= | 左移并赋值 | N/A |
| SHR= | 右移并赋值 | N/A |
| LET | 赋值 | N/A |
| LET() | 赋值 | N/A |
在某些情况下,优先级顺序可能产生令人困惑或反直觉的结果。以下是一些示例:
start GeSHi
'' trying to raise a negated number to a power
-2 ^ 2
Desired result: (-2) ^ 2 = 4
Actual result: -(2 ^ 2) = -4
'' trying to test a bit in a number
n And 1 <> 0
Desired result: (n And 1) <> 0
Actual result: n And (1 <> 0)
'' trying to shift a number by n+1 bits
a Shl n+1
Desired result: a Shl (n + 1)
Actual result: (a Shl n) + 1end GeSHi
对于运算符优先级可能存在歧义的表达式,建议用括号将表达式的各部分括起来,这样既能最大限度地减少出错的可能性,也有助于阅读代码的人理解。