在没有条件的情况下,使用另一个无符号字符的另一位设置一个unsigned char

我使用bitwise以这种方式打开和关闭位:

unsigned char myChar = ...some value myChar |= 0x01 << N // turn on the N-th bit myChar &= ~(0x01 << N) //turn off the N-th bit 

现在,假设N的值已知,但set / unset操作依赖于另一个unsigned char的值。 从现在开始,我这样做:

 if ((otherChar & (0x01 << M)) != 0) { //M-th bit of otherChar is 1 myChar |= 0x01 << N; }else { myChar &= ~(0x01 << N); } 

这应该是从unsigned char到另一个char的“移动位”操作。

我的问题:有没有办法在不使用条件的情况下这样做? (也没有std :: bitset)

简短的回答是“是”。

更长的答案是您直接从源使用该位:

 unsigned char bit = 1 << N; myChar &= ~bit; // Zero the bit without changing anything else myChar |= otherChar & bit; // copy the bit from the source to the destination. 

这假设您要将位N从源复制到目标的位N. 如果源位和目标位可能处于不同的偏移量,则事情变得更加困难。 您不仅要从源中提取正确的位,而且还必须将其移至正确的位置,然后将其移至目标位置。 基本思路就像上面一样,但转移的代码有点单调乏味。 问题是你想做的事情如下:

 unsigned char temp = source & 1 << M; temp <<= N - M; dest |= temp; 

如果N> M,这将正常工作,但如果M> N,你最终会得到像temp <<= -3; 。 你想要的是左移-3为最终为3的右移 - 但这不是发生的事情,所以你需要一些条件代码来取绝对值并弄清楚是否做对了shift或left shift从源到位到目的地的正确位置。

一种解决方案是首先始终取消该位,然后按位或在其他otherChar的适当移位和屏蔽版本中otherChar

将从 c1的位读取并将其写入c2的to位。

 #include  typedef unsigned char uchar; uchar move_bit(uchar c1, int from, uchar c2, int to) { int bit; bit = (c1 >> from) & 1; /* Get the source bit as 0/1 value */ c2 &= ~(1 << to); /* clear destination bit */ return (uchar)(c2 | (bit << to)); /* set destination bit */ } int main() { printf("%02X\n",move_bit(0x84,3,0x42,5)); printf("%02X\n",move_bit(0x81,0,0x03,7)); printf("%02X\n",move_bit(0xEF,4,0xFF,6)); return 0; } 

结果:

 42 83 BF