【问题标题】:Define BIT0, BIT1, BIT2, etc Without #define定义 BIT0、BIT1、BIT2 等 不使用#define
【发布时间】:2010-07-07 23:57:33
【问题描述】:

在 C++ 中是否可以在不使用#define 的情况下在 C++ 中以另一种方式定义 BIT0、BIT1、BIT2?

#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004

然后我用同样的东西从这些位中创建状态:

#define MOTOR_UP   BIT0
#define MOTOR_DOWN BIT1

注意:我只使用 32 位,而不是 64 位。我还使用setBit(flagVariable, BIT)(因此使用clrBit 宏来执行相反操作)宏来设置位,然后比较该位是否使用按位运算符设置,例如

if (flagVariable & MOTOR_UP) { 
   // do something
   clrBit(flagVariable, MOTOR_UP);
}

C++ 中是否存在已经包含这些位掩码的类型?

【问题讨论】:

  • 我很好奇您的编号方案 - 我知道 Bit0 是最低有效位,但为什么 Bit1 是第 3 个最低有效位,而 Bit2 是第 4 个?要么您缺少 0x00000002,要么您的做法非常不一致且令人困惑。
  • 我很好奇为什么这是用宏定义的。在 C++ 代码中使用 #define 作为常量是非常糟糕的做法。
  • setBit 是一个宏,它设置位,而 clrBit 清除位。代码是很久以前从 C 移植过来的。

标签: c++ bitmap bit-manipulation c-preprocessor


【解决方案1】:

您可以改用枚举:

enum {
  BIT1 = 1,
  BIT2 = 2,
  BIT3 = 4,
  ...
};

【讨论】:

  • §7.2/4 说:“由实现定义的整数类型用作枚举的基础类型,但基础类型不应是大于int,除非枚举器的值不能放入intunsigned int。"
  • 我现在删除了那个笔记。不要忘记,您始终可以编辑您的答案以修正无效事实。
【解决方案2】:

怎么样:

enum Bits
{
    BIT0    = 0x00000001,
    BIT1    = 0x00000004,
    BIT2    = 0x00000008,

    MOTOR_UP    = BIT0,
    MOTOR_DOWN  = BIT1
};

【讨论】:

  • 那么根据 C++ 枚举规范将 BIT0 转换为 int
  • 它没有变成一个整数。它在系统上表示为 int。但这不应该对你有任何影响。积分提升规则将根据使用上下文将其转换为正确的类型。
  • BIT0实际上是{}内部的int,外部的Bits值。
  • @Martin:在枚举中声明 MOTOR_UP 或 MOTOR_DOWN 有好处吗?
  • @Changeling:它将所有位标志保存在一个位置,从而使可维护性更容易。
【解决方案3】:

这是一种方法:

const int bit0 = (1<<0);
const int bit1 = (1<<1);
const int bit2 = (1<<2);
//...

const int motor_up = bit0;
const int motor_down = bit1;

【讨论】:

    【解决方案4】:

    你可以使用一个函数来代替:

    #define BIT(n) (1<<(n))
    

    *针对宏怪物合规性进行了编辑

    【讨论】:

    • 问题不是说没有#define吗?
    • @Billy: '当然,但我认为这样做是为了避免手动执行 32 #define BITs,这很好。
    • 啊...如果这是他的意图,那么问题写得很糟糕哈哈。
    • 宏观怪物说,“我需要更多的括号!”:#define BIT(n) (1 &lt;&lt; (n))
    【解决方案5】:

    使用模板怎么样?

    template <int BitN>
    struct bit
    {
        static const int value = (1 << BitN);
    }
    

    你会这样使用它:

    const int MOTOR_UP   = bit<0>::value;
    const int MOTOR_DOWN = bit<1>::value;
    

    或者使用枚举:

    enum
    {
        MOTOR_UP   = bit<0>::value,
        MOTOR_DOWN = bit<1>::value
    }
    

    【讨论】:

    • 该值在编译时可用,因此枚举没有理由不起作用。
    • @Grant Peters:当我在没有编译器的情况下回答问题时,我过于谨慎了;)
    • 嗯,有什么意义呢? bit::value 并不比 (1 更具表现力
    • @peterchen:这比我的答案更适用于原始问题(它同样适用于这里的大多数其他答案)。话虽如此,我不同意它没有比原始表达式更具表现力的说法。只是“位”这个词的存在,对于不熟悉移位操作的人来说,稍微容易理解一些。
    • @Vertexwahn 当然可以!编辑:我将此代码发布给任何人用于任何用途,不提供任何保证。
    【解决方案6】:

    我说结合 tzaman'sMartin York's 答案:

    #define BIT(x) (1 << (x))
    
    enum {
        motor_up = BIT(0),
        motor_down = BIT(1)
    };
    

    没有什么特别的原因会出现一堆像BIT0BIT1、...、BITn 这样的愚蠢名字的宏或枚举。

    枚举作为整数常量非常有用 - 它们没有宏全局命名空间踩踏能力,它们在 C 和 C++ 中同样适用(const int 类型并非如此)。

    【讨论】:

      【解决方案7】:

      您可能想要STL's std::bitset 之类的东西。

      【讨论】:

      • bitset 是一个不好的方法。您不能为各个位域赋予符号名称。
      • @JYoung:你也不能在这里给一半的其他答案赋予符号名称。至少对于bitset,您不会手动旋转位。
      【解决方案8】:

      使用位域联合和结构。 (对于比利:问题的解决方案是 C++ 代码。示例使用的是 C++/CLI。)

      union MotorControl
      {
          struct 
          {
              int motorUp :1;
              int motorDown :1;
          };
          struct 
          {
              int all;
          };
      };
      
      int main(array<System::String ^> ^args)
      {
          MotorControl mc;
          mc.all = 0;
          mc.motorDown = 1;
      }
      

      【讨论】:

      • -1 表示:那不是 C++。将其设为 C++,我将删除我的反对票。
      • 哦——这也不是可移植的字节序。我不会对此投反对票,但我想我会提到它。
      • 别听比利的,这是 C++ 代码。我一直在嵌入式 C++ 项目中使用它。当您使用硬件时,(如电机控制)移植到其他字节序硬件通常不是问题。
      • @Jyoung:不,那是 C++/CLI。 C++/CLI 不是 C++。您的联合和结构代码实际上是正确的。 main 错了。
      • 匿名结构也不是有效的标准 C++。
      【解决方案9】:

      我会稍微修改一下 Martin 的 answer

      enum Bits
      {
          BIT0    = 0x00000001,
          BIT1    = BIT0 << 1, 
          BIT2    = BIT1 << 1,
      
          MOTOR_UP    = BIT0,
          MOTOR_DOWN  = BIT1
      };
      

      使用移位运算符使事情更加一致,如果您稍微跳过一点,就会很明显。

      【讨论】:

      • 这与当前问题已过时,OP 刚刚打错了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多