0

値が 0xB3 の文字があり、これを 2 つの別個の文字に分割する必要があります。したがって、X = 0xB で Y = 0x3 です。私は次のコードを試しました:

int main ()
{
    char addr = 0xB3;
    char *p = &addr;

    printf ("%c, %c\n", p[0], p[1]);          //This prints ?, Y
    printf ("%X, %X\n", p[0], p[1]);          //This prints FFFFFFB3, 59

    return 0;
}

明確にするために、値が 00 から FF の 2 バイト文字を取り、最初と 2 番目のバイトを別々の文字に分割する必要があります。ありがとう。

4

4 に答える 4

5

ウィキペディアから直接:

#define HI_NIBBLE(b) (((b) >> 4) & 0x0F)
#define LO_NIBBLE(b) ((b) & 0x0F)

そうHI_NIBBLE(addr)でしょう0xB。ただし、0x00スルー0xFFは「ダブルバイト」ではありません。それらはシングルバイト値です。1 つの 16 進数は 16 バイトを占めることができますが、1 バイトは 256 = 16² を占めることができるため、任意のバイト値を表すには 2 つの 16 進数が必要です。

于 2012-11-09T16:34:37.707 に答える
1

ここにはかなりの問題があります。コードを見てみましょう。

int main ()
{
    char addr = 0xB3;  <-- you're asigning 0xB3 in hex, which is (179 in dec) to addr
    char *p = &addr;   <-- you're assigning a pointer to point to addr

addr署名されていない場合は、拡張 ASCIIである 179 に設定されます。│ ( Box drawing character )

値は、符号付きのchar場合は -127 ~ +127、符号なしの場合は 0 ~ 255 です。charここで(出力によると)署名されているため、その割り当てでオーバーフローしています。

printf ("%c, %c\n", p[0], p[1]); <-- print the char value of what p is pointing to
                                     also, do some UB
printf ("%X, %X\n", p[0], p[1]); <-- print the hex value of  what p is pointing to
                                     also, do some UB

addrしたがって、ここのコードの 2 番目の部分は、オーバーフローした varの char 値を出力'?'します。の 16 進値は、負の値でaddrあるFFFFFFB3ことを示しています (最上位ビットは符号付きビットです)。

This:p[0]は実際には「追加と参照」演算子です。つまり、 のアドレスを取得し、それpに追加0してから、参照して結果を確認します。

p ---------+
           V
       ------------------------------------------
      | ptr(0xB3) |    ?      |     ?     | ... |
      -------------------------------------------
       0xbfd56c2b  0xbfd56c2C  0xbfd56c2d   ...      

p[1]これを行うcharと、ptr を 1 バイトまたは 1 バイト過ぎて、その結果が得られます。何がありますか?わからない。それはあなたの範囲外です:

p+1 -------------------+
                       V
       ------------------------------------------
      | ptr(0xB3) |    ?      |     ?     | ... |
      -------------------------------------------
       0xbfd56c2b  0xbfd56c2C  0xbfd56c2d   ...   

Yの ASCII 値 (16 進数) は 0x59 であるため、メモリ内のポインタの後ろにはY. しかし、それは何でも可能でした。何をしようとしているのかは未定義でした。これを行う正しい方法は次のとおりです。

int main ()
{
    unsigned char addr = 0xB3;
    char low = addr & 0x0F;
    char high = (addr >> 4) & 0x0F;

    printf("%#x becomes %#x and %#x\n", addr, high, low);

    return 0;
}

これは次の方法で機能します。

    0xB3  =>  1011 0011        0xB3 >> 4 =   0000 1011
            & 0000 1111                    & 0000 1111
            ------------                  -------------
              0000 0011 => 3 low             0000 1011 => B high
于 2012-11-09T17:26:42.280 に答える
0

なぜポインターで渡す必要があるのですか? 関連する 4 ビットを取得し、必要に応じて最も重要なビットをシフトします。

char lower = value & 0x0F;
char higher = (value >> 4) & 0x0F;

次に0xB3、2 バイトではなく 1 バイトです。16 進数は 16 個の値を持つことができるため、2 桁で 16*16 = 256 個の値を格納できます。これは、1 バイトに格納できる量です。

于 2012-11-09T16:35:11.107 に答える