2009-08-04 30 views
2

Cでは、自動変数が初期化されていない場合、ガベージ値を保持します。ただし、次のプログラムを検討してください。初期化されていない値は初期化されていますか?

int main(){ 
signed char term; 
(char)term--; 
printf("%d\n",term); 
} 

「7」の値が出力されます。 (char)term--を実行しないと、 '8'の値が出力されます。だから、それは間違いなくゴミ値を保持していません。これは矛盾していませんか?

答えて

15

これはごみです。あなたはゴミとして8を取得し、7を得るために減算します。

これは未定義の振る舞いです。あなたが8を得続けているという理由だけでは、それが明確に定義されているわけではありません。あなたのコードでもっと複雑なことをやってみてください。 charの上と下に変数を追加します。あなたの「テスト」について


、あなたが言う:

はしかし、一貫性はゴミがランダムであることを考慮すると、見過ごすことは難しいです。

あなたの前提を確認する必要があります。 "ゴミはランダムでなければならない"と誰が言う?ゴミは何をランダムにすべきかに応じて?ガーベジがランダムになる唯一の方法は、システムが定期的にメモリを通過して乱数を割り当てる場合です。

私たちが「ランダム」と言うとき、私たちはそれがどうなるかわからないということです。それはそれを非決定論的にしません。これらはコンピュータです。同じことを何度も繰り返してもらうように言ったら、と同じことをやります。

コンパイラと設定は、これらのゴミ値を与える最後のコードを生成し続けます。決定的ですが、この動作に依存することはできません: "ランダム"。

また、1-800は、あなたのようにこれを取ることを意味しませんでした。あなたのコンパイラが8でそれらを満たすように、 "8"は必ずしもゴミを示すわけではありません。彼が意味するのは、8は他の数字と同じようにごみです。

2

値の点でのごみは、以前の機能によってスタックに残ったものです。 libc、または任意の数のものを変更すると、その番号が変更されます。

4

値8は、「ガベージ」または「初期化されていない」とみなされる数値の集合に含まれます。

0

ガーベッジを保持しています。ガーベッジは8ビットを保持し、バイナリは0-255の数字として読み取ります(符号なしの文字を使用していることが前提です)。

このようにメモリはこのようになりました:

| 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 0 1 |

最後に(1 0 0 1 0 1 0 1)とそれを149という数字で読んでいます。これは、指定された長さの場所にどのようなランダムバイナリがあるかによって異なります(例:unsigned char = 1バイト)

unsigned intの場合は、4バイトのランダムなガーベッジがあり、それを数値にします。

0

任意の値(ビットパターン)で初期化されていると考えてください。

この任意の値は、変数のスタック位置が最後に使用された値によって決まります。間違いなくランダム値ではありません。必ずしも同じ値である必要はありません。それは前に起こった何かに依存することができます。

未定義の動作を避けるために、常に自動変数を初期化することをお勧めします。

2

"ガベージ"と "非決定論的"という言葉が混ざっているようです。言い換えれば、あなたは値が何であるかを制御できないため、ガベージとみなされます。プラットフォームからプラットフォームへ、または実行するために実行することができます。つまり、未定義の動作です。

一方、プログラムのランタイム環境内のものが等しい場合、値はたぶん実行ごとに同じになります。しかし、これはゴミであることを排除するものではありません。

+0

同意する。デバッガでコードを一歩試すことを理解したい場合は、main()より前に起動する起動コードを得るため、シングルステップ(おそらくアセンブリモード)で実行してください。 – Adriaan

0

回答ありがとうございます。

int main(){ 
      signed char term1; 
      signed char term2; 
      signed char term3; 
      printf("%d\n%d\n%d\n",term1,term2,term3); 
} 

私は3つの異なるマシンでプログラムを実行しました。結果はterm1が値= -124、term2 = 4、term3 = 8という3つのマシンで同じ結果になりました。term3を削除すると、term1 = 4、term2 = 8となりました。 signed charとしてデカールされる最後の値は '8'の値を取得します。 1800 INFORMATIONによると、 '8'はごみを示すために使用される値の1つですが、これはその可能性があります。しかし、ガベージはランダムでなければならないことを考慮して、一貫性を見落とすのは難しいです。

+0

コンピュータ上の何も本当にランダムではありません。 3つの異なるランタイムと異なるコンパイラーを使用して、3つの異なるアーキテクチャーでプログラムを試してみることをお勧めします。たとえば、x86 Windowsマシン、x86 Linuxマシン、PowerPC Macintoshなどです。私の推測では、あなたは別の結果を得るでしょう。異なるコンパイラ(Visual Studio 2008とVisual C++ 6.0など)で異なる結果が得られることもあります。根本的な点は、Cランタイム環境に関して一貫性がないことです。 –

関連する問題