【问题标题】:C++ Why does this variable return a random value?C++ 为什么这个变量返回一个随机值?
【发布时间】:2013-02-08 10:29:01
【问题描述】:

我已经用 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;
}

【问题讨论】:

  • 在开始使用变量之前先用一个值初始化变量。默认情况下,它们不会像您所期望的那样初始化为零。
  • 谢谢大家,让它工作。 :)

标签: c++ random int


【解决方案1】:

根据 C++11 标准的第 8.5/11 段:

如果没有为对象指定初始化器,则该对象为默认初始化;如果不执行初始化,则具有自动或动态存储期限的对象具有不确定值。 [ 注意:具有静态或线程存储持续时间的对象是零初始化的,请参见 3.6.2。 ——尾注]

第 8.5/6 段解释了 default-initialized 对不同变量类型的含义:

默认初始化一个 T 类型的对象意味着:

——如果 T 是一个(可能是 cv 限定的)类类型(第 9 条),则调用 T 的默认构造函数(并且 如果 T 没有可访问的默认构造函数,则初始化是非良构的);

——如果 T 是一个数组类型,每个元素都是默认初始化的;

否则,不执行初始化

由于在您的情况下T 既不是类类型也不是数组类型(所有默认初始化的变量都具有int 类型),因此不会执行初始化并且初始值是不确定的。

此外,您的程序具有未定义行为,因为它试图读取未初始化变量的值。这样做需要左值到右值的转换(尽管标准没有明确指定这一点,但可能是有意的,请参阅 this Q&A on SO)和 C+ 的第 4/1 段+11 标准授权:

非函数、非数组类型 T 的泛左值 (3.10) 可以转换为纯右值。53 如果 T 是不完整类型,则需要这种转换的程序是非良构的。如果泛左值引用的对象不是 T 类型的对象,也不是从 T 派生的类型的对象,或者 如果该对象未初始化,则需要此转换的程序具有未定义的行为 .如果 T 是非类类型,则纯右值的类型是 T 的 cv 非限定版本。否则,纯右值的类型是 T.54

【讨论】:

    【解决方案2】:

    在为它们分配任何值之前,您还没有初始化一些您随后使用的变量。它们以未指定的值开始,看起来是随机的。你可以这样修复它

    int guess = 0;
    int guesses = 0;
    

    【讨论】:

      【解决方案3】:

      代码没有初始化guessguesses,所以它们的初始值是不可预测的。

      【讨论】:

      • 具有讽刺意味的是,这可能会让您在零次尝试中猜到正确答案 ;)
      【解决方案4】:

      您不会将猜测初始化为 0。因此它将包含它开始使用的内存地址中的任何内容

      【讨论】:

        【解决方案5】:

        您不初始化猜测,因此您不知道该值是什么。 C/C++ 不对未初始化变量的值做任何保证。

        最好总是初始化所有值

        int guesses = 0;

        【讨论】:

        • 他应该以某种方式初始化guess,否则他的while循环可能在他读取单个值之前就失败了。也许在循环之前有一个cin &gt;&gt; guess;
        • 是的,他也应该这样做{}。只是想指出那个变量的具体问题。
        【解决方案6】:

        您没有将 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 中是这样。

        故事的寓意:启用编译器警告。

        【讨论】:

        • 他也没有初始化guess,所以guess != randomNumber可能永远不会是真的。
        • @NikBougalis:是的,确实如此。奇怪的是 g++ 也没有标记它。
        猜你喜欢
        • 2021-12-09
        • 1970-01-01
        • 1970-01-01
        • 2022-12-03
        • 2017-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-12
        相关资源
        最近更新 更多