我的印象是,下面的代码会打印出“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];
}
}
我的印象是,下面的代码会打印出“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];
}
}
你的条件应该是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。
程序没有未定义的行为。他根本不会访问任何元素,更不用说超出范围的元素。 – 2013-04-27 18:39:42
@BenjaminLindley:对,我编辑了答案。谢谢 – 2013-04-27 18:41:34
好的。但是,尽管行为可能不是OP后的行为,但在第一次修复之后不会出现未定义的行为。 'basic_string'对'operator []'有一个特殊的规定,以便与常见的c-string使用兼容。访问'hiThere [hiThere.size()]'是合法的,并且返回一个char值的引用,其值可以是字符串的末尾,也可以不是。见标准:'21.4.5/1&2'。如果您尝试修改该值,那是未定义的行为,但这不是在这里完成的。 – 2013-04-27 18:51:31
此外,您在for循环条件应该是
i >= 0
,而不是
i == 0
这是因为for循环会,只要是真正的迭代,这将是为FALSE你使用i == 0。
i >= 0
。否则,程序将永远不会进入循环体 - 只要i == 0
为真,并且您将i
设置为字符串的长度,它将循环。i
应该用hiThere.length() - 1
进行初始化。否则,你将会有未定义的行为 - C++中的字符串和数组是0索引的,即第一个索引是0
,最后一个是size - 1
(所以hiThere[hiThere.length() - 1]
是hiThere
的最后一个元素)。你应该看看C++迭代器:
void iterateBackwards(){
std::string hiThere = "dlrow olleh";
for (auto it = hiThere.crbegin(); it != hiThere.crend() ; ++it) {
std::cout << *it;
}
}
@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];
}
几点意见:
for
循环不同,这里使用后递减运算符而非通常的预递减运算符非常重要,整个事情依赖它。但老实说,我更喜欢@ woytaz的迭代器解决方案,只是因为它与STL的其余部分更加一致。
一个for循环在退出条件('i == 0')为假时立即退出。 – Mat 2013-04-27 18:37:10
如果您想向后打印字符串,请使用:'std :: copy(hiThere.rbegin(),hiThere.rend(),std :: ostream_iterator(std :: cout,“”));' –
2013-04-27 18:38:10