在C语言中,设置变量中的特定位最好的方法是什么?

5
考虑一个C语言中的变量unsigned int a;
现在假设我想要将这个变量的第i位设置为1。
请注意,该变量已经有了一些值。因此,a=(1<<i)将无法工作。 a=a+(1<<i)可以工作,但是我正在寻找最快的方法。有什么办法吗?

你为什么认为需要“最快”的方法来做这件事? - Paul R
"a=(1<<i)" 这段代码不会起作用,因为它将清除所有其他的位。如果问题位已经设置,"a = a+(1<<i)" 这个表达式也不行,加法运算将清除这一位并向左侧相邻位产生进位。 - Lindydancer
@Lindy:是的,我知道a=(1<<i)不起作用,就像我在帖子中说的那样。但正如你所说和其他人的评论,最好使用OR运算符。 - vipin
7个回答

11

对它执行按位或运算。例如:a |= (1<<i)


编译器会将 a |= (1<<i) 和 a=a+(1<<i) 转换为相同的机器码吗?我的意思是哪个更快? - vipin
1
@vipin:不,它们并不等价(即当第i位已经设置时,结果会有所不同)。至于性能:唯一的方法是进行性能分析!但我猜对于99%的实际应用程序(即排除仅做无数次赋值的微基准测试),您将无法测量任何真正的差异。 - user395760
加法是带进位的异或操作。这需要更少量的硬件支持,但我怀疑 addl 指令所需的时钟周期不会比 orl 指令更长。 - Matt K

8
一些实用的位运算宏
#define BIT_MASK(bit)             (1 << (bit))
#define SET_BIT(value,bit)        ((value) |= BIT_MASK(bit))
#define CLEAR_BIT(value,bit)      ((value) &= ~BIT_MASK(bit))
#define TEST_BIT(value,bit)       (((value) & BIT_MASK(bit)) ? 1 : 0)

3
最常用的方法是:
a |= (1 << i);

这只有两个操作——移位和或运算。很难想象如何进一步改进它。

2
你应该使用按位或运算符进行此操作。
a |= 1 << i;

1

你可能可以使用

a |= (1 << i)

但这不会有太大的影响。就性能而言,您不应该看到任何差异。

您可以尝试构建一个表格,将 i 映射到位掩码(例如,2 => 0x0010 对于 0000000000100),但这有点不必要。


1
你可以使用按位或符号:
a |= (1 << i);

请注意,这与“+”的行为不同,如果您要设置的位中已经有1,则“+”会将其保留。但是本方法不会。

1

我实现位标志的方式(引用我的代码库,您可以自由地将其用于任何目的,甚至商业用途):

void SetEnableFlags(int &BitFlags, const int Flags)
{
    BitFlags = (BitFlags|Flags);
}
const int EnableFlags(const int BitFlags, const int Flags)
{
    return (BitFlags|Flags);
}

void SetDisableFlags(int BitFlags, const int Flags)
{
    BitFlags = (BitFlags&(~Flags));
}
const int DisableFlags(const int BitFlags, const int Flags)
{
    return (BitFlags&(~Flags));
}

不需要位移操作。

你可能需要整理或修改代码以使用特定的变量集,但通常它应该可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接