![]() |
|
[教程] 枚举器 enum 详细讲解 原文作者: iPLEOMAX - 打印版本 +- samp | open.mp 联机社区论坛 (https://open-mp.cn) +-- 板块: SA-MP (https://open-mp.cn/forumdisplay.php?fid=12) +--- 板块: 教程 (https://open-mp.cn/forumdisplay.php?fid=17) +--- 主题: [教程] 枚举器 enum 详细讲解 原文作者: iPLEOMAX (/showthread.php?tid=26) |
[教程] 枚举器 enum 详细讲解 原文作者: iPLEOMAX - 小鸟unsigned - 03-22-2026 枚举器原文作者: iPLEOMAX 关于枚举,有些细节很多脚本作者并不清楚。 很多人都喜欢在脚本里用枚举来存玩家数据、车辆数据、房屋数据之类的,尤其是用户信息这块。 一个很典型的写法是这样的: 代码: 用起来大概是这样: 代码: 这段应该不难理解。 现在我们看另一个例子: 代码: 你可能会觉得输出是 0 | 9 | 5 | 56,对吧?如果你这么想,那就错了。实际上输出是 0 | 0 | 0 | 0。你可能会以为枚举是用来存储数据的,但事实并非如此。我在枚举里写了 MONEY = 9,然后在 printf 里用了 pInfo[0][MONEY],但编译器其实把它当成 pInfo[0][9] 来处理,而不是什么 E_PLAYER_INFO:MONEY。也就是说,MONEY 在这里只是作为一个索引来用的。所以枚举本质上根本不是变量,它其实就是一组常量,只不过帮你的数组索引起了个好记的名字罢了。 好,我们再来深入一点,应该能让你理解得更清楚。 举个例子: 代码: 现在我们用枚举重写一下: 代码: 这两段代码都能正常编译,做的事情也完全一样。你看出区别了吗?其实就只是代码写法不同而已。 这个例子告诉我们,枚举干的事情和常量是一样的。不过枚举有些地方比常量或者宏定义( const e_CAR1 = 0; 或者 #define e_CAR1 0)更好用,具体差异我们后面再说。首先你需要明白枚举的结构: 代码: Abc 是一个值为 0 的常量(差不多等于 const Abc = 0; 或 #define Abc 0),Def 是值为 1 的常量,Ghi 是值为 2 的常量。预编译器会自动给这些常量赋值,从 0 开始一直往上排。而用常量的时候,你得自己手动赋值。枚举则是自动帮你排好的。 再看个例子: 代码: 看到了吧,如果你手动给某个枚举项赋了值,后面的项就会在此基础上依次加 1。 再来看看更复杂的情况: 代码: 运行下面的代码: 代码: 结果输出 22。因为整个枚举的总大小是 22: INT 占 1 个 + STRING 占 10 个 + INT2 占 1 个 + STRING2 占 10 个 = 22。 你可能会问,为什么我写 INT 是 1 而不是 0?因为这里我数的是占用了多少个位置,不是从哪个位置开始。如果问起始位置,那 INT 确实是 0。 一个大小为 22 的块,索引范围是 0 到 21,总共 22 个位置。 再试一下: 代码: 输出 1。因为第一个位置(索引 0)被 INT 占了,所以 STRING 从索引 1 开始。每个枚举项占用的位置是这样的:
运行这段: 代码: 结果也是 22,因为 DATA 的大小就是 22。所以,这个数组实际上相当于: 代码: 也就是说,用枚举的时候,你其实是用这些枚举常量作为数组的索引。 另一个例子代码: 输出结果:
第一行, SomeInteger 的常量值是 124,我把 1337 存到了索引 124 的位置。第二行, SomeString 虽然定义了长度为 12,但输出常量值时显示的是 125。因为 125 是这个字符串的起始索引,它占了 125 到 136 这 12 个位置。第三行,浮点数正常显示,但 SomeFloat 的常量值是 137。你可能会想,它应该在 SomeString(125)后面,应该是 126 才对?但别忘了 SomeString[12] 是个数组,占了 12 个位置,所以 SomeFloat 的起始索引是 125 + 12 = 137。一些额外的重要信息枚举也可以作为标签使用: 代码: 然后可以这样写: 代码: 代码: 但是: 代码: E_MY_TAG 的大小是 3(枚举里最大索引是 2),而 E_FIRST 的值是 4,已经超出范围了。匿名枚举: 代码: 强标签和弱标签: 代码: 代码: 枚举的大概内容就是这些了,这也是为什么我们更喜欢用枚举而不是直接写常量的原因。 感谢 Y_Less 的讲解。 |