Macros to set and clear bits
我试图编写一些简单的宏来简化设置和清除位的任务,这应该是一个简单的任务,但是我似乎无法使它们正常工作。
1 2
| #define SET_BIT(p,n) ((p) |= (1 << (n)))
#define CLR_BIT(p,n) ((p) &= (~(1) << (n))) |
- 如果你说宏是如何,确切地说,不起作用的话,这会有所帮助。
- 很抱歉忽略了这一点…我认为这个错误对这里一些精通C语言的程序员来说是显而易见的,而不是我试图解释…
- 我可以看到两个潜在的问题,但是没有任何背景,就不可能知道什么适用于你的情况,什么不适用。
尝试
1
| #define CLR_BIT(p,n) ((p) &= ~((1) << (n))) |
然而,由于宏观邪恶的各种原因,我建议不要使用宏观。使用内联函数和传递引用,如下所示:
1 2 3
| static inline void set_bit(long *x, int bitNum) {
*x |= (1L << bitNum);
} |
号
- 谢谢你的努力。我听说过宏的"坏处",通常我会限制对它们的使用,但在这种情况下,我只是为了简化在AVR控制器上设置和清除端口管脚的任务,例如clr_位(porta,pin3),我认为在这种情况下定义是可以接受的?但我想使用内联函数可以消除任何头痛。
- 它们是可以接受的,当然还有更糟糕的使用预处理器的方法:stackoverflow.com/questions/652788,但总有一天你会发现一个奇怪的bug,这个bug与宏相关。
- 是的,我看到了很多宏线程的恐怖。令人害怕的是,人们很容易就会破坏C语言…我认为我会坚持使用内联函数,只要它们和宏一样快,就不会丢失任何东西,只有获得。
- 这些特定的宏非常安全,因为它们只计算一次每个参数。
- 同意,它们是相当安全的,但是如果你不小心给它们一个指针参数或者类似的参数,那么错误会比平常更神秘。不过,带有副作用的宏太容易出错。
- 当sizeof(int)
- 很好,保罗。我太习惯我的32位处理器了…
- 为什么应该是静态的?我给自己写了一个标题,上面有这样的函数,我没有使用static,但是它工作得很正常。
一个明显的问题是,((p) &= (~(1) << (n)))应该是((p) &= ~(1 << (n)))。
除此之外,您还必须注意整数类型的宽度。如果您使用的是unsigned long,您可能需要使用(例如)((p) |= (1UL << (n)))
- 是的,你的权利,这就是问题所在,谢谢。
- +1用于指出整数大小调整问题。
呃。您是否没有一组本地函数来为您执行此操作?这将隐藏跨越单词边界时必须发生的任何魔法。
如果失败了,那么上述的失败又是怎样的呢?它们看起来"不错",但如果函数不可用,我还是宁愿手工做这类事情。宏只是在做这种事情时隐藏讨厌的错误。传递有符号与无符号等不会被宏捕获。