【问题标题】:How to construct a C macro for low-level bit masking?如何构建用于低级位掩码的 C 宏?
【发布时间】:2014-07-09 19:25:50
【问题描述】:

我开始学习编程嵌入式 C 微控制器,并想做一些让我的生活更轻松的事情。通常在处理位掩码时,每个人都会使用以下内容:

char a = (1 << 3) | (1 << 1) | (1 << 5);

我想为这样的事情使用宏。对于一个掩码,我可以简单地定义这个宏:

#define M(n) (1 << (n))

没什么特别的。问题是我无法找到一个可以让我输入的好的解决方案:

a = MM( 3, 1, 5 ); 或至少a = MM( 3, 3, 1, 5 );(其中第一个3 是参数的数量)

而不是a = M(3) | M(1) | M(5);

我想出了一个解决方案,它暗示使用具有多个参数的函数,但我无法使用宏来做到这一点,这真的让我很烦恼。

【问题讨论】:

  • 当然可以。 #define MM( nr, args... ) //whatever 查看可变参数宏。
  • 查看常见的 MCU 头文件以查看好的宏示例。你似乎也想有点太花哨了。例如,在我的 msp430 项目中,某处有一堆 #define BIT0 1&lt;&lt;0#define BIT1 1&lt;&lt;1 等等……而且它非常易读,而且更喜欢看到像 P1OUT = BIT1 | BIT2 | BIT3 这样的代码。您可以使用这些来定义您可能经常使用的更复杂的掩码。
  • 查看之前的回答:stackoverflow.com/questions/1872220/…
  • 我知道我的愿望可能有点花哨,但我认为这个问题更多的是一个有趣的难题,而不仅仅是需要好的代码。

标签: c macros embedded bit-manipulation


【解决方案1】:

找到了答案。

#define M(a)        (1 << (a))
#define M2(a, b)    (M(a) | M(b))
#define M3(a, b...) (M(a) | M2(b))
#define M4(a, b...) (M(a) | M3(b))
// can be continued

#define GET_MACRO( _1, _2, _3, _4, NAME, ... ) NAME
#define MM(args...) GET_MACRO( args, M4, M3, M2, M )(args)

这使用this thread中的答案

【讨论】:

  • 这不是有效的 C 语法,但使用了 gcc 扩展。它应该只有M3(a, ...)MM(...) 并使用__VA_ARGS__ 而不是bargs
【解决方案2】:

也许这会有所帮助:

#define BITMASK_SET(x,y) ((x) |= (y))
#define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
#define BITMASK_FLIP(x,y) ((x) ^= (y))
#define BITMASK_CHECK(x,y) ((x) & (y))

【讨论】:

    【解决方案3】:

    使用提升

    #include <boost/preprocessor/tuple/to_seq.hpp>
    #include <boost/preprocessor/seq/for_each_i.hpp>
    #include <boost/preprocessor/control/if.hpp>
    
    #define M(n) (1 << (n))
    #define F(r, data, i, elem) BOOST_PP_IF(i, data, ) M(elem)
    #define MM(...) BOOST_PP_SEQ_FOR_EACH_I(F, | , BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__)) )
    
    ...
    char a = MM(3, 1, 5);//char a = (1 << (3)) | (1 << (1)) | (1 << (5)) ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-29
      • 2010-09-23
      • 2014-02-03
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 1970-01-01
      相关资源
      最近更新 更多