(char)0xffを8だけ左シフトし、それをintにキャストすると、-256または0xffffff00になります。なぜこれが起こるべきなのか誰かが説明できますか?
#include <stdio.h>
int main (void)
{
char c = 0xff;
printf("%d %x\n", (int)(c<<8),(int)(c<<8));
return 0;
}
出力は
-256 ffffff00
char
符号付きまたは符号なしにすることができます-それは実装定義です。char
コンパイラでデフォルトで署名されているため、これらの結果が表示されます。
符号付き文字の場合、0xFFは-1に対応します(これが2の補数のしくみです)。あなたがそれをシフトしようとすると、それは最初にに昇格され、int
次にシフトされます-あなたは事実上256倍の乗算を取得します。
したがって、このコードは次のとおりです。
char c = 0xFF; // -1
int shifted = c << 8; //-256 (-1 * 256)
printf( "%d, %x", shifted, shifted );
私が最初に問題を調べたとき、私の最初の見解は、char'c'を左に8ビットシフトする必要があるというものでした。8ビットすべてが破棄され、空のcharは値0のintにキャストされます。
少し調べてみると、通常の単項変換が明らかになります。これは、多数の算術型を減らすために、単項'!'、'-'、'〜'、および'*'演算子のオペランドとそれぞれに変換が自動的に適用される場所です。バイナリの'<<'および'>>'演算子のオペランドの。
したがって、char'c'は最初にintに変換され、次に左にシフトされて、表示される答えが得られます。
あなたは毎日何か新しいことを学びます!
cは、シフト操作が実行される前にintにプロモートされています。実装でcharsがデフォルトで署名されると仮定すると、これは0xffffffffを取得することを意味し、これを左にシフトして結果を出します。
cをunsignedcharにすると、期待どおりの結果が得られるはずです。
charは署名されたcharに他なりません。したがって、char c=0xFFは-1になります。-1 x 8ビット左シフトすると、-256になります。