假设*c
为内存中的32位,xmc[]
为内存中的32位数组(摘要:网络数据包)
xmc[0] = (*c >> 4) & 0x7;
xmc[1] = (*c >> 1) & 0x7;
xmc[2] = (*c++ & 0x1) << 2;
xmc[2] |= (*c >> 6) & 0x3;
xmc[3] = (*c >> 3) & 0x7;
代码行xmc[2]
对Value做了什么(以二进制考虑)?
我试着查算术题,但我没能理解从*c++
开始的部分。
编辑:添加了更多上下文以进行澄清
5条答案
按热度按时间hrysbysz1#
c
指针所指地址的值,并递增该地址。&
)是用值0x1
(十进制1
)的掩码执行的,这意味着仅从存储在地址c
的值中取出最低有效位。你可以这样想:您可以有一个4位变量,称为
a
,其十进制值为3
(二进制0011
),并且您正在a
和十进制值2
(二进制10
)的掩码之间执行逐位AND,也是4位(因此0010
):a = 0011
b = 0010
位与(
a & b
或a & (0x10)
)将计算a
和b
中每两位之间的AND。a
中的第一位为1
,b
中的第一位为0
=〉结果中的最低有效位为1 & 0 = 0
,继续每个变量的第二位,导致结果中的第二最低有效位为1
等等。带有此类掩码的
AND
通常用于从存储在变量中的值中获取特定位(或一组位)。在您的情况下,代码将获取存储在a
中的最低有效位。<<
将最低有效位向左移两个位置(例如,从0001
到0100
),将0
上的2位向右添加。xienkqul2#
假设我们对一个无符号的32位值进行运算。
相当于
在伪代码中,这意味着:
gkl3eglg3#
今天的日期可以说是20230215。
如果您将其作为一个数字,则可以按如下方式提取组件:
上面的代码也做了同样的事情,它提取分布在两个字节上的四个值(
a
、b
、c
和d
)。因为我们想提取比特而不是数字,所以我们需要使用2的幂而不是10的幂,当处理2的幂时,
>>
可以用来代替除法,&
可以用来代替%
。要提取
a
、b
、c
和d
,我们可以使用以下代码:发布的代码采用了一种避免计算
n
的方法,但它做的是同样的事情。pxyaymoc4#
++
是C语言中的一个后增量运算符,它将是在=
左边赋值之前的最后一个运算。这一声明可被视为:
1.取消引用:
*c
1.位与:
*c & 0x1
1.左移:
(*c & 0x1) << 2
1.增量后:
c++
1.分配到=的左侧:
xmc[2] =
为第3步的结果。但是,编译器将通过其设计优化这些操作,并可能通过利用CPU的寄存器和内存中的堆栈在按位AND操作之前增加
c
,即可能在最终汇编代码中发现差异。oyxsuwqo5#
发布的代码可以更容易阅读,如果它是,相当于:
(And然后,如果后面的代码依赖于
c
被推进,则这之后可以是独立的c++
。)看起来
xmc[0]
取自c[0]
的三个特定位,而xmc[1]
取自c[0]
的三个其它位。然后下一个字段跨越字边界,因为xmc[2]
是通过将c[0]
中的一个位放在一起而组成的。并且从c[1]
中取出两个位。最后,从c[1]
的其它三个位中取出xmc[3]
。@池上的回答有更多细节。