本文节选自《LPC语言基础教程:从零学习游戏开发》,版权归@mudren,欢迎转载,但必须注明来源(mud.ren)。
简介
和 C 语言一样,LPC驱动(编译器)在编译程序之前,会先使用预处理器(preprocessor)处理代码。
预处理器首先会清理代码,进行删除注释、多行的语句合成一个逻辑行等等。然后,执行#开头的预处理指令。
预处理指令可以出现在程序的任何地方,但是习惯上,往往放在代码的开头部分。
每个预处理指令都以#开头,放在一行的行首,指令前面可以有空白字符(比如空格或制表符)。#和指令的其余部分之间也可以有空格,但是为了兼容老的编译器,一般不留空格。
所有预处理指令都是一行的,除非在行尾使用反斜杠\,将其折行。预处理指令结尾处不需要分号。
在LPC语言中预处理器有以下5种作用:
#include: 文件包含共享代码#define: 宏定义#if...#endif: 条件编译#echo: 代码调试#pragma: 设定预处理状态@和@@: 格式预处理
下面我们分别介绍文件包含、宏定义和条件编译三种预处理器。
文件包含(#include)
在前面我们已经多次使用过 #include 命令,这种以#号开头的命令称为预处理命令。
#include 是文件包含命令,主要用来引入对应的头文件。#include 的处理过程很简单,就是将头文件的内容插入到该命令所在的位置,从而把头文件和当前源文件连接成一个源文件,这与复制粘贴的效果相同。
#include有两种使用方式:
#include <ansi.h>
#include "ansi.h"
第一种方式直接在全局定义的文件包含目录中查找头文件,第二种方式优先在当前目录中查找头文件,如果当前目录中不存才到全局包含目录中查找,第二种方式也可以使用绝对路径(以/开头的路径)或子目录下的相对路径。
一个 #include 命令只能包含一个头文件,多个头文件需要多个 #include 命令。文件包含允许嵌套,也就是说在一个被包含的文件中又可以包含另一个文件。多重包含时请注意重复定义的问题,这个在后面条件编译章节说明怎么解决。
包含代码的扩展名并不限与.h和.c,只是我们规定头文件用.h做扩展名,代码用.c做扩展名,如果一段代码仅仅是包含使用,可参考谷歌官方推荐使用.inc做扩展名。
#include 和 inherit 不同,一个是预处理命令,使用时不能用 ;,作用是包含代码;一个是程序语句,使用时必须用 ; 结束,功能是继承指定对象。
需要强调的是,游戏中的所有对象都会自动包含全局头文件,这个文件在运行时配置文件中指定,本教程的 mudlib 中这个头文件是 /include/globals.h。其内容如下:
#ifndef GLOBALS_H
#define GLOBALS_H
#ifndef __SENSIBLE_MODIFIERS__
#define nosave static
#endif
#define LOGIN_OB "/system/object/login"
#define USER_OB "/system/object/user"
#define VOID_OB "/system/object/void"
#define LOG_DIR "/log/"
#define DB_PASSWD "secret"
#endif
这里强调一点是尽量不要把宏定义放在全局头文件中,这里的内容越少越好。
而关于这个示例代码中的#define就是宏定义,#ifndef ..#endif则是条件编译,在下节课程中详细讲解。