十六进制数的C位操作

十六进制数的C位操作,c,hex,C,Hex,有没有一种方法可以访问C中十六进制数的某些部分 我想写一个函数,它接受一个十六进制数并求反,但保留最低有效字节不变。示例:0x87654321应变为0x789ABC21 我试图以某种方式保存LSB,然后将其应用于求反的x,但我的问题是我的掩码应用于所有字节。我可以为特定的值硬编码,但显然这不是我想要的 void b(int x) { int temp = x & 0xFF; // temp is all 0 with the LSB being the same as x's x

有没有一种方法可以访问C中十六进制数的某些部分

我想写一个函数,它接受一个十六进制数并求反,但保留最低有效字节不变。示例:0x87654321应变为0x789ABC21

我试图以某种方式保存LSB,然后将其应用于求反的x,但我的问题是我的掩码应用于所有字节。我可以为特定的值硬编码,但显然这不是我想要的

void b(int x) {
  int temp = x & 0xFF; // temp is all 0 with the LSB being the same as x's
  x = ~x;  // this negates x
  // one of a couple of attempts I tried thus far:
  // x = (x & 0x00) | temp; 
  // idea: change x's LSB to 00 and OR it with temp, 
  // changing x's LSB to temp's LSB
}

如果您不发布解决方案的代码,而只是回答是否有方法将位运算应用于十六进制数的特定部分,或者我如何解决此问题,我将不胜感激。

通常,您可以使用掩码对值的特定位进行运算

掩码是一种位模式,在需要操作的位置有1,在不需要操作的位置有0

看起来您需要3个操作:提取最低字节、求反、恢复最低字节。你们可以算出否定,所以我将只讨论提取一个位字段和恢复一个提取的位字段

要提取指定的位,请对所需位使用带1的掩码,并使用按位and运算符
&
。and运算符为掩码的所有0设置0,当掩码为1时,它从另一个参数复制位。如果需要在程序中的其他位置检查该值,也可以方便地将该值右移到最低位置(以便更容易在表中查找)

若要还原保存的位,请在先前将其下移时将其上移。然后从值中清除这些位,并使用inclusive或
|
作为所有一位的位和。要清除值中的位,请使用第一次操作中掩码的倒数。例如,
y=x&0xf
保存一个半字节,
x&~0xf
清除该半字节,
(x&~0xf)| y
重新组合为相同的原始x

编辑: 如果要提取的片段不在最低位置,比如32位无符号整数的第二个字节(LSB),那么将提取的值移到零位置以处理它可能会很有用

x = 0x12345678;
y = x & 0xFF00;  // == 0x5600
y >>= 8;         // == 0x56
但如果这样做,则必须先将其移回正确位置(当然),然后再使用位字段的新值更新较大的值

x = (x & ~0xFF00) | (y << 8);

x=(x&~0xFF00)|(y如果我正确理解了这个问题,它似乎是这样的(未经测试)


我找到了一种操作所选字节的方法。(!!!这将是CS:APP的家庭作业2.60!!!)

如果0x12345678是类型为int的给定十六进制值,则这样做将允许我更改第i个字节:

int x = 0x12345678;
unsigned char* xptr = (unsigned char*) &x;
xptr[i] = 0; // say i=2, then this would yield: 0x120045678
现在,如果我想在字节I的位置添加一个值,比如0xAB,我会做luser droog已经提到的事情:

int temp = 0xAB;
temp = temp << i*8; // say i=2, then this would yield: 0x00AB0000
x = x | temp; // this yields the desired result 0x12AB3456
int-temp=0xAB;

Timp = Timp,我对C不太熟悉,那么java或C++中的具体操作和做的是逻辑比较,但是这里没有什么意义,是不是?<代码> x=(~x和~0xFF)(x和0xFF)。
虽然我希望得到一个指导性的答案,而不是一些代码,但我仍然很感激。谢谢李,这确实有效。我知道,但正如我所说,我的掩码应用于所有位。掩码是一个工具,通过控制二进制操作的真值表来选择要应用的位。好的。我确实让它与您一起工作r方法-好吧,基本上我做了李·丹尼尔·克罗克已经建议过的同样的事情。虽然我不太理解正确移位的部分。你能详细说明一下,或者举个小例子吗?@Beko编辑了更多关于移位的内容。他说LS byte,而不是bit,你的代码依赖于32位int,所以你的常量应该是
~0xFF
0xFF
@LeeDanielCrocker:没有注意到是字节而不是位。更新了。当,按照说明浪费了我的时间
如果你不发布解决方案的代码,我将不胜感激。
不,你没有。只是你最初的答案不太正确。好的。很抱歉抱怨。:)
int temp = 0xAB;
temp = temp << i*8; // say i=2, then this would yield: 0x00AB0000
x = x | temp; // this yields the desired result 0x12AB3456