如何在不更改 C 中其余位的情况下在特定位置设置新的位模式?

How do I set a new bit pattern in a certain position without changing the rest of the bits in C?

假设我有以下 unsigned long val = 0xfedcba9876543210,我想将 16 个最低有效位更改为 0xabcd。因此,原始值将更改为 unsigned long val = 0xfedcba987654abcd。我已经有一个可以 return 0x3210 的函数 get,但我不确定如何将这部分值更改为 0xabcd。有关更多上下文,这是我要实现的内容:

void set_pattern(unsigned long* val, int i, unsigned short new_pattern) {
  // my attempt
  unsigned short old_pattern = get(val, i); // ex: returns 0x3210 when i = 0
  unsigned short* ptr = NULL;
  ptr = &old_pattern;
  *ptr = new_pattern;
}

当我尝试时,它似乎没有像我预期的那样设置新模式。感谢任何帮助或反馈,以帮助我更好地理解 C。

好简单的解决方法:

  1. 0xfedcba9876543210 & 0xfedcba9876540000
  2. 0xfedcba9876540000 | 0x000000000000abcd

解释 , you want to apply a bitmask 将相关位清零,然后使用按位或应用新位。

让我们用 32 位来做,你想改变至少 8 个。

应用位掩码将最少 8 位变为 0。val = val & ~0xff~0xff0xffffff00。由于0 & x = 0,所有填充的位都将保留其值,所有的0无论其原始值如何都将变为0。

    0x12345678  val
AND 0xffffff00  ~0xff
  = 0x12345600

既然相关位已经被屏蔽掉,变为0,我们可以用按位或来覆盖它们。 val = val | new_valuex | 0 = x。 new_value 的无关位是 0. x | 0 = x。他们将保留 val 的价值。 val 的相关位为 0。 0 | x = x。他们将保留 new_value 的价值。

   0x12345600  val
OR 0x000000ef  new_value
 = 0x123456ef

如果要替换不同的位,需要将位掩码和替换值移动适当的量。

假设我们想用 ef 代替 56。每个十六进制字符为 4 位,因此我们需要将位掩码和替换值都左移 8 位。

    0x12345678  val
AND 0xffff00ff  ~(0xff << 8) == ~0xff00
  = 0x12340078

    0x12340078  val
OR  0x0000ef00  new_value << 8 == 0xef00
 =  0x1234ef78