C语言 设置和清除位的宏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2978408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:36:03  来源:igfitidea点击:

Macros to set and clear bits

cembeddedmacrosbit-manipulation

提问by volting

Im trying to write a few simple macros to simplify the task of setting and clearing bits which should be a simple task however I cant seem to get them to work correctly.

我试图编写一些简单的宏来简化设置和清除位的任务,这应该是一项简单的任务,但我似乎无法让它们正常工作。

#define SET_BIT(p,n) ((p) |= (1 << (n)))
#define CLR_BIT(p,n) ((p) &= (~(1) << (n)))

回答by Artelius

Try

尝试

#define CLR_BIT(p,n) ((p) &= ~((1) << (n)))

However for various reasons of general macro evil I would advise not using a macro. Use an inline function and pass by reference, something like this:

然而,出于一般宏邪恶的各种原因,我建议不要使用宏。使用内联函数并通过引用传递,如下所示:

static inline void set_bit(long *x, int bitNum) {
    *x |= (1L << bitNum);
}

回答by CB Bailey

One obvious issue is that ((p) &= (~(1) << (n)))should be ((p) &= ~(1 << (n))).

一个明显的问题是((p) &= (~(1) << (n)))应该是((p) &= ~(1 << (n))).

Apart from that, you do have to be careful with the width of your integer types. If you were using unsigned longyou might need to use (e.g.) ((p) |= (1UL << (n)))

除此之外,您必须小心整数类型的宽度。如果您正在使用,unsigned long您可能需要使用(例如)((p) |= (1UL << (n)))

回答by Michael Dorgan

Ugh. Do you not have a set of functions locally to do this for you? That would hide any sort of magic that has to occur when skipping across word boundaries.

啊。您在本地没有一组功能可以为您执行此操作吗?这将隐藏跳过单词边界时必须发生的任何类型的魔法。

Failing that, how does the above fail? They look 'ok', but I'd still rather do this sort of thing by hand if functions aren't available. Macros just hide nasty bugs when doing this sort of thing. Passing signed vs unsigned, etc. Won't be caught with Macros.

失败了,上面的如何失败?它们看起来“还可以”,但如果功能不可用,我仍然宁愿手工做这种事情。在做这种事情时,宏只是隐藏了令人讨厌的错误。传递签名与未签名等。不会被宏捕获。