我有一个16位的地址,我需要为抵消这种分裂成15-8页号和7-0。
所以,我猜我会做它按位老年退休金计划?
比方说0xBEEF
是需要被拆分的地址。
页码:
0xBEEF & 0xFF80= 1011 1110 1110 1111 & 1111 1111 1000 0000 = 1011 1110 1000 0000 = 0xBE80
偏移:
0xBEEF & 0x007F= 1011 1110 1110 1111 & 0000 0000 0111 1111 = 0000 0000 0110 1111 = 0x006F
是否有不同的方式来做到这一点,除了按位算术下的宏?
是的,有一对夫妇,你可以做到这一点不同的方式,但我可以推荐他们没有 。
分裂的高低位的16位值在C ++做的一个非常棘手的事情,因为位的顺序取决于硬件的存储方式。 如果你的系统是大端系统,高位将被第二个存储,如果你的系统是小端,高位首先存储。
让我们把你的0xBEEF的例子,这里是什么样子的记忆:
little endian | big endian
-------------------------------------
... EF BE ... | ... BE EF ...
如果您使用位算术这两个字节分开,你不必关心它们在内存中的顺序,但几乎任何其他方法都将受到影响,需要你以某种方式检测字节顺序和程序有条件有一个便携式解决方案。
话虽这么说,这里有几个选择,如果你不关心可移植性,你可以使用:
1)投
该方法基本上是由冰层提出的一个。 你把这个变量的ADRESS,将它转换为字符指针,并把它当作一个数组,以获得不同的字节。
2)工会
具有与中投同样的效果,你也可以创建一个这样的联盟:
union myvalue
{
uint16_t value;
uint8_t bytes[2];
}
以能够分别ADRESS字节和值
3.)反向
另一种完全不同的方式将存储您的16位数据,无符号字符的摆在首位的数组,你买的地址计算开销,但你并不需要的字节分开。 当然,如果地址是不知何故计算的结果,你无论如何都要分裂字节,这样就没有意义了。
最后一句话-请使用AND和转移到提取字节,如果你关心你的代码的可移植性。
您可以在大多数程序使用位位移运算符。
top8 = 0xABCD >> 8; bottom8 = 0xABCD & 0x00FF;
这会给你top8 = 0x00AB
和bottom8 = 0x00CD
。
请注意,您不必由8位转向他们,它可以是任何东西。
这里是一个办法做到这一点无需位操作:
对于大端系统:
#define OFFSET(x) (*(unsigned char *)x)
#define PAGE(x) (*((unsigned char *)x + 1))
对于little-endian的系统切换的定义OFFSET
和PAGE
。
请注意,前提是char是8位在您的系统(如果不是一些奇怪的原因,使用适当的8位类型)。