基础:变量
变量
编程中最重要的概念之一是「变量」。在编程中,变量是一个可变的实体,但具体是就什么而言可变?在 Pawn 语言中,变量在任何时刻都持有一个「值」,而这个值——正如其名所示——是「可变的」或「可更改的」。
变量之所以如此重要,是因为它们本质上是计算机内存的小单元,可以在程序执行(运行)期间保存或「记住」不同的值,这一特性在编程中非常有用。例如,若想要追踪游戏中 100 名玩家的分数,您可以通过编程让计算机存储(记住)并更新这些值。之后如果您想计算这些玩家的平均分或创建排行榜,可以轻松从变量中访问这些值并用于相应目的。
声明变量
以下是变量声明的语法:
// 创建(更准确地说,「声明」)一个名为'myVariable'的变量
new myVariable;
// 'new'关键字用于声明变量
// 上述代码行声明了一个名为'myVariable'的变量
// 结尾使用分号来结束声明语句
通过查看一些示例可以更好地理解声明语法:
new var;
new ammo;
new score;
new vehicles;
new topScore;
上述每个已定义的变量都有一个默认值,即零。有多种方法可以为变量赋值。其中一种方法是在声明时直接为变量赋值:
new letters = 25;
在上述示例中,声明了一个名为「letters」的变量,其值为 25。您会注意到等号是一个简单的赋值运算符,可用于为变量赋值。它会计算右侧的表达式,并将结果值赋给左侧引用的变量。除了在声明时直接赋值外,您也可以在代码的后续部分进行赋值:
new letters;
letters = 25;
作用域
只有在引用变量的代码部分位于该变量的作用域内时,才能修改变量的值。变量的作用域取决于声明该变量的代码块或位置。例如,在任何代码块外部声明的变量(通常在脚本开头)具有「全局」作用域,可以从脚本内的任何位置访问:
#include <open.mp>
new g_var = 5;
public OnFilterScriptInit()
{
g_var = 10;
printf("当前值为 %i", g_var);
return 1;
}
public OnPlayerConnect(playerid)
{
g_var = 100;
printf("当前值为 %i", g_var);
return 1;
}
// 输出:
// 当前值为 10
// 当前值为 100
// 注意:第二个输出行仅在玩家连接时显示
除了「全局」(作用域)变量外,还有「局部」或「私有」变量,这些变量只能从声明它们的代码块内部访问:
#include <open.mp>
public OnFilterScriptInit()
{
new localVar;
localVar = 5;
return 1;
}
public OnPlayerConnect(playerid)
{
localVar = 10; // 此行在编译时会显示错误
return 1;
}
如果您尝试编译上述代码,编译器会显示错误,这是合理的,因为局部变量在一个完全不同的代码块中被引用。注意:如果是嵌套代码块,则可以从那里访问变量。
需要注意的重要一点是,如果变量的作用域相互交叉,则不能声明同名变量。例如,如果您在全局作用域中已有一个名为「score」的变量,则不能在全局作用域或局部作用域中创建另一个名为「score」的变量,反之亦然(如果已存在局部变量,请避免声明同名的全局变量):
#include <open.mp>
new g_score;
public OnFilterScriptInit()
{
new g_score = 5; // 此行会显示错误
return 1;
}
命名规则
既然您已经知道如何声明变量,您需要了解声明变量的命名规则,如下所列:
- 所有变量名必须以字母或下划线(
_
)开头 - 在第一个起始字母之后,变量名可以包含字母和数字,但不能包含空格或特殊字符
- 变量名区分大小写,即大写字母与小写字母不同
- 使用保留字(关键字)作为变量名会显示错误
示例:
new new; // 错误:使用保留字
new _new; // 正确
new 10letters; // 错误:名称以数字开头
new letters10; // 正确
new letters_10; // 正确
new my name; // 错误:名称中包含空格
new my_name; // 正确
new !nternet; // 错误
new Internet; // 正确
存储不同类型的数据
接下来,让我们看看可以在变量中存储哪些类型的数据以及如何存储:
new letter = 'M';
new value = 100;
new decimalValue = 1.0;
// 有效,但会显示编译器警告
// warning 213: 标签不匹配
new engineOn = true;
// 有效,且不会显示编译器警告,但建议使用标签
new sentence = "This is a sentence";
// 会显示错误
// error 006: 必须赋值给数组
变量能够保存字符、整数值、布尔值(真或假)和浮点值(小数值)。上述代码中的注释显示,在变量中存储字符串会导致错误(因为字符串只能存储在数组中)。除此之外,为变量赋浮点值会导致编译器警告,这可以通过添加「标签」来避免。没有正确的标签,脚本在编译时会显示警告,但仍是可执行的。标签告诉编译器打算存储在变量中的数据类型,如果我们代码中出现破坏程序的错误,这反过来会以错误或警告的形式通知我们。标签示例:
new decimalValue = 1.0; // 错误
new bool:decimalValue = 1.0 // 错误
new Float:decimalValue = 1.0; // 正确
new switchOn = 1.0; // 错误
new switchOn = true; // 错误,不会显示警告
new bool:switchOn = true; // 正确
使用正确的标签对于避免程序执行期间的任何错误或故障非常重要。
Pawn 作为一种无类型语言,允许我们在同一个变量中存储不同类型的数据,这在某些情况下可能有用,但在其他情况下可能带来麻烦,因此不建议这样使用变量:
#include <open.mp>
public OnFilterScriptInit()
{
new var;
var = 'a';
printf("%c", var);
var = 1;
printf("%d", var);
var = 1.0;
printf("%f", var);
var = true;
printf("%d", var); // 打印值0或1
return 1;
}
// 输出:
a
1
1.000000
1