运算符(Operator)是能够利用操作数得出数值的符号,是复合表达式的重要组成部分。
部分运算符的操作数类型、计算结果是可以自定义的。点击查看:运算符重载指南
float.inc文件专门为拥有Float标签的操作数重新定义了运算符计算方式,其它类型的操作数都默认执行整数计算。
版本注意:AMXX1.8.3以下和AMXX1.8.2以上版本,浮点数的相关计算结果略有不同,而且某些运算符被禁用。感兴趣的可以自行查阅float.inc文件。
学习建议:以下内容中,看不懂的可以先跳过,需要用到时再翻回来看。还有就是二进制位操作属于常用的必学内容。
操作数通常是字面量、常量、变量、函数等表达式,还可以是由它们与运算符组合成的表达式。接下来用单个字符表示:
e // 任意表达式
v // 变量(不能有只读特性,不能是数组)
a // 数组(包括数组字面量,字符串字面量)
f // 函数
s // 任何标识符
仅以下运算符可以对数组进行操作:
= [] {} : ?: , sizeof defined tagof
需要注意,标识符和数值不是一回事,标识符可以当做数值使用,但数值不能当做标识符使用。
运算符的操作结果可能会得到标识符本身,或得到标识符绑定的数值。
| 运算符 | 名称 | 用法 | 描述 |
|---|---|---|---|
+ |
加法运算符 | e1 + e2 |
得到e1加e2的结果 |
- |
求负数 减法运算符 |
-ee1 - e2 |
求e的负数 得到e1减e2的结果 |
* |
乘法运算符 | e1 * e2 |
得到e1乘以e2的结果 |
/ |
除法运算符 | e1 / e2 |
得到e1除以e2的商数,向下取整 |
% |
取模运算符 | e1 % e2 |
模 = e2 - 商 * e1 (商=e1/e2,向负无穷取整) |
++ |
递增运算符 | v++++v |
让v的值增加1 后置++得到旧值 前置++得到新值 |
-- |
递减运算符 | v----v |
让v的值减少1 后置--得到旧值 前置--得到新值 |
注意:AMXX中并没有定义求正运算符,因此不能用+得到e的正数。
重要:二进制位操作是AMXXPawn编程中的核心技能,在游戏中应用广泛,务必掌握。
AMXXPawn的所有数值都可用32个位上的0或1表示,左边是高位,右边是低位。
其中,从右往左第32个位称为'符号位',若为0表示数值是正数,若为1表示数值是负数。
源码中可以用0b开头,编写二进制数值字面量(可在数值内任何顺眼的位置穿插下划线),左侧连续的0可以不写。
例如:0b_00001111和0b_1111是同一个数值。
| 运算符 | 名称 | 用法 | 描述 |
|---|---|---|---|
~ |
按位取反 | ~e |
得到e在二进制位中的补数,所有位取反,0变1,1变0 |
>> |
有符号右移 | e1 >> e2 |
右移e2位,用符号位相同值填充左侧,右侧溢出位舍弃 |
>>> |
无符号右移 | e1 >>> e2 |
右移e2位,用0填充左侧,右侧溢出位舍弃 |
<< |
左移 | e1 << e2 |
左移e2位,左侧溢出位舍弃,用0填充右侧 |
& |
位与 | e1 & e2 |
保留e1与e2同位上的1,其它全为0。得到交集 |
| |
位或 | e1 | e2 |
保留e1或e2所有位上的1,其它全为0。得到并集 |
^ |
位异或 | e1 ^ e2 |
保留e1和e2不同位上的1,其它全为0。得到对称差集 |
| 运算符 | 名称 | 用法 | 描述 |
|---|---|---|---|
= |
赋值 | v = e |
将e的每个数值复制给v 若e非数组,结果为e 若e是数组,维度必须与v相同,e和v的每个多维数组尺寸必须相同, e的每个1维数组尺寸必须小于等于v内部对应的1维数组尺寸,计算结果是e的地址 |
+= |
加法赋值 | v += e |
v = v + e的简写 |
-= |
减法赋值 | v -= e |
v = v - e的简写 |
*= |
乘法赋值 | v *= e |
v = v * e的简写 |
/= |
除法赋值 | v /= e |
v = v / e的简写 |
%= |
求模赋值 | v %= e |
v = v % e的简写 |
>>= |
右移赋值 | v >>= e |
v = v >> e的简写 |
>>>= |
无符号右移赋值 | v >>>= e |
v = v >>> e的简写 |
<<= |
左移赋值 | v <<= e |
v = v << e的简写 |
&= |
位与赋值 | v &= e |
v = v & e的简写 |
|= |
位或赋值 | v |= e |
v = v | e的简写 |
^= |
位异或赋值 | v ^= e |
v = v ^ e的简写 |
下列运算符的计算结果皆为0或1,是用于表示真假,是非,对错的数值。
若数值为0,对应常量false,表示否定。若数值非0,对应常量true,表示肯定。
注意:虽然任何非0数都可以表示true,但它的实际数值为1。
| 运算符 | 名称 | 用法 | 描述 |
|---|---|---|---|
== |
等号 | e1 == e2 |
相等得1,反之得0 |
!= |
不等号 | e1 != e2 |
相等得0,反之得1 |
< |
小于 | e1 < e2 |
e1小于e2得1,否则得0 |
<= |
小于等于 | e1 <= e2 |
e1小于等于e2得1,否则得0 |
> |
大于 | e1 > e2 |
e1大于e2得1,否则得0 |
>= |
大于等于 | e1 >= e2 |
e1大于等于e2得1,否则得0 |
下列运算符的计算结果皆为0或1,是用于表示真假,是非,对错的数值。
若数值为0,对应常量false,表示否定。若数值非0,对应常量true,表示肯定。
注意:虽然任何非0数都可以表示true,但它的实际数值为1。
| 运算符 | 名称 | 用法 | 描述 |
|---|---|---|---|
! |
逻辑非 | !e |
是非颠倒。e为0得1,否则得0 |
&& |
逻辑与 | e1 && e2 |
全都要。两者皆非0,则得1,否则得0 |
|| |
逻辑或 | e1 || e2 |
不可无。两者皆为0,则得0,否则得1 |
短路求值:假设e2内部含有运算符,&&运算符仅在e1为true时计算e2;||运算符仅在e1为false时计算e2。
| 运算符 | 名称 | 用法 | 描述 |
|---|---|---|---|
[] |
单元索引器 | a[e] |
访问数组元素,a必须是数组而不是数组字面量 |
{} |
字节索引器 | a{e} |
访问数组字节(大端序),a必须是数组而不是数组字面量 |
() |
分组运算 调用函数 |
(e)f(e1, e2, ...) |
若e是多个表达式组成,优先计算e的值,再参与外界运算 以某种顺序对e1,e2,...求值,调用f函数,得到f的返回值 |
? : |
三元运算 | e1 ? e2 : e3 |
若e1非0,则得e2,否则得e3 |
: |
类标签生成与覆盖 | s:e |
若s不存在则创建值类型标签,否则覆盖e的标签 虽然这其实不是运算符,但解析器源码中是这么称呼它的 点击查看值类型标签指南 |
: |
跳转标签生成 | s: |
在函数体内生成一个跳转标签,可用goto关键字跳转至标签位置 虽然这其实不是运算符,但解析器源码中是这么称呼它的 点击查看跳转标签指南 |
, |
逗号 | e1, e2 |
得到e2的值 注意:某些逗号是分隔符,而不是运算符 |
defined |
已定义 | defined s |
检查标识符是否已经定义 |
sizeof |
求尺寸 | sizeof s |
s只能是变量 若s是单值变量,得1 若s是数组变量,得元素数量 |
tagof |
取值类型标签 | tagof s |
s不能是自动机或状态名称 1.8.3以下版本中s不能是值类型标签 取得s的值类型标签uid |
char |
压缩尺寸 | e char |
得到(e + 3) / 4的结果 表示储存e个字节最少需要多少个cell 1个cell可以储存4个字节 |
new a[] = { 41, 42, 43, 0 };
new value = a[0]; // 取0号元素值,得到41
a[0] = 40; // 对0号元素赋值
new b[1] = { 0b_11100110_10001000_10010001_00000000 };
new byteVal = b{0}; // 得到0b_11100110
byteVal = b{1}; // 得到0b_10001000
b{2} = 0b_00000000; // 将10010001部分改为00000000
运算符优先级决定将某些表达式视作一组,优先求值。
v = e1 + e2 * e3 // 分组结果:(v = (e1 + (e2 * e3))),最内层括号优先求值
v = (e1 + e2) * e3 // 使用圆括号改变分组结果:(v = ((e1 + e2) * e3))
运算符优先级从高到低(1级最高,15级最低):
| 级别 | 运算符 |
|---|---|
| 1 | () [] {} |
| 2 | ! ~ -(负号) ++ -- : char defined sizeof tagof |
| 3 | * / % |
| 4 | + -(减号) |
| 5 | >> >>> << |
| 6 | & |
| 7 | ^ |
| 8 | | |
| 9 | < <= > >= |
| 10 | == != |
| 11 | && |
| 12 | || |
| 13 | ? : |
| 14 | = *= /= %= += -= >>= >>>= <<= &= ^= |= |
| 15 | , |