-3

我的印象是下面的代码会打印出“hello world”,但它根本不打印任何东西。为什么?使用 g++ 4.2.1 和 cl++ 3.2 编译。

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

4 回答 4

5

您的条件应该是i >= 0,而不是i == 0for只要条件是false,循环就会退出,在您的示例中就是这种情况)。

此外,一旦你解决了这个问题,你也应该修复分配i,因为下标运算符接受从零开始的索引;这意味着当i == hiThere.length()您访问字符串的终止符时,您可能对输出没有兴趣。

这应该会更好:

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

这是一个活生生的例子

于 2013-04-27T18:36:14.593 回答
2
  1. 循环中的条件必须是i >= 0。否则程序将永远不会进入循环体——只要它i == 0是真的并且你设置i了字符串的长度,它就会循环。
  2. i应该用 初始化hiThere.length() - 1。否则,您将有未定义的行为——C++ 中的字符串和数组是 0 索引的,即第一个索引是0,最后一个索引是size - 1hiThere[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;
        }
    }
    
于 2013-04-27T18:46:35.700 回答
1

@AndyProwl 已经给出了一个解决方案,我将在此处复制它以便与我的比较:

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

为了完整起见,您也可以这样写(值得了解这种形式,因为您可能会遇到它——请注意,它与 Andy 的解决方案完全相同):

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

几点评论:

  • 我们现在可以使用无符号 (size_t) 索引,因为我们不再需要负值。这很有趣,因为如果您的字符串长于 INT_MAX,Andy 的解决方案会发生什么情况?(这不太可能发生,我同意你,但仍然......)这种形式解决了这个小(实际上是迂腐的)困境。
  • 终止条件和事后想法合并在一起,所以事后想法是空的。
  • 与我们习惯的大多数for循环不同,这里使用后减运算符而不是通常的前减运算符非常重要,整个事情都依赖于它。

但老实说,我更喜欢 @woytaz 的迭代器解决方案,只是因为它与 STL 的其余部分更一致。

于 2013-04-27T19:08:14.970 回答
0

此外,您在 for 循环中的条件应该是

i >= 0

代替

i == 0

这是因为 for 循环将迭代,只要它是真的,如果你使用 i==0 它将是 FALSE。

于 2013-04-27T18:38:49.913 回答