AMXXPawn 变量

目录

1. 简介

变量(Variable)是由用户创建的标识符,其数值在插件运行后才能确定,并且可更改。

关键概念:

按储存位置划分,变量可以分为数据段变量栈变量

全局变量和函数体内用static声明的变量属于数据段变量数据段变量的声明、定义仅在插件启动时执行一次,确定初始值。

函数体内用new关键字声明的是栈变量栈变量的声明、定义可在插件运行时重复执行,重复计算不同初始值。

参数分为传值和传引用,传值参数是实参的临时副本,必定是栈变量;传引用参数等于实参本体,实参有可能是数据段变量

关于参数变量的相关概念:点击查看参数指南

非参数变量声明语句语法格式:

变量声明语法拆解:

维度声明语法拆解:

初始化表达式拆解:

注意:

2. 声明说明符

new public static stock 可用于编写全局变量声明语句。

new static 可用于编写局部变量声明语句。

若额外添加 const 关键字进行修饰,可令变量获得只读特性。变量值在初始化之后不能被运算符修改。

代码示例:

// 声明假公共只读变量(数据段变量,全局变量) public const Float:NULL_VECTOR[3] = { 0.0, 0.0, 0.0 }; // 声明插件私有备用只读变量(数据段变量,全局变量) stock const Float:V3_4Dir[][] = { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { -1.0, 0.0, 0.0 }, { 0.0, -1.0, 0.0 } }; // 声明文件私有变量(数据段变量,全局变量) static m_flNextAttack = 83; // 声明插件私有变量(数据段变量,全局变量) new bool:gWeaponShooting; public plugin_init() { // 声明静态只读变量(数据段变量,静态局部变量) static const PluginName[] = "插件名称"; // 声明临时变量(栈变量,局部变量) new pluginId = register_plugin(PluginName, "插件版本", "插件作者"); }

关于声明说明符的特性,点击查看更多详细内容

3. 值类型标签

若不填写值类型标签,变量将会获得默认标签 _:

因此,下面两行代码是相同的:

new _:variable;
new variable;

若填写未定义的值类型标签,编译器会自动创建这个标签。

当变量与拥有不同标签的表达式做运算时,通常会触发编译器警告:

// variable拥有_标签,表达式15.0拥有Float标签,触发警告:"标签不匹配"
new _:variable = 15.0;

变量通常是用来储存函数返回值或充当函数的参数,因此需要定义与函数或参数相同的标签。

另外,定义不同的值类型标签,会导致变量参与运算时,根据运算符重载触发不同的运算函数。

若这个标签没有运算符重载,将会触发默认的运算函数。

关于值类型标签,点击查看更多详细内容

4. 维度声明

声明变量时,在变量名称末尾添加中括号,会让变量变成数组,使变量可以储存多个数值。

中括号的数量表示数组的维度,[ ][ ]表示变量是2维数组。[ ][ ][ ]表示变量是3维数组。

3维数组储存的元素是多个2维数组,2维数组储存的元素是多个1维数组,1维数组储存的元素是多个数值。

中括号内可填写常量表达式(单值字面量或常量),表示各维度数组的尺寸(元素数量)。

在有多对中括号时,填写的尺寸从左至右对应从外层至内层数组。

代码示例:

// 创建3尺寸的1维数组,他能储存3个值 static array1[3]; // 创建2维数组:2维数组尺寸为3,1维数组尺寸为2 static array2[3][2]; // 创建3维数组:3维数组尺寸为4,2维数组尺寸为3,1维数组尺寸为2 static array3[4][3][2];

若使用枚举结构体名称充当1维数组尺寸,编译器会按照枚举的成员结构,将数组解析为结构体。

此时允许使用枚举成员访问结构体的属性:

enum tZombieClass_Normal { _: ZCN_Name[32], _: ZCN_MaxHealth, _: ZCN_MaxSpeed, Float: ZCN_EyePos[3] } static sZombieClass[tZombieClass_Normal]; public plugin_init() { // 访问ZCN_EyePos常量所指的结构体属性,该属性是3尺寸数组,修改这个数组的值 // AMX Mod X 1.8.3以下版本中,用=运算符会错误解析属性标签为_,因此需以_覆盖右值标签,避免警告 sZombieClass[ZCN_EyePos] = _:{ 0.0, 0.0, 17.0 }; // AMX Mod X 1.8.2以上版本中,可正常解析属性标签,但数组字面量在任何版本中都是_标签,需以Float标签覆盖(在初始化表达式中不检查数组字面量标签,所以不需要) sZombieClass[ZCN_EyePos] = Float:{ 0.0, 0.0, 17.0 }; }

关于枚举结构体:点击查看enum指南

5. 初始化表达式

若省略初始化表达式,则变量储存的每个初始值被设为0。

在为单值变量设置初始值时,若未使用 new 关键字,仅允许填写常量表达式。

注意:若表达式含有重载的运算符,则不是常量表达式! #include <float> /* +的两个操作数都含有Float标签,而且float.inc内含有此定义: * native Float:operator+(Float:oper1, Float:oper2) = floatadd; * 因此10.0 + 5.0将会变为floatadd(10.0, 5.0) * 而static声明的变量并不支持使用函数进行初始化,因此会报错:"必须使用常量表达式" */ static Float:var = 10.0 + 5.0;

在为数组设置初始值时,仅允许填写常量表达式,数组字面量,字符串字面量:

// 使用常量表达式,将数组第一个元素值设为15 static array1[3] = 10 + 5; // 使用常量表达式,将数组第一个元素值设为15.0 static Float:array2[3] = 15.0; // 使用数组字面量,对2维数组的每个元素进行初始化 static Float:array3[4][3] = { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { -1.0, 0.0, 0.0 }, { 0.0, -1.0, 0.0 } }; // 使用字符串字面量,对2维数组的每个元素进行初始化 static array4[4][] = { "字符串字面量1", "字符串字面量2", "字符串字面量3", "字符串字面量4" };

数组字面量或字符串字面量的尺寸可以小于维度声明中设定的尺寸,编译器会自动将空缺的元素值设定为0。

使用常量表达式进行初始化与此类似,只能对数组第一个数值元素赋值,后续数值元素皆为0。

编译器提供了2种自动推测后续元素值的写法:

// 每个1维数组拥有8个数值 static array[2][8] = { // 后续7个数值皆等于1 { 1, ... }, // 用4-0得到差值4,后面每个数值都等于上一个数值+4,即{ 5, 0, 4, 8, 12, 16, 20, 24 } { 5, 0, 4, ... } };

若维度声明中未填写尺寸,编译器会根据初始化表达式自动推测尺寸,此时禁止使用 ... 运算符。

// 尺寸=1 static array1[] = 10 + 5; // 尺寸=3 static Float:array2[] = { 15.0, 15.0, 15.0 }; // 2维数组尺寸=4,1维数组尺寸=3 static Float:array3[][] = { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { -1.0, 0.0, 0.0 }, { 0.0, -1.0, 0.0 } };

若使用枚举结构体名称充当1维数组尺寸,编译器会按照枚举的成员结构,将数组解析为结构体。

此时允许使用结构体字面量进行初始化:

enum tZombieClass_Normal { _: ZCN_Name[32], _: ZCN_MaxHealth, _: ZCN_MaxSpeed, Float: ZCN_EyePos[3] } static sZombieClass[tZombieClass_Normal] = { "普通僵尸", 1000, 240, { 0.0, 0.0, 34.0 } };

关于枚举结构体:点击查看enum指南

注意:通常情况下,初始化表达式与变量的值类型标签必须一致,否则会被警告:“标签不匹配”

6. 连续声明变量

与常量声明语句不同,变量声明语句允许连续声明多个变量:

new var1, bool:var3 = true, Float:var3 = 5.0;

提示:连续声明的变量不能更换声明说明符,因此它们获得的特性是相同的。

7. 数据段变量和栈变量区别

数据段变量的声明语句仅在插件启动(载入游戏地图)时执行一次。

意味着下一次来到声明语句位置,并不会重新初始化,而是保持上次修改的数值。

#include <amxmodx> public plugin_init() { test(); // 第1次进入函数内部执行代码 test(); // 第2次进入函数内部执行代码 test(); // 第3次进入函数内部执行代码 } test() { // 在进入游戏场景时创建数据段变量dataVar,设定初始值为1000,此语句不会运行第二次 static dataVar = 1000; // 在控制台打印dataVar的值 server_print("dataVar = %d", dataVar); // dataVar储存的值增加2 dataVar += 2; } // 离开dataVar作用域,并不会删除dataVar

打印内容:

dataVar = 1000;
dataVar = 1002;
dataVar = 1004;

栈变量的声明语句允许重复执行,离开变量作用域时会被删除。

因此,无论栈变量被如何修改,重新创建后仍会得到新的初始值。

#include <amxmodx> public plugin_init() { test(); // 第1次进入函数内部执行代码 test(); // 第2次进入函数内部执行代码 test(); // 第3次进入函数内部执行代码 } test() { // 创建栈变量tempVar,设定初始值为1000 new tempVar = 1000; // 在控制台打印tempVar的值 server_print("tempVar = %d", tempVar); // tempVar储存的值增加2,这没有意义,因为他将要被删掉了 tempVar += 2; } // 离开tempVar作用域,删除tempVar

打印内容:

tempVar = 1000;
tempVar = 1000;
tempVar = 1000;
注意:全局变量全都是数据段变量,仅仅是作用域有差别。