2013-08-20 40 views
0

我在教我自己的C++的一方,我意識到這個問題可能似乎補救一些。在我作爲學習過程的一部分的遊戲中,我希望用戶能夠選擇一個難度,當他們選擇一個或另一個時,隨機數值範圍會發生變化。順便說一句,我使用的編譯器是x-Code。這裏是代碼:一個int錯誤的重定義

#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; 

} 

2情況發生在情況2和3,我嘗試重新定義secretNumber的值。

+2

我不太清楚是什麼問題是...? –

+0

您是否打算在每次猜測之後更改數字,對或錯?因爲這就是它現在正在做的事情。如果你希望每場比賽有一個數字,而不是每個猜測,'switch(choice)'語句應該在內部循環之外。 – cHao

回答

0

看起來你有一些其他語言的背景 - 也許是一種功能語言,也許是一些JavaScript。

C++的關鍵特性之一是範圍界定。變量(名爲值持有者)具有它們所在範圍的生命週期,並且變量僅在它們定義的範圍內可見。 (不要與對象混淆,通過指針和分配的對象可以從堆棧和堆內存中調出,只有在地址變量超出範圍時纔會丟失,如果它們沒有正確釋放)。另外,除非裝飾爲「const」,否則C++變量是可變的 - 它們可以改變。

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

所以:你的代碼是不是「重新定義」 secretNumber,它是shadowing以前的定義,它隱藏在當前範圍的持續時間。因此,當您爲內部版本分配一個值時,可以在範圍外編碼的「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

2

case塊不會打開不同的作用域,而是相同塊的一部分。您的代碼(僅考慮範圍)看起來在某種程度上類似於:具有相同的名稱

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

三種不同的變量在同一範圍內,這是不是在語言允許被宣佈。請注意,switch中的所有三個聲明都會隱藏在外部範圍中聲明的變量,這可能不是您想要的。

+0

我以爲你不能在switch語句中聲明變量,但我顯然沒有完全理解switch語句的侷限性?請解釋。看到這一個現在http://stackoverflow.com/questions/1231198/declaring-variables-inside-a-switch-statement,但它是客觀的C. – user2672165

+0

@ user2672165:這很複雜;你可以在交換機中直接設置變量,因爲交換機只是一個帶有特殊標籤並且內置了'if' /'goto'的塊。但就像gotos一樣,你不允許跳過變量的定義進入其範圍 - 這有效地使得變量在最後一種情況之外變得非法。 (當對每個定義變量的案例使用大括號時,這些古怪都會消失,這會爲變量創建一個新的範圍;跳過案例然後跳過整個範圍,所以你很好。) – cHao

+0

是的,你可以定義塊級變量,但在這種情況下,你不需要它。在switch語句級別,您只能聲明一次變量。 – Tarik

0

由於您在相同範圍(case語句塊級作用域)內重新聲明瞭相同的變量,因此您將收到編譯時錯誤。您需要在所有case語句中的secretNumber之前刪除int。否則,在while循環塊級聲明的secretNumber變量將保持未定義狀態。