#define SwapByte4(ldata) \
(((ldata & 0x000000FF) << 24) | \
((ldata & 0x0000FF00) << 8) | \
((ldata & 0x00FF0000) >> 8) | \
((ldata & 0xFF000000) >> 24))
0x000000FF代表什么?我知道小数15用十六进制表示为F,但为什么它&lt;&lt; 24?
答案 0 :(得分:30)
这是一个十六进制值0x12345678,写为二进制,并带有一些位位置注释:
|31 24|23 16|15 8|7 bit 0| +---------------+---------------+---------------+---------------+ |0 0 0 1 0 0 1 0|0 0 1 1 0 1 0 0|0 1 0 1 0 1 1 0|0 1 1 1 1 0 0 0| +---------------+---------------+---------------+---------------+
......这里是0x000000FF:
+---------------+---------------+---------------+---------------+ |0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|1 1 1 1 1 1 1 1| +---------------+---------------+---------------+---------------+
因此,按位AND仅选择原始值的底部8位:
+---------------+---------------+---------------+---------------+ |0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 1 1 1 1 0 0 0| +---------------+---------------+---------------+---------------+
...并将其向左移动24位将其从底部的8位移到顶部:
+---------------+---------------+---------------+---------------+ |0 1 1 1 1 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0| +---------------+---------------+---------------+---------------+
...十六进制为0x78000000。
其他部分适用于输入的剩余8位部分:
0x12345678 & 0x000000FF ---------- 0x00000078 << 24 = 0x78000000 (as shown above) 0x12345678 & 0x0000FF00 ---------- 0x00005600 << 8 = 0x00560000 0x12345678 & 0x00FF0000 ---------- 0x00340000 >> 8 = 0x00003400 0x12345678 & 0x00000000 ---------- 0x12000000 >> 24 = 0x00000012 | ---------- 0x78563412
所以整体效果是将32位值ldata
视为四个8位字节的序列,并颠倒它们的顺序。
答案 1 :(得分:5)
这种代码往往用于在big endian and little endian格式之间交换内容。还有一个小技巧可以将一些已知格式的单词(比方说,小端)转换为当前机器所遇到的任何字节顺序,反之亦然。这将是这样的:
unsigned long littleEndian;
unsigned char* littleBytes = &littleEndian;
unsigned long result = 0;
for (i = 0; i < 4; i++)
result += unsigned long(littleBytes[i]) << (8 * i);
这是有效的(假设我没有弄乱它),因为无论实际存储的是多少字节,左移都可以保证向更高位移位。转换为char *允许您按照它们实际存储在内存中的顺序访问字节。使用此技巧,您无需检测机器字节序以读取/写入已知格式的内容。不可否认,你也可以使用标准函数(hton等):P
(注意:你必须要小心一点,然后在转移之前施放char,否则它只会溢出你的鞋子。而且,+ =不是唯一的选择,| =可能会更有意义,但可能是不太清楚,如果你不习惯,我不确定)
答案 2 :(得分:2)
你需要将0x000000FF
看作一个位掩码,即它的值为1 ldata
将被取代,并且它将取0 - 0。
为了理解你需要将其转换为二进制的位掩码,使用hex非常容易,每个十六进制数字都是4个二进制数字,即:
hex 0 =二进制0000 十六进制1 =二进制0001 等等。
现在转换:请注意,转移从源获取一些数据,准确地取出8位,并将其移动到目标中的另一个位置。
现在请注意,|
即对所有位掩码AND操作进行OR运算,即零将保持为零,如果为'1',则结果将包含一个。
希望有所帮助:)
答案 3 :(得分:0)
假设数据是32位数字,表示为0x12345678(每个数字为4位十六进制)
数据&amp; 0x000000FF表示仅保留最后8位(称为位掩码) = 0x00000078
&lt;&lt; 24表示将此值移至左侧24位(位置24处开始78 [0索引]) = 0x78000000
|意味着逻辑或在这种情况下只是一个加法
最终结果= 0x78563412
阅读逻辑操作