0

I'm teaching my self C++ on the side and i realize this question may seem remedial to some. In the game I'm making as part of the learning process I want the user to be able to pick a difficulty and when they pick one or the other the random number value range changes. The compiler I'm using is x-Code by the way. Here is the code:

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

using namespace std;

int secretNumber;

int main() //integrate difficulty chooser where easy is a number b/w 1 and 10, norm 1 and 50, and hard is 1 and 100
{
    srand(static_cast<unsigned int>(time(0))); //seeds random number by time read on system

    int guess;
    int choice;

    char again = 'y';

    cout << "\tWelcome to Guess My Number\n\n";
    cout << "Please choose a difficulty:\n";
    cout << "1 - Easy\n";
    cout << "2 - Normal\n";
    cout << "3 - Hard\n";
    cin >> choice;

    while (again =='y')
    {
        int tries = 0;
        int secretNumber;
        do
        {                
            cout << "Enter a guess: ";
            cin >> guess;
            ++tries;

            switch (choice)
            {
                case 1:
                    cout << "You picked Easy.\n";
                    int secretNumber = rand() % 10 + 1;
                    break;            
                case 2:
                    cout << "You picked Normal.\n";
                    int secretNumber = rand() % 50 + 1;
                    break;
                case 3:
                    cout << "You picked Hard.\n";
                    int secretNumber = rand() % 100 + 1;
                    break;                    
                default:
                    cout << "You have made an illegal choice.\n";
            }

            if (guess > secretNumber)
            {
                cout << "\nToo high!";
            }
            else if (guess < secretNumber)
            {
                cout << "\nToo low!";
            }
            else if (guess == secretNumber && tries == 1)
            {
                cout << "\nThat's unbelievable! You guessed it in exactly 1 guess";
            }
            else
            {
                cout << "\nGreat job, you got it in just " << tries << " guesses!\n";
            }

        }
        while(guess != secretNumber);

        cout << "Do you want to play again y/n: ";
        cin >> again;
    }

    return 0;

}

The 2 errors occur in case 2 and 3 where i try to redefine the value of secretNumber.

4

3 回答 3

2

这些case块不会打开不同的范围,而是同一个块的一部分。您的代码(仅考虑范围)看起来类似于:

int secretNumber;
{
int secretNumber = rand() %  10 + 1;
...
int secretNumber = rand() %  50 + 1;
...
int secretNumber = rand() % 100 + 1; 
}

在同一范围内声明了三个具有相同名称的不同变量,这在语言中是不允许的。请注意,内部的所有三个声明switch也会隐藏在外部范围中声明的变量,这可能不是您想要的。

于 2013-08-20T18:53:23.453 回答
0

您收到编译时错误,因为您在同一范围内(case 语句块级范围)重新声明了相同的变量。您需要在所有 case 语句中删除 secretNumber 之前的 int 。否则,在 while 循环块级别声明的 secretNumber 变量将保持未定义。

于 2013-08-20T19:01:50.667 回答
0

看起来你有一些其他语言的背景——可能是一种函数式语言,也可能是一些 JavaScript。

C++ 的关键特性之一是作用域。变量(命名值持有者)在它们所在的范围内具有生命周期,并且变量仅在它们定义的范围内可见。(不要与对象混淆,通过指针和分配可以将对象从堆栈中取出并放入堆内存中,只有当变量及其地址超出范围时,如果它们没有正确释放,它们就会丢失)。

{
    int i = 1;
}
std::cout << "i is " << i << std::endl; // compiler error, i does not exist here.
void foo() {
    int i = 1;
}
void bar() {
    foo();
    std::cout << i << std::endl;  // compiler error, i does not exist here.
}

此外,除非装饰为“const”,否则 C++ 变量是可变的 - 它们可以更改。

int i = 1;
i = 2;
std::cout << i << std::endl; // writes 2, not 1. 

因此:您的代码不是“重新定义”secretNumber,而是隐藏先前的定义,在当前范围内隐藏它。因此,当您为内部版本分配值时,范围外代码可见的“secretNumber”不会受到影响。

#include <iostream>

int main()
{
    int foo = 1; // outer foo
    std::cout << "Originally, foo = " << foo << std::endl;

    {
        int foo = 2; // inner foo
        std::cout << "Inside the inner scope, foo = " << foo << std::endl;
    }

    // inner foo doesn't exist here, so it references outer foo.
    std::cout << "But the original foo still exists, " << foo << std::endl;
}

您实际上想要做的只是为您在外部范围中声明的原始 secretNumber 变量分配一个新值,因为这是唯一可用于该范围内代码的名为“secretNumber”的变量。

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

using namespace std;

int secretNumber;

int main() //integrate difficulty chooser where easy is a number b/w 1 and 10, norm 1 and 50, and hard is 1 and 100
{
    srand(static_cast<unsigned int>(time(0))); //seeds random number by time read on system

    int guess;
    int choice;

    char again = 'y';

    cout << "\tWelcome to Guess My Number\n\n";
    cout << "Please choose a difficulty:\n";
    cout << "1 - Easy\n";
    cout << "2 - Normal\n";
    cout << "3 - Hard\n";
    cin >> choice;

    while (again =='y')
    {
        int tries = 0;
        int secretNumber;
        do
        {                
            cout << "Enter a guess: ";
            cin >> guess;
            ++tries;

            switch (choice)
            {
                case 1:
                    cout << "You picked Easy.\n";
                    secretNumber = rand() % 10 + 1;
                    break;            
                case 2:
                    cout << "You picked Normal.\n";
                    secretNumber = rand() % 50 + 1;
                    break;
                case 3:
                    cout << "You picked Hard.\n";
                    secretNumber = rand() % 100 + 1;
                    break;                    
                default:
                    cout << "You have made an illegal choice.\n";
            }

            if (guess > secretNumber)
            {
                cout << "\nToo high!";
            }
            else if (guess < secretNumber)
            {
                cout << "\nToo low!";
            }
            else if (guess == secretNumber && tries == 1)
            {
                cout << "\nThat's unbelievable! You guessed it in exactly 1 guess";
            }
            else
            {
                cout << "\nGreat job, you got it in just " << tries << " guesses!\n";
            }

        }
        while(guess != secretNumber);

        cout << "Do you want to play again y/n: ";
        cin >> again;
    }

    return 0;

}

这就是为什么许多 C++ 程序员选择使用前缀和后缀符号来区分某些类型的变量的原因之一:

#include <iostream>

class Foo {
public:
    int m_i;  // member variable, m_xxx
    Foo(int); // constructor taking an int.
};

static int s_i;

Foo::Foo(int i_)   // arguments use _ suffix
{
    int i = i_;    // local value of i
    i *= 3;
    m_i = i;       // we're assigning it the local value, not the argument.
}

int main()
{
    int i = 1;
    Foo foo(2);
    s_i = 3;

    std::cout << "i = "<<i<<", foo.m_i = "<<foo.m_i<<", s_i = "<<s_i<< std::endl;
}

现场演示:http: //ideone.com/dSTwPT

于 2013-08-20T19:12:42.820 回答