<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alliedmods.net/index.php?action=history&amp;feed=atom&amp;title=Zh_cn%3AIntroduction_to_SourcePawn_1.7</id>
	<title>Zh cn:Introduction to SourcePawn 1.7 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alliedmods.net/index.php?action=history&amp;feed=atom&amp;title=Zh_cn%3AIntroduction_to_SourcePawn_1.7"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zh_cn:Introduction_to_SourcePawn_1.7&amp;action=history"/>
	<updated>2026-05-09T14:06:28Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Zh_cn:Introduction_to_SourcePawn_1.7&amp;diff=10191&amp;oldid=prev</id>
		<title>Xiaooloong: Created page with &quot;本指南将介绍最基础的 SourcePawn 语言编写方法。 Pawn 是一门“脚本”语言，被设计用来将功能嵌入到其它程序中。它不是一门独立...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Zh_cn:Introduction_to_SourcePawn_1.7&amp;diff=10191&amp;oldid=prev"/>
		<updated>2016-07-29T10:42:39Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;本指南将介绍最基础的 SourcePawn 语言编写方法。 &lt;a href=&quot;/Pawn&quot; class=&quot;mw-redirect&quot; title=&quot;Pawn&quot;&gt;Pawn&lt;/a&gt; 是一门“脚本”语言，被设计用来将功能嵌入到其它程序中。它不是一门独立...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;本指南将介绍最基础的 SourcePawn 语言编写方法。 [[Pawn]] 是一门“脚本”语言，被设计用来将功能嵌入到其它程序中。它不是一门独立的语言（如 C++ 或 Java ），并且它的细节会由所在应用的不同而不同。SourcePawn 是 [[SourceMod]] 模组中使用的 Pawn 版本。&lt;br /&gt;
&lt;br /&gt;
本指南并不教你如何去写 SourceMod 插件，而是介绍这门语言的语法和语义的概览。想要了解 SourceMod API 的细节，请参考[[Introduction to SourceMod Plugins]]。&lt;br /&gt;
&lt;br /&gt;
=零基础教程=&lt;br /&gt;
本章节针对没有编程经验的初学者。如果阅读完后仍有疑问，你可能需要学习另一门编程语言，如 PHP, Python 或者 Java，以便更好的理解编写程序的方法。&lt;br /&gt;
&lt;br /&gt;
==标识符/关键字==&lt;br /&gt;
标识符是一串字母、数字、下划线的组合，用于唯一标识某些东西。标识符是大小写敏感的，通常以字母开头。&lt;br /&gt;
（译者注： c 语言中，标识符不能以数字开头。）&lt;br /&gt;
&lt;br /&gt;
SourcePawn 中有一些保留的关键字，它们有特殊的含义。例如 &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;，&amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;，&amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; 。这些关键字是特殊的结构，会在下文介绍。他们不能用于标识符的命名。&lt;br /&gt;
&lt;br /&gt;
==变量==&lt;br /&gt;
在你开始编码前，有一些重要的概念你需要了解。首先就是'''变量'''。变量是一个用来保存数据的“标识符”或“名称”。例如，变量 &amp;quot;a&amp;quot; 能够保存数字 &amp;quot;2&amp;quot; 或 &amp;quot;16&amp;quot; 或 &amp;quot;0&amp;quot; 等。变量会申请存储数据所需的内存空间。&lt;br /&gt;
&lt;br /&gt;
变量除了有“名字”，还有'''类型'''。变量的类型告诉程序如何处理变量存储的数据，以及决定变量使用的内存空间大小。Pawn 有三种最常使用的数据类型：&lt;br /&gt;
* 整形，使用 &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; 关键字。整形可以存储 -2147483648 ~ 2147483647 (- 2^31 ~ 2^31 - 1) 的整数，类似于 c 语言中的 32 位有符号整数。&lt;br /&gt;
* 浮点，使用 &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; 关键字。浮点型可以表示很大范围内的小数，但浮点类型是不精确的，不像整形是精确的。&lt;br /&gt;
* 字符，使用 &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; 关键字。字符型存储一字节的数据，通常是一个 [http://www.asciitable.com/ ASCII] 字符。&lt;br /&gt;
*布尔，使用 &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; 关键字。布尔存储一个真值：真(true) 或者 假(false)。&lt;br /&gt;
声明变量和给变量赋值的例子：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int money = 5400;&lt;br /&gt;
float percent = 67.3;&lt;br /&gt;
bool enabled = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==函数==&lt;br /&gt;
另一个重要的概念是'''函数'''。函数是能执行一系列动作的“标识符”或“名称”。当调用函数时，函数会执行一系列的动作，并返回一个值。SourceMod 中有几种类型的函数，不过他们都使用同样的方法来使用。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
show(56);     // 调用 &amp;quot;show&amp;quot; 函数，并传入一个整形常量 56。&lt;br /&gt;
enable();     // 调用 &amp;quot;enable&amp;quot; 函数，不传入参数。&lt;br /&gt;
bool visible = show(a);    //调用 &amp;quot;show&amp;quot; 函数，并将函数的返回值赋给一个变量。&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
传入给函数的数据被称为 '''参数'''。函数支持任意数量的参数（由于某种原因，SourceMod 函数最大支持 32 个参数）。关于参数将会在后文说明。&lt;br /&gt;
&lt;br /&gt;
==注释==&lt;br /&gt;
所有以 &amp;quot;//&amp;quot; 开头的文本都被称作“注释”，他们不是程序的代码，不会被执行。有两种注释的方法：&lt;br /&gt;
*&amp;lt;tt&amp;gt;// 注释内容&amp;lt;/tt&amp;gt; - 单行注释，这一行内所有双斜线后的部分都被忽略&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* 注释内容 */&amp;lt;/tt&amp;gt; - 块注释，所有星号之前的部分都被忽略&lt;br /&gt;
&lt;br /&gt;
==代码块==&lt;br /&gt;
下一个概念是代码块。你可以把代码组织在“块”中，通过 { 和 } 来包裹。这能有效的使得一大块的代码运行起来就像一句语句一样。比如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
使用花括号包裹起来的代码块被用于编程的各个地方。块代码可以相互嵌套。编程时应尽早形成统一的、可读的编码习惯。&lt;br /&gt;
&lt;br /&gt;
=语言泛型=&lt;br /&gt;
Pawn 可能和其他语言相似（例如 c），但是它们有本质的区别。一开始就明白这些区别并不重要，但是如果你有其他语言的变成基础，了解这些区别会很有帮助。&lt;br /&gt;
* '''Pawn 是无类型的''' 在 SourceMod 1.7 之前，Pawn 是没有类型的。在旧版本的代码和内置方法中，使用了 “tag” 的方法和关键字 &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; 来表达类型。而现在，我们推荐使用类型来书写代码。关于旧版的信息请查阅 [[SourcePawn Transitional Syntax]]。&lt;br /&gt;
*'''Pawn 没有垃圾回收''' Pawn 语言没有内置的内存分配功能，因此也没有垃圾回收功能。如果一个函数申请过内存，你需要自行释放。&lt;br /&gt;
*'''Pawn 不是面向对象的''' Pawn 没有结构体或者对象。SourceMod 1.7 以后，通过有限的语法糖实现了将特定的数据类型视为对象，但是用户不能自行定义对象和类。&lt;br /&gt;
*'''Pawn 是单线程的''' Pawn 运行在一个线程，因此没有线程安全检查。&lt;br /&gt;
*'''Pawn 是编译的''' Pawn 被编译为平台无关的中间代码，保存在 “.smx” 文件中。运行时，由 SourceMod 加载 “.smx” 文件，并解释为对应平台的机器码而执行。&lt;br /&gt;
&lt;br /&gt;
早期语言设计由 ITB CompuPhase 完成。语言是为底层嵌入式设备设计，因此极为精简和迅速。&lt;br /&gt;
&lt;br /&gt;
=变量=&lt;br /&gt;
Pawn 现在支持以下几种基本类型：&lt;br /&gt;
*&amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; - 布尔，true 或者 false。&lt;br /&gt;
*&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; - 字符，八位（一字节） ASCII 字符。&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - 整形，32 位有符号整数。&lt;br /&gt;
*&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; - 浮点，32位 IEEE-754 浮点数。&lt;br /&gt;
*&amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; - 基本类型的 SourceMod 对象&lt;br /&gt;
&lt;br /&gt;
其他的类型定义在一些头文件中。例如， enums （枚举）定义了一个新的“命名整形”的类型，以及许多从 &amp;lt;tt&amp;gt;Handle&amp;lt;/tt&amp;gt; 派生的类型。&lt;br /&gt;
&lt;br /&gt;
Strings （字符串）现在是以字符 '\0' 结尾的字符数组。细节将在后文说明。&lt;br /&gt;
&lt;br /&gt;
==声明==&lt;br /&gt;
下面给出了一些正确的，以及错误的变量声明的例子。SourcePawn 最近增加了如下文描述的新语法。一些旧版本的代码可能使用了旧的语法，这些旧版本的语法不再支持。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&lt;br /&gt;
float b = 5.0;&lt;br /&gt;
bool c = true;&lt;br /&gt;
bool d = false;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
错误的变量使用：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5.0;         // 类型错误。常量 5.0 是浮点型&lt;br /&gt;
float b = 5;         // 类型错误。常量 5 是整形&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
未明确赋值的变量声明将被赋以以下的值&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a;        // 默认赋值为 0&lt;br /&gt;
float b;      // 默认赋值为 0.0&lt;br /&gt;
bool c;       // 默认赋值为 false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==赋值==&lt;br /&gt;
变量创建后，可以被重新赋值。例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a;&lt;br /&gt;
float b;&lt;br /&gt;
bool c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=数组=&lt;br /&gt;
数组是一个连续的数据序列。数组能在一个变量中存储多个数据，或者将一种类型的数据映射为另一种。&lt;br /&gt;
&lt;br /&gt;
==声明==&lt;br /&gt;
数组使用方括号声明，例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int players[32];     // 存储了 32 个整形数&lt;br /&gt;
float origin[3];     // 存储了 3 个浮点数&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
数组默认会被初始化为 0。你可以显示的初始化为其他的值：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5] = {1, 2, 3, 4, 5};       // 存储了 1， 2， 3， 4， 5。&lt;br /&gt;
float origin[3] = {1.0, 2.0, 3.0};      // 存储了 1.0， 2.0， 3.0。&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果显示的初始化数组，你可以留空数组的大小。例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
编译器会在编译时自动将这个数组的大小设为 5&lt;br /&gt;
&lt;br /&gt;
定义数组时，如果方括号在变量名后，Pawn 将其认为是 '''定长''' 的。定长数组的大小在任意时刻都可以明确的知道。&lt;br /&gt;
另一些数组是 '''变长''' 的，声明时将方括号放在变量名前。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int[] numbers = new int[MaxClients]&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这段代码声明了一个 &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt; 大小的数组，长度由 &amp;lt;tt&amp;gt;MaxClients&amp;lt;/tt&amp;gt; 决定。变长数组直到数组被分配内存时，才能确定数组的大小。&lt;br /&gt;
&lt;br /&gt;
==使用==&lt;br /&gt;
数组和普通变量使用方法一样。唯一区别是使用数组时需要一个 '''索引''' 。索引定义了从数组中需要取出的元素。&lt;br /&gt;
&lt;br /&gt;
这是使用数组和索引的例子：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
float origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
以上示例中，'''索引'''是在方括号间的数字。数组的索引从 0 开始。如果数组有 N 个元素，那么数组的合法索引是从 0 到 N-1 。用索引存取的数据和普通变量的使用方法相同。&lt;br /&gt;
&lt;br /&gt;
使用非法的索引会造成错误。例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5 不是一个正确的索引。这个数组最大的索引是 4。&lt;br /&gt;
&lt;br /&gt;
你可以使用任意的表达式作为索引。例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   // 赋 a 为 1&lt;br /&gt;
numbers[a] = 4;          // 赋 numbers[1] 为 4&lt;br /&gt;
numbers[numbers[a]] = 2; // 赋 numbers[4] 为 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
表达式的概念将在下文说明。&lt;br /&gt;
&lt;br /&gt;
=字符串=&lt;br /&gt;
字符串是可以存储文本（或者二进制数据）的结构。字符串即为字符数组，与之不同的是，字符串必须以 '\0' （空终止符） 结束。Pawn 以 '\0' 判断字符串的结尾。字符串在 SourcePawn 中均为 [https://zh.wikipedia.org/wiki/UTF-8 UTF-8] 编码。&lt;br /&gt;
&lt;br /&gt;
通常，在存储字符串前，你必须明确字符串的长度。 SourcePawn 现在并没有自动确定字符串大小的功能。&lt;br /&gt;
&lt;br /&gt;
==使用==&lt;br /&gt;
字符串通常被声明为数组。例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
char clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
以下代码作用和上述相同：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
char message[7];&lt;br /&gt;
char clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
虽然字符串极少使用这种方式初始化，但是非常重要的是要记住空终止符，也就是字符串终结的标志。编译器以及大多数 SourceMod 函数将会自动为你加上空终止符，所以当你直接处理字符串时这个概念是不可忽略的。&lt;br /&gt;
&lt;br /&gt;
字符串使用半角双引号定义，字符使用半角单引号定义。&lt;br /&gt;
&lt;br /&gt;
==字符==&lt;br /&gt;
字符文本既可以被当做字符串也可以被当做 cell （注：cell 类型是旧版本中的概念，译时此处文档未更新。）使用。例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;char text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
char clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //赋 clam 为 'D'&lt;br /&gt;
text[0] = 'A';      //赋 'C' 为 'A'。字符串现在为 'Arab'&lt;br /&gt;
clam = text[0];     //赋 clam 为 'A'&lt;br /&gt;
text[1] = clam;     //赋 'r' 为 'A'。字符串现在为 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
你所不能做的就是把字符数组与字符串混合起来。它们的内部存储并不一样。例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int clams[] = &amp;quot;Clams&amp;quot;;                       // 无效。&lt;br /&gt;
int clams[] = {'C', 'l', 'a', 'm', 's', 0};  // 有效，但不是一个 String&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=函数=&lt;br /&gt;
函数，如上文所述，是一种独立的代码块来实现某种功能。它们能被触发，或者说被'''调用'''，并通过'''参数'''来给定选项。&lt;br /&gt;
&lt;br /&gt;
有2种调用函数的方式：&lt;br /&gt;
*'''直接调用''' - 在你的代码中明确的调用一个函数&lt;br /&gt;
*'''回调（callback）''' - 由应用程序来调用你代码中的函数，例如事件触发器。&lt;br /&gt;
&lt;br /&gt;
有 6 中类型的函数：&lt;br /&gt;
*'''native（原生、本地）'''：由应用程序提供的直接的，内部的函数。&lt;br /&gt;
*'''public（公共）'''：对于其他应用程序或者其他脚本可见的回调函数。&lt;br /&gt;
*'''normal（普通）'''：只有你能调用的普通函数。&lt;br /&gt;
*'''static（静态）'''：作用域仅在当前文件内，可以与 stock 一起使用。&lt;br /&gt;
*'''stock（共享、仓库）'''：由 include 头文件引入的普通函数。如果不使用，它不会被编译。&lt;br /&gt;
*'''forward（导出、转发）'''：由应用程序提供的全局事件函数。如果你实现了这个函数，它将被回调。&lt;br /&gt;
&lt;br /&gt;
所有Pawn中的代码都必须存在于函数中，这有别于PHP，Perl和Python允许你全局代码。这是因为Pawn是一种基于回调的语言：从父应用程序产生一种动作，那么Pawn的函数就必须被编写来回应这种动作。我们的例子都是一些独立的代码，没有上下文关系，这样是为了纯粹的示范性目的。例子中的这些独立代码可能是某些函数的一部分。&lt;br /&gt;
&lt;br /&gt;
==声明==&lt;br /&gt;
和变量不同，函数不需要你在使用前声明。函数有两个要素，签名（signature）和函数体（body）。签名包含了你函数的名字它所要接受的参数。函数体包含着代码的内容。&lt;br /&gt;
&lt;br /&gt;
这是一个函数的例子：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int AddTwoNumbers(int first, int second)&lt;br /&gt;
{&lt;br /&gt;
  int sum = first + second;&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这是一个简单的函数。签名是这一行：&lt;br /&gt;
&amp;lt;pawn&amp;gt;int AddTwoNumbers(int first, int second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
解释一下，它的意思是：&lt;br /&gt;
*&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; - 函数返回值的类型（整形）&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - 函数的名字&lt;br /&gt;
*&amp;lt;tt&amp;gt;int first&amp;lt;/tt&amp;gt; - 第一个参数（整形）&lt;br /&gt;
*&amp;lt;tt&amp;gt;int second&amp;lt;/tt&amp;gt; - 第二个参数（整形）&lt;br /&gt;
&lt;br /&gt;
函数体是一个简单的代码块。它创建一个新的变量，叫做 &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;，并给它赋值为 first 和 second 的和值（表达式在后文说明）。主要需要注意的是 &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; 语句，它表明了函数的结束，并且把值返回给函数的调用者。函数运行结束后会返回一个数据，否则返回 &amp;lt;tt&amp;gt;void&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
函数可以接收任意类型的输入，返回除数组外的任意类型。&lt;br /&gt;
&lt;br /&gt;
传参数给函数：&lt;br /&gt;
&amp;lt;pawn&amp;gt;int numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意，cell类型通过值传递。就是说，它们的值不会被函数变化。例如：&lt;br /&gt;
（译注：区别于值传递的一种传递是引用传递，具体参考其他的编程语言）&lt;br /&gt;
（译注：旧版 SourceMod 中，类型通过对 cell 的 tag 来实现。原文中这里依然为 cell，未修正。）&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这段代码不会改变 &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; 的值。这是因为 &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; 的值被拷贝了一份，这份拷贝值代替了 &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;  本身被传递过去。&lt;br /&gt;
&lt;br /&gt;
更多的函数的例子将会贯穿本文。&lt;br /&gt;
&lt;br /&gt;
==公共函数==&lt;br /&gt;
public 函数被用于实现回调。你不需要创建 public 函数除非需要实现特定的回调。比如，这里有两个回调函数，他们在 &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; 中：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward void OnPluginStart();&lt;br /&gt;
forward void OnClientDisconnected(int client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
为了实现和接收这两个事件，你需要写函数如下：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* 代码 */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnClientDisconnected(int client)&lt;br /&gt;
{&lt;br /&gt;
   /* 代码 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''public''' 关键字把函数暴露为公共的，允许父应用程序直接调用这个函数。&lt;br /&gt;
&lt;br /&gt;
==原生函数==&lt;br /&gt;
Native 是由 SourceMod 提供的内置函数。你能像普通函数一样调用它们。例如，SourceMod 有如下函数：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native float FloatRound(float num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
它能像如下调用：&lt;br /&gt;
&amp;lt;pawn&amp;gt;int rounded = FloatRound(5.2);     // rounded 被赋值为 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==数组参数==&lt;br /&gt;
你可以传递数组或者字符串作为参数。非常关键的是，这种传递属于 '''引用传递''' 。就是说，相对于产生一份数据的拷贝（值传递），引用传递则是把它们本身传递了过去。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
void ChangeArray(int[] array, int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这个函数是通过给定的索引来给数组赋值。当它运行如下语句时，它会改变索引2所在的数组元素的值，从3变成29。结果如下：&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这里要注意两点。首先，在传递给函数时，并没有复制数组。他们通过 ''引用'' 被传递，保证了数组的一致性。其次，方括号在形参中被改变了位置，因为我们的函数可以接受任意长度的数组，所以必须使用变长语法。&lt;br /&gt;
&lt;br /&gt;
为了预防数组被直接修改，你可以给它加上 &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; 关键字。这会导致一个代码错误当它尝试修数组的时候。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void CantChangeArray(const array[], int index, int value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //不会被编译&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果你知道这个数组不会被修改，在数组前添加 &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; 是一个好习惯。这可以避免写代码时的错误。&lt;br /&gt;
&lt;br /&gt;
=表达式=&lt;br /&gt;
表达式确切的说等同于数学运算。它们是一组用于求值的操作符或标识符。它们经常被包含在括号中。它们遵循严格的“运算顺序”。它们能包含变量，函数，数字以及表达式本身可以被嵌套在其它的表达式中，或者乃至被当做参数传递。&lt;br /&gt;
&lt;br /&gt;
最简单的表达式可以是单独的一个数字，例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //表达数字 0&lt;br /&gt;
(0); //也表达了数字 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
表达式可以返回任意值，它们同样能返回 ''0 或 非 0'' 值。在这层意义上，''0'' 代表 ''false''，非 ''0'' 代表 ''true'' 。例如，-1 是 '''true''' ，因为它是 非0。负数不是 false。&lt;br /&gt;
&lt;br /&gt;
操作符的运算顺序类似于 C 语言：圆括号，乘法，除法，加法，减法。这里是一些简单的例子：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //表达了 11&lt;br /&gt;
5 * 6 + 3;               //表达了 33&lt;br /&gt;
5 * (6 + 3);             //表达了 45&lt;br /&gt;
5.0 + 2.3;               //表达了 7.3&lt;br /&gt;
(5 * 6) % 7;             //取余操作符，表达了 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //表达了 -8&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如前所述，表达式可以包含变量，乃至是函数：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5 * 6;&lt;br /&gt;
int b = a * 3;      //表达了 90&lt;br /&gt;
int c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：字符串处理的例程可以在 string.inc 中找到，位置在 include 的子目录中。它们也可以通过 [http://docs.sourcemod.net/api/ API Reference] 浏览。&lt;br /&gt;
&lt;br /&gt;
==运算符==&lt;br /&gt;
在Pawn中有一些额外的有用的运算符。第一种便是自聚表达式。&lt;br /&gt;
例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
可以写成：&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这种自聚集对于以下操作符都适用：&lt;br /&gt;
*1.	四则运算： *， /， -， +&lt;br /&gt;
*2.	位运算： |， &amp;amp;， ^， ~， &amp;lt;&amp;lt;， &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
另外，有一种自增，自减运算符：&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
可以写成：&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意：运算符 ++ 和 -- 可以写在变量的前面（先自增，先自减）或者后面（后自增，后自减）。区别在于在表达式中，剩下的部分取到此变量的值有所不同。&lt;br /&gt;
&lt;br /&gt;
* ''先自增、先自减'' 变量在参与表达式的运算前自增/自减，表达式的剩余部分取自增/自减后变量的值。 &lt;br /&gt;
* ''后自增、后自减'' 变量在参与表达式的运算后自增/自减，表达式的剩余部分取自增/自减前变量的值。&lt;br /&gt;
&lt;br /&gt;
换句话说， &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; 参与表达式运算的是 &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;；&amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; 参与表达式运算的是 &amp;lt;tt&amp;gt;(a + 1)&amp;lt;/tt&amp;gt;。两种情况下最后 &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; 都自增了 1。&lt;br /&gt;
&lt;br /&gt;
例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;int a = 5;&lt;br /&gt;
int b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
int c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) 中 &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; 取 &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; 自增前的值 &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;&lt;br /&gt;
(2) 中 &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; 取 &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; 自增后的值 &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==比较运算符==&lt;br /&gt;
有6个比较操作符用于比较两个数字的值，并且结果是 true（0） 和 false（非 0） 。&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - a、b 相同表达为 true，否则表达为 false&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - a、b 不同表达为 true，否表达为 false&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - a 大于 b 表达为 true，否则为 false&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - a 大于或者等于 b 表达为 true，否则为 false&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - a 小于 b 表达为 true，否则为 false&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - a 小于或者等于 b 表达为 true，否则为 false&lt;br /&gt;
&lt;br /&gt;
例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //表达为 true&lt;br /&gt;
(3 + 3 == 6);     //表达为 true&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //表达为 false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意这些运算符不能用在数组或者字符串上。&lt;br /&gt;
&lt;br /&gt;
==真值运算符==&lt;br /&gt;
这些真值可以用3个布尔运算符结合。&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - a 和 b 同为 true ，结果为 true ，否则为 false （与运算符）&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; -  a 和 b 同为 false ，结果为 false ，否则为 true （或运算符）&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - a 为 true ，!a 为 false ， a 为 false ， !a 为 true (非运算符)&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //表达了 true&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //表达了 false&lt;br /&gt;
(!1 || 0);        //表达了 false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==左值与右值==&lt;br /&gt;
两个重要的概念是左手边的值和右手边的值，或简称为左值和右值。左值在赋值语句的左边，右值在赋值语句的右边。例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这个例子中 &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; 是一个左值 &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; 是一个右值&lt;br /&gt;
&lt;br /&gt;
规则：&lt;br /&gt;
*'''表达式不可能是左值'''&lt;br /&gt;
*'''变量可以是左值也可以是右值'''&lt;br /&gt;
&lt;br /&gt;
=条件语句=&lt;br /&gt;
条件语句允许你在符合特定条件的情况运行代码。&lt;br /&gt;
&lt;br /&gt;
==If 语句==&lt;br /&gt;
if语句测试一个或多个条件。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* 表达式为 true 时代码才会执行 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
当然也可以写成多个匹配：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* 代码 */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* 代码  */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* 代码 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
你也可以处理没有条件匹配的。例如：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* 代码 */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* 没有表达式为 true 时这里的代码才会运行 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Switch 语句==&lt;br /&gt;
Switch 语句是限制的 if 语句。Switch 用一系列可能的值来测试一个表达式。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* 代码 */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* 代码 */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* 代码 */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* 代码 */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* 以上 case 皆不匹配，这里的代码才会运行 */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
不像其他语言，switch 匹配后不会一直运行到最后。也就是说，多个 cases 并不会运行。当一个 case 匹配了，这个 case 的代码块运行完就会跳出 switch。&lt;br /&gt;
&lt;br /&gt;
=循环=&lt;br /&gt;
循环允许在条件为真时重复执行一段代码。&lt;br /&gt;
&lt;br /&gt;
==for 循环==&lt;br /&gt;
for 循环由 4 个部分组成：&lt;br /&gt;
* '''初始化''' 语句 - 在第一次循环之前运行&lt;br /&gt;
* '''条件''' 语句 - 每次循环前运行，结果为 false 则终止循环&lt;br /&gt;
* '''迭代''' 语句 - 每次虚幻后运行&lt;br /&gt;
* '''循环体''' - 每次循环中 '''条件''' 为 true 时运行&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* 初始化 */ ; /* 条件 */ ; /* 迭代 */ )&lt;br /&gt;
{&lt;br /&gt;
   /* 循环体 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
一个简单的例子是写一个函数计算数组的总合&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
int sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total;&lt;br /&gt;
&lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
解释：&lt;br /&gt;
*&amp;lt;tt&amp;gt;int i = 0&amp;lt;/tt&amp;gt; - 新建一个变量 i 并赋值为 0&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - 仅在 &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; 小于 &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt; 时执行循环。这确保了循环在适当的时机停止读取数组。在这种情况下，我们不要读取这个循环无效的索引。&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - 每次循环后 &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; 自增。这样保证了循环不会永远运行下去，最终会由于 &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; 变得太大使得循环停止。&lt;br /&gt;
&lt;br /&gt;
因此，函数 &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; 会遍历数组所有有效的索引，每次都会把值加到总合里。for 循环对于处理数组是非常常用的。&lt;br /&gt;
&lt;br /&gt;
==while 循环==&lt;br /&gt;
while 循环比起 for 循环用的少一些，但它的确是最简单的循环。它有两个部分：&lt;br /&gt;
* '''条件''' 语句 - 每次循环前执行，如果为 false 终止循环。&lt;br /&gt;
* '''循环体''' - 每次循环执行的部分。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* 条件语句 */ )&lt;br /&gt;
{&lt;br /&gt;
   /* 循环体 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
只要条件表达式保持为真，这个循环就会继续执行。所有的 for 循环都可以改写成 while 循环：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* 初始化 */&lt;br /&gt;
while ( /* 条件语句 */ )&lt;br /&gt;
{&lt;br /&gt;
   /* 循环体 */&lt;br /&gt;
   /* 迭代 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这是之前 for 循环重写为 while 循环的例子：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumArray(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
当然还有 '''do...while''' 循环，这是更少见得循环。它和 while 循环基本相同，除了条件的检查之外。 '''do...while''' 的条件检查是在每次循环之后，这意味着，循环体至少要被执行一次。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* 循环体 */&lt;br /&gt;
}&lt;br /&gt;
while ( /* 条件语句 */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==循环控制==&lt;br /&gt;
有两种方法可以让你有选择的控制循环：&lt;br /&gt;
*'''跳过''' 一次循环，然后继续&lt;br /&gt;
*'''终止''' 循环，不再继续&lt;br /&gt;
&lt;br /&gt;
比如你有一个函数，获取一个数组并且在数组内寻找匹配的数字。当你找到了这个数字，就想立刻停止循环：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * 返回匹配的数字所在的索引，没找到时返回 -1&lt;br /&gt;
 */&lt;br /&gt;
int SearchInArray(const int array[], int count, int value)&lt;br /&gt;
{&lt;br /&gt;
   int index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
的确，这个函数只是简单的 &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt; ，但是这个例子展示了如何用 &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; 来终止一个循环。&lt;br /&gt;
&lt;br /&gt;
相似的，关键字 &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; 会跳过循环的迭代。例如，假设我们想要计算所有素数的和：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int SumEvenNumbers(const int array[], int count)&lt;br /&gt;
{&lt;br /&gt;
   int sum;&lt;br /&gt;
 &lt;br /&gt;
   for (int i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* 如果被 2 整除余 1 ，那就是奇数 */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* 跳过剩余的部分 */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=作用域=&lt;br /&gt;
作用域指的是代码的 '''可视性'''。那就是，在某个层级的代码对于另一个层级的代码是“不可见的”。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int A, B, C;&lt;br /&gt;
&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Function2()&lt;br /&gt;
{&lt;br /&gt;
   int C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在这个例子中， &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt; ， &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; 和 &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; 存在于 '''全局作用域''' 。他们可以被任何函数看见。但是，在 &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; 中的变量 &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; 不同于全局层级的 &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; 。它被叫做 '''局部作用域''' ，因此也叫做 '''局部变量''' 。&lt;br /&gt;
&lt;br /&gt;
相似的， &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; 和 &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; 互相并不知道各自的变量。&lt;br /&gt;
&lt;br /&gt;
不仅是 &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; 的私有变量，每次重新创建的时候也是如此。像这样：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在这个例子中， &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; 调用它自己。当然，这是一个无限递归（不好的东西），但是重要的是每次这个函数运行，就会有产生一个新的 &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; 。当函数结束时， &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; 被销毁，相应的值也消失了。&lt;br /&gt;
&lt;br /&gt;
作用域的这个特性简单来说就是变量的作用域等于它所在的代码块。同时，在全局作用域的变量对于所有函数是可见的。一个变量在局部作用域的对所有在这个代码块之下的代码可见。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
以上代码是合法的，因为 A 的作用域延伸到整个函数。下面的代码就是不合法的：&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
void Function1()&lt;br /&gt;
{&lt;br /&gt;
   int A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      int B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意， &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; 的声明在一个新的代码块里。这意味着 &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; 只能在这个代码块被存取（以及在这个代码块中的子代码块）。一旦这个代码块运行结束了， &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; 也就不存在了。&lt;br /&gt;
&lt;br /&gt;
=动态数组=&lt;br /&gt;
动态数组不需要硬编码他的大小。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;void Function1(int size)&lt;br /&gt;
{&lt;br /&gt;
   int array[size];&lt;br /&gt;
&lt;br /&gt;
   /* 代码 */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
动态数组可以用任意的表达式作为他们的大小，只要这个表达式的值大于0。就像普通数组，SourcePawn 在其创建后，并不知道它的大小，你必须保存它的大小以备不时之需。&lt;br /&gt;
&lt;br /&gt;
动态数组只能在局部作用域中使用，它不能存在于全局。&lt;br /&gt;
&lt;br /&gt;
=扩展的变量声明=&lt;br /&gt;
变量可以有更多种声明方式，除了用&amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;、&amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt;或&amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
==静态变量==&lt;br /&gt;
关键字 &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; 可以在全局作用域和局部作用域使用，不同的作用域有不同的意义。&lt;br /&gt;
&lt;br /&gt;
===全局静态变量===&lt;br /&gt;
全局作用域下的静态变量只能在同一个文件中访问。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static float g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static float g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
某个文件同时 include 了这两个头文件，会无法访问 &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; 或者 &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt; 。这可以简单的隐藏某些信息，类似于其他变成语言中的 private 属性。&lt;br /&gt;
&lt;br /&gt;
===局部静态变量===&lt;br /&gt;
局部静态变量其实也是一个全局的变量，只不过它只对所在的代码块可见。例如：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   static int counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在这个例子中， &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; 其实是一个全局的变量（其生命周期是全局的）————它只在第一次被初始化为 -1 ，之后不再初始化，不存在函数的堆栈中。每次函数 &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; 执行时，变量 &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; 和它在内存中存储的位置是同一个。&lt;br /&gt;
&lt;br /&gt;
再看这个例子：&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
在这个例子中， &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; 为 &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;（&amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;）。它存在于函数的生命周期之外。注意，如果你在递归函数中使用静态变量可能会造成一些问题。如果你使用了递归函数，不要将静态变量作为每次递归的新变量使用。&lt;br /&gt;
&lt;br /&gt;
使用局部静态变量的好处是避免过多的定义全局变量。如果你的变量不会被其他的函数使用，你可以放心的使用静态变量持久的存储在函数“内部”。&lt;br /&gt;
&lt;br /&gt;
静态变量可以在任意的代码块中：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
int MyFunction(int inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static int counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
翻译 Translated By：&lt;br /&gt;
[http://steamcommunity.com/profiles/76561198086652043 STF.Iscariot]&lt;br /&gt;
[http://steamcommunity.com/id/xiaooloong STF.xiaooloong]&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Xiaooloong</name></author>
		
	</entry>
</feed>