17.用枚举优化宏

一、前言

从本章开始,我们将逐步对原有程序进行优化。

优化的方面有很多,比如本章介绍的便是代码层面上的优化。

其它的还有游戏程序执行逻辑上的优化,比如我们游戏地图写死在程序里面就有些不好,我们可能更想要将其分离出程序,动态加载地图。

这样的好处就是,当你更新游戏地图的时候,就不用再去修改程序了,即两者分离了。

二、枚举

说话本章要讨论的重点:枚举。

它的使用方式如下:

enum name{
	a=1,
	b=2,
	c=3
};

正如你所看到的,它是用关键字enum来声明的,这就和普通的变量声明差不过,比如int name;

只不过不同之处在于,它后面跟了一个大括号,然后里面写了一系列的等号,比如a=1,b=2这种。

这就是在给数字重新命名,将a这个字母重新赋予了1的含义。

之后你再使用字母a时,它就不再是单纯的字母了,而是一个枚举值:1。

上面的写法如果用宏替换的话,等于于下面这样:

#define a 1
#define b 2
#define c 3

那我们为什么要用枚举来替换宏呢?毕竟相比较而言,宏的功能可比枚举强的多。

枚举只能给数字重命名,而宏则可以给任意东西重命名,因为宏的本质是替换。

原因并不复杂,那就是宏纯粹只是通过替换实现的。

那么首先一点就是它没有组织性,每一个宏定义都是独立的,即使这些宏可能比较相关。

而枚举你就可以将相关联的枚举量写在一起。

其次就是,编译器无法检测它的对错,因为它单纯就是替换,这就导致一旦出错,你也很难定位具体的错误点。

而枚举不一样,它也是C语言的一种基本结构,编译器会检测它的错误的,一旦出现错误,你很容易排查出来。

三、使用枚举

枚举的使用并不难,直接拿我们的代码来测试即可,将所有相关的宏定义更改为枚举。

首先就是定义,将原有的宏更改为对应的枚举即可:

enum Game {
	SPACE =  0,  //空地
	WALL = 1, //墙壁
	TARGET = 3, //目标位置
	BOX = 4 , //箱子
	TARGET_IN = 5, //箱子已经推到目标位置
	PLAYER = 6 ,   // 玩家
	PLAYER_IN_TARGET= 2 //玩家在目标位置
};

然后你依旧可以向往常一样正常使用,其它代码丝毫不需要更改。

唯一变化的可能就是vs中的代码颜色,从原有的紫色,替换为现在的淡绿色

image-20230913091155952

这个时候,如果你写错了,比如让里面的枚举量SPACE等于字母o了,编译器就会直接报错,并且报错点在这个枚举定义的地方,你可以直接修改。

但如果你使用的是宏,由于它是通过替换的方式进行的,那么报错地点就会是所有你使用到宏的地方。

一般你就会看到大量的红线、错误提示,短时间就不容易排查错误了。

四、枚举进阶

虽然上面就是枚举最基本的用法了,但其实还可以简写。

比如你发现我们上面的枚举名Game根本没用啊!

所以你是可以省略的:

enum{
	SPACE =  0,  //空地
	WALL = 1, //墙壁
	TARGET = 3, //目标位置
	BOX = 4 , //箱子
	TARGET_IN = 5, //箱子已经推到目标位置
	PLAYER = 6 ,   // 玩家
	PLAYER_IN_TARGET= 2 //玩家在目标位置
};

同时由于这种数字递增的方式定义枚举量太常见了,所以它默认就是递增的,你可以省略掉其中比较规范递增的枚举量赋值:

enum{
	SPACE =  0,  //空地
	WALL = 1, //墙壁
	PLAYER_IN_TARGET= 2, //玩家在目标位置
	TARGET = 3, //目标位置
	BOX = 4 , //箱子
	TARGET_IN = 5, //箱子已经推到目标位置
	PLAYER = 6 ,   // 玩家
};

调整为上面的位置顺序,那么就刚好为0-6依次递增。

这时就可以省略后面的数字:

enum{
	SPACE,  //空地
	WALL, //墙壁
	PLAYER_IN_TARGET, //玩家在目标位置
	TARGET, //目标位置
	BOX , //箱子
	TARGET_IN, //箱子已经推到目标位置
	PLAYER,   // 玩家
};

这两种写法完全等价。

但这种简化写法只推荐在简单区别下使用,而我们这里由于SPACE这种含义明确的枚举量必须为0(地图数据中就是这么写的),那么如果有人不清楚这一点,更换了各个枚举量的位置,程序就会立马出问题。

对于这种明确某个枚举量必须为某个数字的情况下,最好还是将后面的数字明确的写出来。

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux