2

char の最初の 4 ビットを末尾に移動し、最後の 4 ビットを先頭に移動するプログラムを C で作成しています。ほとんどの値では、逆の操作と同様に正常に機能しますが、8、x、y、z などの一部の値では、結果として 32 ビット値が得られます。変数の 16 進値を出力してチェックされる値。なぜこれが起こっているのか誰か説明できますか?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char o, f,a=15;
    scanf("%c",&o);
    printf("o= %d\n",o);
    f=o&a;
    o=o>>4;
    printf("o= %d",o);
    o=o|(f<<4);
    printf("o= %x, size=%d\n",o,sizeof(o));
    f=o&a;
    o=o>>4;
    printf("o= %d",o);
    o=o|(f<<4);
    printf("o= %x, size=%d\n",o,sizeof(o));
    return 0;
}
4

4 に答える 4

6

oに引数として渡すとprintf()、自動的に に変換さintれます。これは、システム上では明らかに 32 ビットです。自動変換では符号拡張が使用されるため、ビット 7oが設定されている場合、変換結果のビット 8 ~ 31 が設定されます。これにより、表示内容が説明されます。

これを回避するunsigned char代わりに使用できます。charまたは に渡しo & 0xffますprintf()

于 2012-06-12T17:43:48.883 に答える
3

変数を として宣言してみてくださいunsigned char。上位ビットの符号拡張を取得しています。

于 2012-06-12T17:38:33.017 に答える
2

printf (または任意の可変引数関数、またはプロトタイプのない任意の関数) の引数として指定された char は、int に昇格されます。プラットフォームで char が署名されていて、渡された値が負の場合、符号は拡張されます。

于 2012-06-12T17:43:43.050 に答える
2

フォーマット指定子%xprintf値をunsigned int. として出力するには、長さ修飾子を含むunsigned char書式指定子が必要です。値が正の場合、印刷出力に違いはありませんが、負の数の場合は、最上位ビットが設定されているため違いがあります。%hhxhh

CHAR_BIT == 8以下では、そのコードで負の値がどのように発生するかを説明します。負の整数の 2 の補数表現を想定しています。

シフトの場合、 の値oは に昇格されintます。元の値の 4 番目の最下位ビットが設定されている場合 (if (o & 8) != 0)、ニブルの最初のスワップの後、最上位ビットoが設定されます。charプラットフォームでデフォルトで署名されている場合、結果が否定的であることを意味します。2 番目のニブル スワップでは、 の値oが再び に昇格さintれ、負の値になります。負の値の右シフトは実装定義なので、

o=o>>4;

その場合、移植性はありません (ただし、実際には、すべての実装で算術右シフト [符号拡張あり] または論理右シフト [左からゼロをシフト] のいずれかが使用されます)。

負の整数に対して算術シフトを行う実装では、 の最上位 4 ビットoがすべて設定されるため、

o=o|(f<<4);

もう値を変更しません。

コードを移植可能に修正して目的の動作を得る唯一の方法は、Ned の提案に従って としてo宣言することです。unsigned charこれで、すべての値が正になり、シフトの動作が明確に定義され、期待どおりになります。

于 2012-06-12T17:59:14.287 に答える