の場合、次の行はどのように正確に機能します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
が、同じですが右にシフトします。
( &
)and
演算は、両方の入力の対応するビットが 1 である場合にのみ、結果の各ビットを 1 に設定します。
( |
)or
演算は、両方の入力の対応するビットの 1 つ以上が 1 の場合、結果の各ビットを 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
&
は論理 AND ではなく、ビット単位の AND です。
a
0x61 であるためpData[0] & 0x1c
、
0x61 0110 0001
0x1c 0001 1100
--------------
0000 0000
>> 2
これを右に 2 桁シフトします。すべてのビットが 0 であるため、値は変化しません。
pData[0] << 6
または0x61
を与えるために6ビット左シフト01000000
0x40
pData[1] & 0x3f
0x62 0110 0010
0x3f 0011 1111
--------------
0x22 0010 0010
したがって、結果は0x40 | 0x22
-|
これも論理 OR ではなく、ビット単位です。
0x40 0100 0000
0x22 0010 0010
--------------
0x62 0110 0010
pDes
が char 配列でない場合、結果は異なります。左にシフトすると、または-0x61
が得られます(が char 配列の場合、左の部分は画像にありません)。0001 1000 0100 0000
0x1840
pDes
0x1840 0001 1000 0100 0000
0x0022 0000 0000 0010 0010
--------------------------
0x1862 0001 1000 0110 0010
pDes[0]
0x1862
または 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
は、 からビット #2 ~ #4 を抽出することpData[0]
です。その後>> 2
、最後に余分なゼロを削除します。
同様に、& 0x3f
は からビット #0 ~ #5 を抽出することpData[1]
です。
<< 6
は、ビットの最下位に 6 個のゼロをプッシュします。pDes[0]
も であると仮定すると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]
これは、3 つの値を 6-5-5 ビット構造にパックする操作のように見えます。