---
title: "基础：变量 | open.mp"
description: "Pawn语言变量入门指南"
canonical: https://omp.itsneufox.com/zh-CN/docs/scripting/language/Variables
language: zh-CN
---

# 基础：变量

## 变量

编程中最重要的概念之一是「变量」。在编程中，变量是一个可变的实体，但具体是就什么而言可变？在 Pawn 语言中，变量在任何时刻都持有一个「值」，而这个值——正如其名所示——是「可变的」或「可更改的」。

变量之所以如此重要，是因为它们本质上是计算机内存的小单元，可以在程序执行（运行）期间保存或「记住」不同的值，这一特性在编程中非常有用。例如，若想要追踪游戏中 100 名玩家的分数，你可以通过编程让计算机存储（记住）并更新这些值。之后如果你想计算这些玩家的平均分或创建排行榜，可以轻松从变量中访问这些值并用于相应目的。

### 声明变量

以下是变量声明的语法：

```c
// 创建（更准确地说，「声明」）一个名为'myVariable'的变量

new myVariable;

// 'new'关键字用于声明变量
// 上述代码行声明了一个名为'myVariable'的变量
// 结尾使用分号来结束声明语句
```

通过查看一些示例可以更好地理解声明语法：

```c
new var;
new ammo;
new score;
new vehicles;
new topScore;
```

上述每个已定义的变量都有一个默认值，即零。有多种方法可以为变量赋值。其中一种方法是在声明时直接为变量赋值：

```c
new letters = 25;
```

在上述示例中，声明了一个名为「letters」的变量，其值为 25。你会注意到等号是一个简单的赋值运算符，可用于为变量赋值。它会计算右侧的表达式，并将结果值赋给左侧引用的变量。除了在声明时直接赋值外，你也可以在代码的后续部分进行赋值：

```c
new letters;

letters = 25;
```

### 作用域

只有在引用变量的代码部分位于该变量的作用域内时，才能修改变量的值。变量的作用域取决于声明该变量的代码块或位置。例如，在任何代码块外部声明的变量（通常在脚本开头）具有「全局」作用域，可以从脚本内的任何位置访问：

```c
#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

// 注意：第二个输出行仅在玩家连接时显示
```

除了「全局」（作用域）变量外，还有「局部」或「私有」变量，这些变量只能从声明它们的代码块内部访问：

```c
#include <open.mp>

public OnFilterScriptInit()
{
    new localVar;

    localVar = 5;

    return 1;
}

public OnPlayerConnect(playerid)
{
    localVar = 10; // 此行在编译时会显示错误

    return 1;
}
```

如果你尝试编译上述代码，编译器会显示错误，这是合理的，因为局部变量在一个完全不同的代码块中被引用。注意：如果是嵌套代码块，则可以从那里访问变量。

需要注意的重要一点是，如果变量的作用域相互交叉，则不能声明同名变量。例如，如果你在全局作用域中已有一个名为「score」的变量，则不能在全局作用域或局部作用域中创建另一个名为「score」的变量，反之亦然（如果已存在局部变量，请避免声明同名的全局变量）：

```c
#include <open.mp>

new g_score;

public OnFilterScriptInit()
{
    new g_score = 5; // 此行会显示错误
    return 1;
}
```

### 命名规则

既然你已经知道如何声明变量，你需要了解声明变量的命名规则，如下所列：

-   所有变量名必须以字母或下划线（`_`）开头
-   在第一个起始字母之后，变量名可以包含字母和数字，但不能包含空格或特殊字符
-   变量名区分大小写，即大写字母与小写字母不同
-   使用保留字（关键字）作为变量名会显示错误

#### 示例：

```c
new new; // 错误：使用保留字
new _new; // 正确

new 10letters; // 错误：名称以数字开头
new letters10; // 正确
new letters_10; // 正确

new my name; // 错误：名称中包含空格
new my_name; // 正确

new !nternet; // 错误
new Internet; // 正确
```

### 存储不同类型的数据

接下来，让我们看看可以在变量中存储哪些类型的数据以及如何存储：

```c
new letter = 'M';

new value = 100;

new decimalValue = 1.0;
// 有效，但会显示编译器警告
// warning 213: 标签不匹配

new engineOn = true;
// 有效，且不会显示编译器警告，但建议使用标签

new sentence = "This is a sentence";
// 会显示错误
// error 006: 必须赋值给数组
```

变量能够保存字符、整数值、布尔值（真或假）和浮点值（小数值）。上述代码中的注释显示，在变量中存储字符串会导致错误（因为字符串只能存储在_数组_中）。除此之外，为变量赋浮点值会导致编译器警告，这可以通过添加「标签」来避免。没有正确的标签，脚本在编译时会显示警告，但仍是可执行的。标签告诉编译器打算存储在变量中的数据类型，如果我们代码中出现破坏程序的错误，这反过来会以错误或警告的形式通知我们。标签示例：

```c
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 作为一种无类型语言，允许我们在同一个变量中存储不同类型的数据，这在某些情况下可能有用，但在其他情况下可能带来麻烦，因此不建议这样使用变量：

```c
#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
```
