ここにはかなりの問題があります。コードを見てみましょう。
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