【问题标题】:Bit flags - check if any of the specific flags (and no other) are set位标志 - 检查是否设置了任何特定标志(而不是其他标志)
【发布时间】:2019-02-12 22:11:42
【问题描述】:

我在游戏中的玩家命令上使用位标志来决定是否应该允许它们执行。 所以位标志的列表是这样的:

CMD_NONE = 0x0,
CMD_TELEPORT = 0x1,
CMD_VIP = 0x2,
CMD_NO_LOG = 0x4, // don't log the execution of this command

我想做的是制作一些函数/宏来简化事情,因为我想检查命令是否设置了 CMD_TELEPORTCMD_VIPnothing 更多,所以CMD_TELEPORTCMD_VIP 都是可选的,可以开/关,但不能同时启用其他任何功能。

至于现在我是手动检查的,但这很麻烦。 我无法使用

if (flags == (CMD_TELEPORT | CMD_VIP)

因为这会检查是否同时设置了 两个 标志,并且我希望它们实际上是唯一可以设置 的标志,但是不一定同时。 所以它是 CMD_NONE、CMD_TELEPORT、CMD_VIP 或 (CMD_TELEPORT | CMD_VIP)

我可以做一些循环并检查每个标志是否已设置并从标志值中减少它并检查是否有任何剩余,但我希望有一种更简单的方法来做到这一点。

【问题讨论】:

  • 如果CMD_NO_LOG 不应该使用,有没有意义?
  • 这只是一个例子,我为不同的目的使用了更多的标志,但是在很多情况下我只想允许带有特定标志的命令,假设玩家正在执行某些任务并且我不想要允许任何传送或 vip 命令等,所以我只检查对游戏本身没有任何影响的optional 标志(所以它可以是 CMD_NONE 或 CMD_NO_LOG 但其他任何东西都被阻止等,还有其他可选标志)

标签: bit-fields bitmask


【解决方案1】:

如果您想检查除了CMD_TELEPORTCMD_VIP 之外没有设置其他位,您可以将它们屏蔽掉,看看结果是否非零:

if (flags & ~(CMD_TELEPORT|CMD_VIP)) {
    /* something else is set */
} else {
    /* just TELEPORT or VIP, or both, or nothing */
}

如果您想进一步检查其中是否只有一个,则必须单独检查。有两个标志,这很容易,但更多的标志会有点重复。

【讨论】:

    猜你喜欢
    • 2010-11-23
    • 2011-03-09
    • 2019-12-22
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    相关资源
    最近更新 更多