如果 ,以下几行究竟是如何工作的pData = "abc"
?
pDes[1] = ( pData[0] & 0x1c ) >> 2;
pDes[0] = ( pData[0] << 6 ) | ( pData[1] & 0x3f );
如果 ,以下几行究竟是如何工作的pData = "abc"
?
pDes[1] = ( pData[0] & 0x1c ) >> 2;
pDes[0] = ( pData[0] << 6 ) | ( pData[1] & 0x3f );
好的,假设绝对不能保证的 ASCIIpData[0]
是'a'
( 0x61
) 并且pData[1]
是'b'
( 0x62
):
pDes[1]:
pData[0] 0110 0001
&0x1c 0001 1100
---- ----
0000 0000
>>2 0000 0000 0x00
pDes[0]:
pData[0] 0110 0001
<< 6 01 1000 0100 0000 (interim value *a)
pData[1] 0110 0010
&0x3f 0011 1111
-- ---- ---- ----
0010 0010
|(*a) 01 1000 0100 0000
-- ---- ---- ----
01 1000 0110 0010 0x1862
这个怎么运作:
<< N
只是意味着将位N
空间向左移动,>> N
相同但向右移动。
当且仅当两个输入中的对应位均为 1 时, &
( and
) 操作会将结果的每一位设置为 1。
如果两个输入中的一个或多个对应位为 1,则|
( or
) 操作将结果的每个位设置为 1。
pDes[0]
请注意,如果类型不够宽,0x1862 将被截断以适应。
以下 C 程序显示了这一点:
#include <stdio.h>
int main(void) {
char *pData = "abc";
int pDes[2];
pDes[1] = ( pData[0] & 0x1c ) >> 2;
pDes[0] = ( pData[0] << 6 ) | ( pData[1] & 0x3f );
printf ("%08x %08x\n", pDes[0], pDes[1]);
return 0;
}
它输出:
00001862 00000000
并且,当您更改pDes
为 char 数组时,您会得到:
00000062 00000000
&
不是逻辑与 - 它是按位与。
a
是 0x61,因此pData[0] & 0x1c
给出
0x61 0110 0001
0x1c 0001 1100
--------------
0000 0000
>> 2
将其向右移动两个位置 - 值不会改变,因为所有位都为零。
pData[0] << 6
左移0x61
6 位给出01000000
或0x40
pData[1] & 0x3f
0x62 0110 0010
0x3f 0011 1111
--------------
0x22 0010 0010
因此它归结为0x40 | 0x22
- 再次|
不是逻辑或,它是按位的。
0x40 0100 0000
0x22 0010 0010
--------------
0x62 0110 0010
pDes
如果不是 char 数组,结果会有所不同。左移0x61
会给你0001 1000 0100 0000
或0x1840
- (如果pDes
是一个字符数组,左边的部分不在图片中)。
0x1840 0001 1000 0100 0000
0x0022 0000 0000 0010 0010
--------------------------
0x1862 0001 1000 0110 0010
pDes[0]
最终会是0x1862
or decimal 6242
。
C++ 将根据字符的编码将字符视为数字。因此,假设 ASCII,“a”为 97(位模式为 0110_0001),“b”为 98(位模式 0110_0010)。
一旦将它们视为数字,对字符的位操作应该会更清晰一些。
在 C 中,所有字符也是整数。这意味着"abc"
相当于(char[]){0x61, 0x62, 0x63, 0}
。
&
不是逻辑AND 运算符 ( ) &&
。它是按位 AND,它在位级计算 AND,例如
'k' = 0x6b -> 0 1 1 0 1 0 1 1
0x1c -> 0 0 0 1 1 1 0 0 (&
———————————————————
8 <- 0 0 0 0 1 0 0 0
这里的主要目的& 0x1c
是从pData[0]
. 然后>> 2
在最后删除多余的零。
类似地,这& 0x3f
是从 中提取#0 ~ #5 位pData[1]
。
在位的<< 6
最低有效端推入 6 个零。假设pDes[0]
也是 a char
,最高有效 6 位将被丢弃:
'k' = 0x6b -> 0 1 1 0 1 0 1 1
<< 6 = 0 1 1 0 1 0 1 1 0 0 0 0 0 0
xxxxxxxxxxx—————————————————
0xc0 <- 1 1 0 0 0 0 0 0
就位而言,如果
pData[1] pData[0]
pData -> b7 b6 b5 b4 b3 b2 b1 b0 a7 a6 a5 a4 a3 a2 a1 a0
然后
pDes -> 0 0 0 0 0 a4 a3 a2 a1 a0 b5 b4 b3 b2 b1 b0
pDes[1] pDes[0]
这看起来像是将三个值打包成 6-5-5 位结构的操作。