AMXXPawn 字面量

1. 简介

字面量(Literal)用于表示一个或多个具体的数值。可用于做运算,或为标识符赋值。

AMXXPawn只有整数,不存在浮点数。而整数的类型是int32(在AMXXPawn中称为cell)。

字面量能表达的单个数值范围是-2147483648~2147483647。

字面量可简单分为单值字面量、数组字面量。

单值字面量可细分为以下几个类型:

数组字面量可细分为以下几个类型:

单值字面量是不可再分解的最小计算单元,属于原子表达式,例如:0b_1111、1024、0xFF、512.0

数组字面量或与运算符组合的单值字面量,属于复合表达式,例如:{ 1, 2, 3 }、-512、 256 + 256

任何字面量都在编译时就能确定数值,因此全都属于常量表达式

然而数组字面量本质是创建一个数据段匿名变量,因此仅在对命名变量初始化时会被编译器认定为常量表达式

2. 字符字面量

字符字面量通常指的是ASCII码表中的128个字符(不含中文,详情百度ASCII码表)。

字符字面量的正确写法是:以单引号'作为开头和结尾,中间填写1个ASCII字符。

例如:'a' 'b' 'c' '1' '2' '3'

每个字符字面量都对应一个具体的数值,与ASCII码表中字符编码一致。

例如:

转义指示符可以表示一些不可见或键盘按不出来的字符,这种表示方式称为转义字符。

转义字符 解释
'^a' 蜂鸣符
等于十进制7
'^b' [BACKSPACE]退格键
等于十进制8
'^e' [ESC]退出键
等于十进制27
'^f' 换页符
等于十进制12
'^n' 换行符
等于十进制10
'^r' 回车符
等于十进制13
'^t' [TAB]水平制表符
等于十进制9
'^v' 垂直制表符
等于十进制11
'^^' [^]键自己
等于十进制94
'^'' [']单引号
等于十进制39
'^"' ["]双引号
等于十进制34
'^%' [%]百分号
等于十进制37
'^ddd;' ddd可以填十进制数值
分号;可省略
'^114514'直接等于114514
'^114514' % 256 = 82 = 'Q'
'^xhhh;' hhh可以填十六进制数值,不区分大小写
分号;可省略
'^x1BF52'直接等于114514
'^x1BF52' % 256 = 82 = 'Q'

编译器指令#pragma ctrlchar '^'可以更改转义指示符,若不更改,默认为^字符。

若更改转义指示符,则'^^'也要相应改变,例如将转义指示符改为\,要表示字符\就得写成'\\'

注意:终止符'^0''^x0'等于十进制0,而零字符'0'等于十进制48,不要混淆。

3. 二进制整数字面量

十进制指的是逢十进一,二进制类似,是逢二进一。

二进制整数字面量的正确写法:以0b作为开头,后续跟随任意数量的_、0、1,下划线没有实际意义。

注意事项:

整数最大值+1会变为最小值。这与二进制对最小值和最大值的定义以及逢二进一的机制有关。

 0b_01111111_11111111_11111111_11111111 + 1

= 0b_10000000_00000000_00000000_00000000

= -2147483648

数值展示:

4. 十进制整数字面量

十进制整数字面量正确写法:以任意数字开头,后续跟随任意数量的_或数字。

若写出来的数值超出cell(int32)能表示的数值范围,得到的数值等于:除以最大值然后求模的结果。

例如6442450944实际等于6442450944 % 2147483648等于0。

整数最小值的各种写法:

整数最大值的各种写法:

5. 十进制浮点数字面量

AMXXPawn默认情况下不允许编写浮点数字面量,会在编译时触发报错。

必须使用#pragma rational指令设置一个浮点数标签,才允许使用浮点数字面量。

由于float.inc文件中包含这个指令,而amxmodx.inc文件引用了float.inc文件,只需引用amxmodx.inc文件便能达到一样效果。

浮点数字面量在被编译器解析时,解析器会访问浮点数的二进制表示,将其解释为一个32位整数。

因此,虽然看着是浮点数,但数值在AMXXPawn仍是整数,核心模块提供的接口函数在得到这个整数时会自动转换回浮点数。

因为会转换回浮点数,我们通常不需要担心计算结果错误,但这导致AMXXPawn对于浮点数的运算效率要低一些。

浮点数字面量自带Float标签(#pragma rational Float指令设定的),与其它表达式做运算会被警告标签不匹配。

浮点数字面量的正确写法:(数字)【数字或下划线】(.)(数字)【数字或下划线】【(e)【-】(数字)】

()是必选项目,【】是可选项目。

【(e)【-】(数字)】部分表示小数点要移动多少个位。负数向左移动,正数向右移动。

浮点数能表示的最小值是无穷小,但只能用整数字面量表示:Float:0b_11111111_10000000_00000000_00000000

浮点数能表示的最大值是无穷大,但只能用整数字面量表示:Float:0b_01111111_10000000_00000000_00000000

浮点数字面量最小有限值:-340282346638528800000000000000000000000.0(或-3402823466385288.0e23)

浮点数字面量最大有限值:340282346638528800000000000000000000000.0(或3402823466385288.0e23)

由于浮点数精度问题,距离0.0越远的字面量与接口函数实际所得浮点数差距越大。

例如0.0001字面量被接口函数接收时,因为误差会变为0.000099999997473

6. 十六进制整数字面量

十进制指的是逢十进一,十六制类似,是逢十六进一。

十六进制字面量用ABCDEF字母(不区分大小)分别表示10、11、12、13、14、15、16,所以是逢F进一。

十六进制整数字面量的正确写法:以0x作为开头,后续跟随任意数量的_、数字、A~F,下划线没有实际意义。

注意:只有末端的8个数字和字母是有效的

若写出来的数值超出cell(int32)能表示的数值范围,得到的数值等于:除以最大值然后求模的结果。

例如0x_F0000000实际等于4294967296 % 2147483648等于0。

整数最小值的各种写法:

整数最大值的各种写法:

7. 数组字面量

任何数组字面量都储存在数据段,并且相同内容的字面量储存在不同的数据段地址,每一个都是可修改的。

多个单值常量表达式用逗号隔开,再用{ }包裹它们,就能形成一维数组字面量。

#include <float> const CONSTANT = 512 + 512; // 数组字面量的花括号{ }可以含有任意常量表达式 static array1[] = { '8', 0b_11111111, 255, 0xFF, 127 + 128, CONSTANT }; static Float:array2[] = { 32.0, 64.0, 128.0, 256.0 };

数组字面量和数组略有不同。数组指的是数组类型的变量,变量拥有名称,而数组字面量是储存在数据段的匿名变量。

因为数组字面量是变量,所以被按引用传递到函数内时,可以被函数更改内容。而真正的常量表达式是不会被更改的。

一维数组字面量之上还有二、三维数组字面量,AMX Mod X 1.8.2以上版本扩展到四维。

正确的编写方法应该参照变量声明语句所设定的规则:变量维度变量初始化

8. 转义字符串字面量

任何字符串字面量都储存在数据段,并且相同内容的字面量储存在不同的数据段地址,每一个都是可修改的。

转义字符串字面量(普通字符串字面量)是最常用的字符串字面量,特点是像字符字面量一样,内部允许填写转义字符。

转义字符串字面量的正确写法:以"作为开头和结尾,中间填写任意数量的字符(包括转义字符),例如:"中文^t"

有时候我们会关注字面量的长度尺寸

长度指的是第一个终止符之前有多少个cell储存数据。

尺寸总共有多少个cell储存数据。

若源码是UTF8编码,每个ASCII字符占用1个cell,每个转义字符占用1个cell,每个中文占用3个cell。

字面量末端会自动增加1个终止符,占用1个cell。

例子:

注意事项:

9. 压缩字符串字面量

一个cell拥有4字节的储存空间,但UTF8编码下,1个ASCII字符只需要1字节空间,1个中文只需要3个字节空间。

也就是说,非压缩字符串字面量用1个cell去储存1个数据,浪费了3/4的空间。

使用压缩字符串字面量就能紧凑储存这些数据,大幅度改善这一情况。

若一个字符串字面量的左边紧贴着!感叹号,则内容会在编译时被压缩,例如:!"中文^t"!^"中文^t"

压缩后,每个ASCII字符占1个字节,每个中文占3个字节,每4个字节占1个cell,剩下的不足4字节也占1个cell。

注意事项:

10. 素字符串字面量

素字符串字面量(未加工字符串字面量)与转义字符串字面量相反,是不支持转义字符的。

若一个字符串字面量的左边紧贴着^转义指示符,则是素字符串字面量,例如:^"中文^t"^!"中文^t"

所有转义字符会原模原样的存入,不转变为其它字符。例如^48本该转变为0字符,但素字符串会直接储存^、4、8三个字符。

注意事项:

11. 压缩素字符串字面量

转义字符串字面量的左边加上!和转义指示符,则是压缩素字符串字面量,例如:^!"中文"!^"中文"

同时拥有压缩字符串字面量素字符串字面量的特性。

12. 结构体字面量

结构体字面量是允许含有任意常量表达式的一维数组字面量,例如: { "急速僵尸", { 0.0, 0.0, 17.0 }, 1000, 1.0 }

仅在为结构体(数组+枚举组合而成)赋值时,才允许根据其结构编写对应的字面量。

这种字面量虽然有时候看起像是多维的,但必须使用相同结构的一维数组变量才能储存,否则会被编译器视作语法错误。

详情查阅:数组初始化enum模拟结构体