左转与或

时间:2011-11-21 08:07:14

标签: c

i2c_receiveData(sDevice *psDevice, byte_t *pbBuffer, uint16_t *puiLen)
{
.
.    
//extract the packet data length
unFrameLen = (*(pbBuffer+1) << 8) | *(pbBuffer + 2);
if(unFrameLen > *puiLen)
unFrameLen=*puiLen;
.
.
}

这个语句如何找到帧长度?

unFrameLen =(*(pbBuffer + 1)&lt;&lt; 8)| *(pbBuffer + 2);

这里 pbBuffer 是指向unsigned char数组的指针。

调用函数是,

i2c_receiveData(psDevice, prgDataRecv, &unRegLen);

3 个答案:

答案 0 :(得分:4)

在这种情况下,似乎“帧长度”存储在偏移1处,并传递给传递的缓冲区。

它似乎也是一个16位整数。

要获得可用的16位整数,必须从缓冲区中解压缩。最好转换并使用htons / ntohs,但我认为架构是众所周知的,并且可移植性不是问题。

对于pbBuffer = {0, 1, 2}的输入,最终是:

(1 << 8) | 2;

...给出:

(00000001b << 8) | 00000010b

...将1b左移8位给出:

100000000b

...和OR {与10b

100000010b

现在,pbBuffer[1..2]中的两个8位整数有一个16位整数:

100000010b = 0x102

答案 1 :(得分:2)

显然,帧长度在第2和第3字节的协议中发送。该表达式构建了2个字节的16位整数。

*(pbBuffer+x)pbBuffer[x]相同,因此字节#1左移8,字节#2添加到其中。

如果您在pbBuffer收到,例如{ 0000 0000, 0101 0101, 1100 1100, ...}(二进制),提取的两个字节将是

*(pbBuffer+1) = 0101 0101
*(pbBuffer+2) = 1100 1100

计算将是

 *(pbBuffer+1) << 8                  = 0101 0101 0000 0000
(*(pbBuffer+1) << 8) | *(pbBuffer+2) = 0101 0101 1100 1100

逐位或(|)与此处的加法相同,因为(*(pbBuffer+1) << 8)的低8位全部为0。

请注意,细节略微取决于平台。

答案 2 :(得分:1)

将声明分成小块:

 *(pbBuffer+1)       /* gets the byte_t value one beyond the pbBuffer pointer */
(*(pbBuffer+1) << 8) /* shifts that byte eight bits left -- in essence
                        xxxxxxxx00000000 -- where xxx comes from pbBuffer+1 */


*(pbBuffer+2)        /* gets the byte_t value two beyond the pbBuffer pointer */

(*(pbBuffer+1) << 8) | *(pbBuffer + 2)
/* xxxxxxxx00000000  |  yyyyyyyy */
   xxxxxxxxyyyyyyyy */

这会将指定的两个字节重建为单个16位数据类型。这些 在处理网络时,各种操作尤为常见 代码,因为不同的机器有不同的byte orders。不同的顺序意味着大于一个字节的数字不能 在不使用network byte order的情况下在网络上轻松传播 作为中介格式。 (有些计算机在网络字节中工作 本地订购,而其他人必须始终执行转换。)