本文节选自《LPC语言基础教程:从零学习游戏开发》,版权归@mudren,欢迎转载,但必须注明来源(mud.ren)。
LPC条件编译的使用和C语言完全相同,主要包括如下:
if...#endif
#if 命令的完整格式为:
#if 整型常量表达式1
程序段1
#elif 整型常量表达式2
程序段2
#elif 整型常量表达式3
程序段3
#else
程序段4
#endif
#if...#endif指令用于预处理器的条件判断,满足条件时,内部的行会被编译,否则就被编译器忽略。
#if 0
float pi = 3.1415; // 不会执行
#endif
上面示例中,#if后面的0,表示判断条件不成立。所以,内部的变量定义语句会被编译器忽略。#if 0这种写法常用来当作注释使用,不需要的代码就放在#if 0里面。
#if后面的判断条件,通常是一个表达式。如果表达式的值不等于0,就表示判断条件为真,编译内部的语句;如果表达式的值等于0,表示判断条件为伪,则忽略内部的语句。
#if...#end之间还可以加入#else指令,用于指定判断条件不成立时,需要编译的语句。
#define FOO 1
#if FOO
printf("defined\n");
#else
printf("not defined\n");
#endif
上面示例中,宏FOO如果定义过,会被替换成1,从而输出defined,否则输出not defined。
如果有多个判断条件,还可以加入#elif命令。
#if HAPPY_FACTOR == 0
printf("I'm not happy!\n");
#elif HAPPY_FACTOR == 1
printf("I'm just regular\n");
#else
printf("I'm extra happy!\n");
#endif
上面示例中,通过#elif指定了第二重判断。注意,#elif的位置必须在#else之前。如果多个判断条件皆不满足,则执行#else的部分。
没有定义过的宏,等同于0。因此如果UNDEFINED是一个没有定义过的宏,那么#if UNDEFINED为伪,而#if !UNDEFINED为真。
#if的常见应用就是打开(或关闭)调试模式。
#define DEBUG 1
#if DEBUG
printf("value of i : %d\n", i);
printf("value of j : %d\n", j);
#endif
上面示例中,通过将DEBUG设为1,就打开了调试模式,可以输出调试信息。
在LPC中有一个特殊的预编译判断函数efun_defined,可以判断指定efun是否定义,如:
#if efun_defined(parse_command)
// todo
#else
// todo
#endif
ifdef...#endif
#ifdef 命令的格式为:
#ifdef 宏名
程序段1
#else
程序段2
#endif
#ifdef...#endif指令用于判断某个宏是否定义过。
有时源码文件可能会重复包含某个库,为了避免这种情况,可以在库文件里使用#define定义一个空的宏。通过这个宏,判断库文件是否被包含了。
#define EXTRA_HAPPY
上面示例中,EXTRA_HAPPY就是一个空的宏。
然后,源码文件使用#ifdef...#endif检查这个宏是否定义过。
#ifdef EXTRA_HAPPY
printf("I'm extra happy!\n");
#endif
上面示例中,#ifdef检查宏EXTRA_HAPPY是否定义过。如果已经存在,表示加载过库文件,就会打印一行提示。
#ifdef可以与#else指令配合使用。
#ifdef EXTRA_HAPPY
printf("I'm extra happy!\n");
#else
printf("I'm just regular\n");
#endif
上面示例中,如果宏EXTRA_HAPPY没有定义过,就会执行#else的部分。
#ifdef...#else...#endif可以用来实现条件加载。
#ifdef MAVIS
#include "foo.h"
#define STABLES 1
#else
#include "bar.h"
#define STABLES 2
#endif
上面示例中,通过判断宏MAVIS是否定义过,实现加载不同的头文件。
ifndef...#endif
#ifndef 命令的格式为:
#ifndef 宏名
程序段1
#else
程序段2
#endif
#ifndef...#endif指令跟#ifdef...#endif正好相反。它用来判断,如果某个宏没有被定义过,则执行指定的操作。
#ifdef EXTRA_HAPPY
printf("I'm extra happy!\n");
#endif
#ifndef EXTRA_HAPPY
printf("I'm just regular\n");
#endif
上面示例中,针对宏EXTRA_HAPPY是否被定义过,#ifdef和#ifndef分别指定了两种情况各自需要编译的代码。
#ifndef常用于防止重复包含。举例来说,为了防止头文件myheader.h被重复包含,可以把它放在#ifndef...#endif里面包含。
#ifndef MYHEADER_H
#define MYHEADER_H
#include "myheader.h"
#endif
上面示例中,宏MYHEADER_H对应文件名myheader.h的大写。只要#ifndef发现这个宏没有被定义过,就说明该头文件没有包含过,从而加载内部的代码,并会定义宏MYHEADER_H,防止被再次加载。
在LPC编程中,推荐使用#ifndef防止头文件报重复定义的警告,如:
#ifndef ANSI_H
#define ANSI_H
// 定义头文件
#endif
推荐把所有头文件都以这种方式定义,注意定义的宏不要重名就好。
注意在LPC语言中没有 defined 预处理
// 示例:7.3.1
#define X 11
int main(object me, string arg)
{
#ifdef FLUFFOS
debug("driver 是 FLUFFOS!");
#else
#ifdef MUDOS
debug("driver 是 MUDOS!");
#else
debug("未知 driver!");
#endif
#endif
#if X < 1 || X > 10
debug("X = " + X);
#else
debug("...");
#endif
#ifdef __PACKAGE_DB__
debug("支持数据库!");
#endif
return 1;
}