1

如果 ,以下几行究竟是如何工作的pData = "abc"

pDes[1] = ( pData[0] & 0x1c ) >> 2;
pDes[0] = ( pData[0] << 6 ) | ( pData[1] & 0x3f );
4

4 回答 4

4

好的,假设绝对不能保证的 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
于 2010-07-14T06:54:41.543 回答
2

&不是逻辑与 - 它是按位与。

a是 0x61,因此pData[0] & 0x1c给出

0x61 0110 0001  
0x1c 0001 1100
--------------
     0000 0000

>> 2将其向右移动两个位置 - 值不会改变,因为所有位都为零。

pData[0] << 6左移0x616 位给出010000000x40

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 00000x1840- (如果pDes是一个字符数组,左边的部分不在图片中)。

0x1840 0001 1000 0100 0000
0x0022 0000 0000 0010 0010
--------------------------
0x1862 0001 1000 0110 0010

pDes[0]最终会是0x1862or decimal 6242

于 2010-07-14T06:57:33.237 回答
1

C++ 将根据字符的编码将字符视为数字。因此,假设 ASCII,“a”为 97(位模式为 0110_0001),“b”为 98(位模式 0110_0010)。

一旦将它们视为数字,对字符的位操作应该会更清晰一些。

于 2010-07-14T06:52:54.370 回答
0

在 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 位结构的操作。

于 2010-07-14T07:08:29.057 回答