3

私はc++で基本的な「ナンバーゲームを推測する」を作成し、人が数字を推測するのにかかった推測の数の変数を追加しました。ただし、ゲームが終了すると、推測のランダムな値が表示されます。1980046322のようなものです。コードに特別なものを何も入れていないことを考えると、なぜこれが行われるのか理解できません。

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
int randomNumber;
int guess;
int guesses;

srand((unsigned)time(0));
randomNumber = (rand()%10)+1;

cout << "I am thinking of a number between 1 to 10. Can you guess it?" << endl;

while(guess != randomNumber){
    cout << "That is not correct, try again.";
    guesses++;
    cin >> guess;
}

if(guess == randomNumber){
    cout << "Good Job. Guesses: " << guesses << endl;
    guesses++;
}

return 0;
}
4

6 に答える 6

9

C++11規格の8.5/11項によると:

オブジェクトに初期化子が指定されていない場合、オブジェクトはデフォルトで初期化されます。初期化が実行されない場合、自動または動的な保管期間を持つオブジェクトの値は不確定です。[注:静的またはスレッドの保存期間を持つオブジェクトはゼロで初期化されます。3.6.2を参照してください。—エンドノート]

8.5 / 6項では、さまざまな変数タイプのデフォルトで初期化された意味を説明しています。

T型のオブジェクトをデフォルトで初期化するということは、次のことを意味します。

— Tが(おそらくcv修飾された)クラスタイプの場合(第9節)、Tのデフォルトコンストラクターが呼び出されます(Tにアクセス可能なデフォルトコンストラクターがない場合、初期化は不正な形式になります)。

— Tが配列型の場合、各要素はデフォルトで初期化されます。

それ以外の場合、初期化は実行されません

このT場合、はクラス型でも配列型でもないため(デフォルトで初期化されたすべての変数には型がintあります)、初期化は実行されず、初期値は不確定です。

さらに、初期化されていない変数の値を読み取ろうとするため、プログラムには未定義動作があります。そうすることは、左辺値から右辺値への変換を必要とし(標準はこれを明示的に指定していませんが、そうすることを意図している可能性があります。SOに関するこのQ&Aを参照してください)、C++11標準のパラグラフ4/1は以下を義務付けています。

非関数、非配列型Tのglvalue(3.10)は、prvalueに変換できます53。Tが不完全な型である場合、この変換を必要とするプログラムは不正な形式です。glvalueが参照するオブジェクトがタイプTのオブジェクトではなく、Tから派生したタイプのオブジェクトでもない場合、またはオブジェクトが初期化されていない場合、この変換を必要とするプログラムの動作は未定義です。Tが非クラスタイプの場合、prvalueのタイプはTのcv非修飾バージョンです。それ以外の場合、prvalueのタイプはT.54です。

于 2013-02-22T18:03:42.583 に答える
4

値を割り当てる前に使用するいくつかの変数を初期化していません。それらは、ランダムに見える不特定の値で始まります。このように修正できます

int guess = 0;
int guesses = 0;
于 2013-02-22T18:02:05.450 に答える
3

コードは初期化されないguessguesses、であるため、それらの初期値は予測できません。

于 2013-02-22T18:02:00.973 に答える
2

推測を0に初期化しないでください。したがって、メモリアドレスに含まれていたものがすべて含まれます。

于 2013-02-22T18:03:17.140 に答える
2

推測を初期化しないため、値がどうなるかわかりません。C / C ++は、初期化されていない変数の値が何であるかについては保証しません。

常にすべての値を初期化することをお勧めします

int guesses = 0;

于 2013-02-22T18:03:34.967 に答える
1

guesses変数をゼロに初期化しませんでした。

たとえば、次のフラグを使用してコードをg ++でコンパイルすると、問題が明らかになります。

$ g++ -O2 -Wall foo.cpp 
foo.cpp: In function ‘int main()’:
foo.cpp:25:38: warning: ‘guesses’ may be used uninitialized in this function [-Wmaybe-uninitialized]

少なくともg++4.7.2では、警告をトリガーするために警告フラグに加えて最適化フラグが必要であることに注意してください。

話の教訓:コンパイラの警告を有効にします。

于 2013-02-22T18:03:46.267 に答える