当在单个表达式中发生多个操作时,将以预定顺序评估和解析每个操作。这被称为操作顺序或运算符优先级。
如果一个表达式中的运算符具有较高的优先级,则在较低优先级的运算符之前进行求值。
如果操作者具有相同的优先级,则按照其关联性的顺序进行评估。关联性可以是从左到右或从右到左的顺序。
通常,二进制运算符(例如
+,
^)和一元后缀运算符(例如
(),
->)被评估为从左到右,一元前缀运算符(例如
Not,
@)从右到左进行评估。
具有“N / A”的关联性的运算符表示,无论按优先级还是关联性,都不需要检查其操作顺序,可以使用操作符的表达式。像
Cast这样的类似功能的运算符由于其语法中需要的括号,始终是第一个被评估的运算符。赋值运算符总是最后一个被评估。
圆括号可用于覆盖运算符优先级。括号内的操作在其他操作之前执行。在括号内使用正常运算符优先级。
下表列出了从最高到最低的运算符优先级。表中的突破标记了具有相同优先级的运算符组。
最高优先级
| 操作者 | 描述 | 关联性 |
| | | |
| CAST | 类型转换 | N/A |
| PROCPTR | 程序指针 | N/A |
| STRPTR | 字符串指针 | N/A |
| VARPTR | 变量指针 | N/A |
| | | |
| [] | 字符串索引 | Left-to-Right |
| [] | 指针索引 | Left-to-Right |
| () | 数组索引 | Left-to-Right |
| () | 函数调用 | Left-to-Right |
| . | 成员访问 | Left-to-Right |
| -> | 指向成员访问 | Left-to-Right |
| | | |
| @ | 的地址 | Right-to-Left |
| * | 取数据值 | Right-to-Left |
| New | 赋值内存 | Right-to-Left |
| Delete | 取消赋值内存 | Right-to-Left |
| | | |
| ^ | 取幂 | Left-to-Right |
| | | |
| - | 求反 | Right-to-Left |
| | | |
| * | 乘 | Left-to-Right |
| / | 除以 | Left-to-Right |
| | | |
| \ | 整数除法 | Left-to-Right |
| | | |
| MOD | 余数 | Left-to-Right |
| | | |
| SHL | 位左移 | Left-to-Right |
| SHR | 位右移 | Left-to-Right |
| | | |
| + | 加 | Left-to-Right |
| - | 减去 | Left-to-Right |
| | | |
| & | 字符串连接 | Left-to-Right |
| | | |
| Is | 运行时类型信息检查 | N/A |
| | | |
| = | 等于 | Left-to-Right |
| <> | 不平等 | Left-to-Right |
| < | 少于 | Left-to-Right |
| <= | 小于或等于 | Left-to-Right |
| >= | 大于或等于 | Left-to-Right |
| > | 大于 | Left-to-Right |
| | | |
| NOT | 求位反码 | Right-to-Left |
| | | |
| AND | 位逻辑与 | Left-to-Right |
| | | |
| OR | 位逻辑或 | Left-to-Right |
| | | |
| EQV | 等价 | Left-to-Right |
| IMP | 意义 | Left-to-Right |
| XOR | 位异或 | Left-to-Right |
| | | |
| ANDALSO | 短路逻辑与 | Left-to-Right |
| ORELSE | 短路逻辑或 | Left-to-Right |
| | | |
| = | 赋值 | 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 |
在某些情况下,优先顺序可能导致混乱或反直觉的结果。这里有些例子:
'' 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) + 1
对于运算符优先级可能不明确的表达式,建议将表达式的部分包含在括号中,以便尽可能减少错误的可能性,并帮助读者阅读代码。
参考