2017-03-16 9 views
0
#include<stdio.h> 
int main() 
{ 

    char c =118,a=117; 
    c=c+10; 
    a=a+10; 
    printf("c:%d, a:%d\n", c,a); 

} 

答えはc:-128、a:127です。cのchar値の加算

誰かがなぜc + 10が-128で、+ 10が127であるのか説明できますか?

ありがとうございます。

+0

@deepak [デフォルトでは、charは署名されているのか署名されていませんか]を参照してください(http://stackoverflow.com/questions/2054939/is-char-signed-or-unsigned-by-default) 。コンパイラ固有の結果が得られます。 – Lundin

+0

@ Lundin:私の悪い。 'char'が' int'と同じくらい多くのビットを持たない限り、それは実際に定義された実装です。 – Olaf

+0

システムでは、 'char'が実際に' signed char'であることは明らかです – user3629249

答えて

1

charはコンパイラで8ビットであるためです。したがって118+10が範囲外です(最大は127)。

あなたのコンパイラの実装はそれを "包む"代わりに-128を得ます。あなたのケースで

+0

これは未定義の動作です。結果は正しいでしょう。 – Olaf

+1

ok、未定義ですが、実装が定義されています:コンパイラは何かを行います。切り詰めまたは折り返しのいずれか。だからこそ、私は自分の答えで非常に慎重だったのですが、それは実装が定義していることを思い出させます(したがって、移植性がなく、未定義の動作に非常に近い) –

1

が8ビット値に署名し、そして2's complement reoresentationにあるように、charは、特定のプラットフォーム上のコンパイラによって表されています。つまり、最も高いビットは符号ビットです(1の場合は数値が負です)。したがって、負でない値のバイナリの範囲は(バイナリで)00000000-01111111です。これは10進数で0-127です。負の値の範囲は10000000から11111111(バイナリ)で、小数点で-128〜-1です。

あなたはだバイナリで、118で始まる場合:

01110110 

私は小数点10を追加した場合、それはバイナリで1010を追加しています:

01110110 
+00001010 
--------- 
10000000 

あなたは最上位ビットがセットされている今見ることができ、オーバーフローした数が10進数で最大127より大きくなったことを意味し、現在は負の数を表します。 8ビットのバイナリ値10000000は、小数点で-128を表すようになります。

したがって、値118にcharに(10進で)10を加算すると、-128が得られます。

aの値が117なので、10 + 117 = 127は、正の値127の場合でも7ビットに収まります。上記のバイナリ分析を実行して、その動作を確認することができます。

+0

これはUBには関係ありません。問題は、それはUBではありませんが、実装が定義した、私は間違っていました - もし 'char'が' int'と同じくらい多くのビットを持っていなければ - ありそうもありません。コンパイラのドキュメントで指定する必要があります。 – Olaf

+0

@Olafはい私は同意します。プラットフォームとコンパイラの依存関係についてもう少し明確になるように答えを更新しました。 – lurker

2

符号付き8ビットの値の範囲は-128〜127です。127のビットは0111 1111で、128のビットは1000 0000です。問題は、符号付きの数値では、上位ビット(左端)符号フラグです(0は+、1は - )。したがって、署名されているため、コンピュータはこれを負の数値として解釈します。結果は-128です(これは符号付きオーバーフローと呼ばれ、正しく記憶されていれば誰でも同じポイントでプログラムを実行します)(2の補数をチェックしますなぜ低7ビットが128ではなく0でないかを知る)。この問題を回避するには、charではなく、unsigned charとcとaを指定します。

ところで、このよう変数を救うことができる:

開く場合char型(-128-127)

の範囲内にある= 127

char a=117; printf("c:%d, a:%d\n", a+11,a+10);

+1

@Olaf、あなたは、正確には未定義の動作であることに気づくことができますか?私の説明は、実際に何が起こるべきかを定義しようとしていない、OPで実際に起こっていることに答える。 – andrew

2

117 + 10あなたのウィンドウをプログラマーモードで計算すると、118がバイナリーで1110110と表されていることが分かります。また、10は1010として表されます。この2つを加算すると、結果は10000000になります。これはchar型の範囲にはなく、この数値は-128に相当します。-128が印刷されます。