13

I wrote some C++ code to show ASCII characters on a console which I found in a book i was reading. The code looked like this:

#include <iostream>

using namespace std;

int main()  
{  
    for (unsigned char i = 32; i<128; i++)  
       cout << i;  
    int response;  
    cin >> response;  
    return 0;  
}

When I take away the unsigned keyword and use signed instead, the results become infinite and the PC beeps until I shut off the executable file. But when I use an int i variable instead I don't need to unsign the variable. Why is that?

4

6 に答える 6

26

unsigned単純に、数値が負にならないことを意味します。ええ、数値です。なぜなら、acharは実際には 8 ビットの整数だからです。

そのunsignedため、すべてのビットが負でない範囲で使用され、0 から 255 になります。省略してsigned(デフォルトの) char を使用すると、範囲は -128 から 127 になるため、常に小さくなります。 128 よりも大きくなり、無限ループに陥ります。

聞こえるビープ音は、値 7 の文字が「印刷」されているためです。


int一方、 は、署名されている場合でも、-2.147... 億から +2.147 億になるため、128 に到達して停止するまで通常どおり反復します。

于 2013-07-05T00:17:24.957 に答える
5

符号なしとは、変数に正の値のみが含まれることを意味します。つまり、より大きな正の数値を含むことができることを意味します。通常、unsigned char の範囲は 0 ~ 255 で、signed char の範囲は -128 ~ +127 です。これは、ハードウェアによって異なる場合があります (ただし、遭遇する可能性が高いほとんどのハードウェアでは異なります)。

変数が最大値からインクリメントされると、オーバーフローします。変数に何が起こるかは、それが符号なしかどうかによって異なります。符号なしの型は 0 になることが保証されていますが、符号付きの型の動作は未定義です。私が見たほとんどのシステムでは、変数は最小値 (この場合は -128) にラップしますが、この動作に依存することはできません。

これが意味することは、変数が 128 に達することはないため、ループは永遠に続くということです。

このページに移動して基本的なデータ型を見ると、すべての基本的な型の符号付きと符号なしの典型的な範囲を見ることができます: http://www.cplusplus.com/doc/tutorial/variables/

于 2013-07-05T00:21:43.480 に答える
3

タイプsigned charunsigned charは別個の整数タイプです。名前が示すように、1 つは符号付きの型 (つまり、負の値を表すことができる) で、もう 1 つは符号なしの型 (つまり、負でない値のみを表すことができる) です。

またはプレフィックスcharのないtypeは、さらに別の異なるタイプです。または のいずれか同じ表現と範囲を持ちます。それがどれであるかは実装定義です。(微妙な点: そのうちの 2 つが同じ特性を持っていても、それらはまだ 3 つの異なるタイプです。)signedunsigned signed char unsigned char

典型的な実装では、これら 3 つの型はすべて 8 ビットであり、符号付き型は 2 の補数を使用して表されsigned char、-128 .. +127unsigned charの範囲と 0 .. +255 の範囲が与えられます。

あなたの実装では、プレーンcharが署名されているようです (これは非常に一般的です)。したがってi、タイプが の場合char常にtrue であり、無限ループが発生します。また、最大値を超えてまたはオブジェクトをインクリメントすると、実際には未定義の動作になりますが、通常は最大値から最小値にラップアラウンドします。これが表示されていることです。(ビープ音はおそらく、出力される文字が、ASCII文字である場合に発生します。それか、端末を台無しにする制御文字を送信している場合です。)i < 128charsigned char\007BEL

を作成iするunsigned charと、0 から 255 の範囲が与えられ、128 に達するとループが停止します (符号なし型の値をその最大値を超えてインクリメントすることは明確に定義されていますが、とにかくそれを行うことはありません)。

intは常に符号付きの型であり、その範囲は言語によって少なくとも -32767 .. +32767 である必要があります。最近では、一般的に 32 ビットで、範囲は -2147483648 .. +2147483647 です。しかし、必要最小限の範囲であっても、ループには十分な大きさです。

于 2013-07-05T01:17:54.337 に答える
3

signed char範囲は -128 ~ +127 なので、常に 128 未満になります。

あなたがするとき

signed i=127;
i++;

i通常は -128 になります (ただし、この動作ではカウントできません)

unsigned char範囲は 0 ~ 255 です

すべてのASCII文字が印刷できるわけではありません! それらを印刷するのはナンセンスです。

于 2013-07-05T00:17:05.407 に答える
1

signed char (少なくとも典型的なケースでは) は、-128 から +127 までの値のみを表すことができます。値が 128 になることはないため、ループは永遠に実行されます。

正式には、値が 127 のときにインクリメントすると、結果は未定義の動作になります。実際には、ほとんどすべての典型的なマシン (2 の補数を使用するもの) で、値が 127 でインクリメントすると、-128 に戻り、127 に戻り、-128 に戻り、サイクル全体を実行します。また。

unsigned char を使用すると、0 から (少なくとも) 255 までの値が取得されるため、127 に到達してインクリメントすると、値は 128 になり、期待どおりにループが終了します。

同様に、 にintは少なくとも -32767 ~ +32767 の範囲が必要です。したがって、値が 127 の場合、インクリメントすると、通常予想どおり、結果は 128 になります。

于 2013-07-05T00:16:50.303 に答える