2013-04-27 57 views
-4

我的印象是,下面的代碼會打印出「hello world」,但它根本不打印任何東西。爲什麼? 使用g ++ 4.2.1和cl ++ 3.2編譯。向後迭代C++

void iterateBackwards(){ 
    std::string hiThere = "dlrow olleh"; 
    for (int i = hiThere.length(); i == 0; i--) { 
     std::cout << hiThere[i]; 
    } 
} 
+1

一個for循環在退出條件('i == 0')爲假時立即退出。 – Mat 2013-04-27 18:37:10

+2

如果您想向後打印字符串,請使用:'std :: copy(hiThere.rbegin(),hiThere.rend(),std :: ostream_iterator (std :: cout,「」));' – 2013-04-27 18:38:10

回答

5

你的條件應該是i >= 0,不i == 0(一for循環的條件是false,這立即在你的榜樣的情況下儘快退出)。因爲下標運算符接受從零開始的索引,所以一旦你解決了這個問題,你也應該修改這個賦值爲i。這意味着當您要訪問字符串的終止符字符時,您可能對輸出不感興趣。

這應該更好地工作:

void iterateBackwards(){ 
    std::string hiThere = "dlrow olleh"; 
    for (int i = hiThere.length() - 1; i >= 0; i--) { 
     std::cout << hiThere[i]; 
    } 
} 

這裏是一個live example

+0

程序沒有未定義的行爲。他根本不會訪問任何元素,更不用說超出範圍的元素。 – 2013-04-27 18:39:42

+0

@BenjaminLindley:對,我編輯了答案。謝謝 – 2013-04-27 18:41:34

+0

好的。但是,儘管行爲可能不是OP後的行爲,但在第一次修復之後不會出現未定義的行爲。 'basic_string'對'operator []'有一個特殊的規定,以便與常見的c-string使用兼容。訪問'hiThere [hiThere.size()]'是合法的,並且返回一個char值的引用,其值可以是字符串的末尾,也可以不是。見標準:'21.4.5/1&2'。如果您嘗試修改該值,那是未定義的行爲,但這不是在這裏完成的。 – 2013-04-27 18:51:31

0

此外,您在for循環條件應該是

i >= 0 

,而不是

i == 0 

這是因爲for循環會,只要是真正的迭代,這將是爲FALSE你使用i == 0。

2
  1. 循環中的條件必須是i >= 0。否則,程序將永遠不會進入循環體 - 只要i == 0爲真,並且您將i設置爲字符串的長度,它將循環。
  2. i應該用hiThere.length() - 1進行初始化。否則,你將會有未定義的行爲 - C++中的字符串和數組是0索引的,即第一個索引是0,最後一個是size - 1(所以hiThere[hiThere.length() - 1]hiThere的最後一個元素)。
  3. 你應該看看C++迭代器:

    void iterateBackwards(){ 
        std::string hiThere = "dlrow olleh"; 
        for (auto it = hiThere.crbegin(); it != hiThere.crend() ; ++it) { 
         std::cout << *it; 
        } 
    } 
    
1

@AndyProwl已經給了,我會在這裏複製與煤礦相比,更容易的解決方案:

std::string hiThere = "dlrow olleh"; 
for (int i = hiThere.length() - 1; i >= 0; i--) { 
    std::cout << hiThere[i]; 
} 

爲求的完整性,你也可以這樣寫(這是值得知道的形式,因爲你可能會遇到它 - 請注意,它是正好相當於安迪的溶膠ution):

std::string hiThere = "dlrow olleh"; 
for (size_t i = hiThere.length(); i--;) { 
    std::cout << hiThere[i]; 
} 

幾點意見:

  • 現在我們可以用一個無符號(爲size_t)指數,因爲我們不需要負值了。這很有趣,因爲如果你的字符串比INT_MAX更長,安迪的解決方案會發生什麼? (這是不太可能發生的,我會授予你的,但仍然......)這種形式解決了這個小的(實際上是迂腐的)困境。
  • 終止條件和事後的想法合併在一起,所以事後留空。
  • 與我們習慣的大多數for循環不同,這裏使用後遞減運算符而非通常的預遞減運算符非常重要,整個事情依賴它。

但老實說,我更喜歡@ woytaz的迭代器解決方案,只是因爲它與STL的其餘部分更加一致。