LPC 语言基础教程:5.2 LPC语言的变量作用域

本文节选自《LPC语言基础教程:从零学习游戏开发》,版权归@mudren,欢迎转载,但必须注明来源(mud.ren)。

第二节 LPC语言的变量作用域

学C语言时我们知道变量是有作用域的,定义在函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数后就是无效的;在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的源文件,包括 .c 和 .h 文件,而如果给全局变量加上 static 关键字,它的作用域就变成了当前文件,在其它文件中就无效了;另外,C语言允许在代码块内部定义变量,称为块级变量,这样的变量具有块级作用域,即在代码块内部定义的变量只能在代码块内部使用,出了代码块就无效了。

LPC语言对局部变量和块级变量的使用和C语言完全一样,而且和C语言一样,局部变量必须在代码块开头声明,位置必须在所有语句之前。但对全局变量,不太一样。

在LPC语言中,全局变量是可以被保存和读取的,用来实现游戏的存档和读档功能,而且作用域是当前对象,也就是当前文件,类似C语言中加了 static 关键字的全局变量。在旧版的mudos中也存在 static 关键字,但意思和C语言中的不一样,如果一个全局变量增加 static,就代表不保存这个变量的值,在 fluffos 中, static 关键字被 nosave 关键字取代,字面意思更直接。

以下是一个简单的示例代码:

// 示例:5.2.1

// 全局变量,可以在当前文件中使用,不会被存档
nosave string file = "/data/dbase";
// 全局变量,可以在当前文件中使用,会被存档
string data;

int sum(int m, int n);

int main(object me, string arg)
{
    // me、arg 是局部变量,可以在 main() 内部使用
    if (arg == "load")
    {
        if (file_size(file + __SAVE_EXTENSION__) > 0)
        {
            // 读取存档,file 是全局变量
            restore_object(file);
            printf("data = %s\n", data);
        }
        else
        {
            printf("目前没有存档!\n");
        }
    }
    else if (arg)
    {
        // data 是全局变量
        data = arg;
        // 数据存档,file 是全局变量
        if (!catch (save_object(file)))
        {
            printf("数据存档成功!\n");
        }
        else
        {
            printf("数据存档失败,请确认存档目录 data 存在!\n");
        }
    }
    else
    {
        // begin、end、result 是块级变量,只能在本代码块内使用
        int begin = 1, end = 1024;
        int result = sum(begin, end);
        printf("The sum from %d to %d is %d\n", begin, end, result);
    }

    return 1;
}

int sum(int m, int n)
{
    int sum = 0;
    //m、n、sum 都是局部变量,只能在 sum() 内部使用
    // i 是块级变量,只能在 for 循环内部使用
    for (int i = m; i <= n; i++)
    {
        sum += i;
    }
    return sum;
}

以上代码展示了全局变量、局部变量和块级变量,同时使用了存档和读档的 efun,这里存档文件为 /data/dbase.o,需要我们在LIB目录中新建data 文件夹,否则会因目录不存在无法存档。直接输入指令 5.2.1 会给1...1024求和,输入 5.2.1 load 会读取档案,如果没有先存档第一次执行会提醒存档不存在,输入 5.2.1 mud.ren会把 mud.ren 存到全局变量 data 中(你也可以输入任意内容),可以打开 /data/dbase.o 文件查看,哪怕重启LIB,再次执行 5.2.1 load 也会正常读取存档。

asciicast

我们正常在线玩的MUDLIB的档存也是使用这种方式的,只是使用 mapping 格式存档玩家的各种数据,在后续章节我们会讲解游戏存档和读档功能的开发。

另外,LPC语言是面向对象编程,有继承(inherit),全局变量可以被继承使用,因为这里还没有讲到继承,所以先不做过多阐述,后续章节会说明。

最后,强调一点小小的不同:C语言代码是由一个一个的函数构成的,除了定义和说明类的语句(例如变量定义、宏定义、类型定义等)可以放在函数外面,所有具有运算或逻辑处理能力的语句(例如加减乘除、if else、for、函数调用等)都要放在函数内部。LPC语言全局变量定义时,可以使用运算,但也仅限于在声明同时赋初始值时使用运算。另外,全局变量必须在inheirt之后声明

京ICP备13031296号-4