使用c++,我想创建一个for循环如下(text
是std::string
):
for(int i = text.size(); i >= 0; i--) {
{
请有人帮助我理解为什么我的编译器(Xcode)要求我将i
初始化为无符号长,而不是整数?
我假设如下,但我不知道,我想更好地理解:我相信它与一个最大值为2147483647的整数有关,而unsigned long的最大值为18,446,744,073,709,551,615。由于字符串最多可以容纳4294967295个字符,因此使用整数是不合适的,因为它的最大值不能表示字符串的最大长度。
最后,unsigned long数据类型是否合适,还是应该使用long int类型?
修改后的for循环如下:
for(unsigned long i = text.size(); i >= 0; i--) {
}
或
for(long int i = text.size(); i >= 0; i--) {
}
std::string::size()
返回无符号整数类型(std::size_t
)。更改i
的类型很容易,但会引入另一个问题。当i
类型为std::size_t
时,循环条件被打破;根据定义unsigned类型总是将是>= 0
有一些替代方法,最直接的是将整个for循环修改为:
- 将
i
声明为std::size_t
- 将减量作为条件检查中的后减量移动
- 完全删除增量步骤
结果如下所示:
for (std::size_t i = text.size(); i-- > 0;)
{
// use text[i] here
}
这将在循环体内从(text.size()-1)
到0
(包括CC_13)枚举,然后中断循环。即使字符串为空,它也会工作。
请注意,这样的胡闹是一个更大问题的标志:首先使用错误的结构。std::string
提供反向迭代器用于反向遍历字符串内容:
for (auto it = text.rbegin(); it != text.rend(); ++it)
{
// use *it to access each character in reverse order
}
在这两种方法中,首选第二种方法。
如注释所述,std::string
类的size()
成员函数返回类型为size_t
的值。该类型的确切性质因平台和编译器而异,但它始终是unsigned类型。一般来说,它相当于unsigned long int
或unsigned long long int
。
因此,为了避免编译器对初始化int i
的警告,您应该将循环索引声明为size_t
变量:然而,正如注释中所指出的那样,循环测试条件(i >= 0
)就不好了,因为对于任何unsigned类型,该条件永远不能为false。因此,您应该将该条件更改为i > 0
;您还应该确保基于i
变量对test
元素的任何访问都应该使用索引值i - 1
(而不仅仅是i
):最后一个元素将位于size - 1
,第一个元素将位于0
,因此您的循环将保持以下内容:
for (size_t i = text.size(); i > 0; --i) {
char element = text[i - 1]; // We need to offset our loop index by -1 ...
// Do something with or to 'element'
// ...
}