有没有办法在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
}
如果您没有为解决方案发布代码,我会感激不尽,而只是回答是否有办法将位操作应用于十六进制数的特定部分,或者我如何解决这个问题
答案 0 :(得分:3)
通常,您可以使用掩码对值的特定位进行操作。
一个掩码是位模式,你要操作的是1s,你不喜欢的是0。
好像你需要3个操作:提取最低字节,否定,恢复最低字节。你可以弄清楚否定,所以我只谈谈提取位域并恢复提取的位域。
要提取指定的位,请使用1s的掩码作为所需的位,并使用按位和运算符&
。 和运算符为掩码的所有0设置0,并且掩码为1,它从另一个参数复制位。如果您需要在程序的其他位置检查此值,将值>>
向右移动到最低位置也是很方便的(这样可以更容易在表中查找)。
要恢复已保存的位,如果先将其向下移动,请向上移动。然后从值中清除这些位,并使用 inclusive-or |
作为所有位的按位求和。要清除值中的位,请使用第一个操作中的掩码的反转。 IE浏览器。 y = x & 0xf
保存一个半字节,x & ~0xf
清除那个半字节,(x & ~0xf) | y
重新组合到相同的原始x。
编辑: 如果你提取的部分不在最低位置,比如说是32位无符号整数的第二个字节(LSB),那么将提取的值移动到零位置以使用它可能很有用。 / p>
x = 0x12345678;
y = x & 0xFF00; // == 0x5600
y >>= 8; // == 0x56
但如果你这样做,那么你必须将它移回正确的位置(当然),然后用位域的新值更新较大的值。
x = (x & ~0xFF00) | (y << 8);
答案 1 :(得分:2)
如果我正确地理解了这个问题,看起来就像这样(未经测试)。
void b(int x) {
return (~x & ~0xFF) | (x & 0xFF);
}
答案 2 :(得分:0)
我找到了一种操纵所选字节的方法。 (!!!这将是CS的家庭作业2.60:APP !!!)
如果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