将字符串的长度分配给整数:C++
Assigning length of a string to an integer: C++
使用 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()
returns 无符号整数类型 (std::size_t
)。改变 i
的类型很容易,但是引入了另一个问题。 i
类型为 std::size_t
循环条件被打破;根据定义,无符号类型是 always 将是 >= 0
有替代方案,最直接的是将整个 for 循环修改为:
- 声明
i
为 std::size_t
- 在条件检查中将减量作为 post-减量移动
- 完全删除增量步骤。
结果如下所示:
for (std::size_t i = text.size(); i-- > 0;)
{
// use text[i] here
}
这将在循环体中从 (text.size()-1)
到 0
进行枚举,然后中断循环。即使字符串为空,它也会起作用。
请注意,此类恶作剧预示着更大的问题:首先使用了错误的结构。 std::string
提供 反向迭代器 用于向后遍历字符串内容:
for (auto it = text.rbegin(); it != text.rend(); ++it)
{
// use *it to access each character in reverse order
}
这两种方法中,首选第二种。
如评论中所述,std::string
class returns 的 size()
成员函数是一个 size_t
类型的值。这种类型的确切性质因平台和编译器而异,但它始终是 unsigned 类型。通常,它等同于 unsigned long int
或 unsigned long long int
.
因此,为了避免编译器警告初始化您的 int i
,您应该将该循环索引声明为 size_t
变量:for (size_t i = text.size(); ...
.
但是,正如评论中也指出的那样,您的循环测试条件 (i >= 0
) 并不好,因为对于任何 unsigned 类型,该条件可以永远不会是假的。因此,您应该将该条件更改为 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'
// ...
}
使用 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()
returns 无符号整数类型 (std::size_t
)。改变 i
的类型很容易,但是引入了另一个问题。 i
类型为 std::size_t
循环条件被打破;根据定义,无符号类型是 always 将是 >= 0
有替代方案,最直接的是将整个 for 循环修改为:
- 声明
i
为std::size_t
- 在条件检查中将减量作为 post-减量移动
- 完全删除增量步骤。
结果如下所示:
for (std::size_t i = text.size(); i-- > 0;)
{
// use text[i] here
}
这将在循环体中从 (text.size()-1)
到 0
进行枚举,然后中断循环。即使字符串为空,它也会起作用。
请注意,此类恶作剧预示着更大的问题:首先使用了错误的结构。 std::string
提供 反向迭代器 用于向后遍历字符串内容:
for (auto it = text.rbegin(); it != text.rend(); ++it)
{
// use *it to access each character in reverse order
}
这两种方法中,首选第二种。
如评论中所述,std::string
class returns 的 size()
成员函数是一个 size_t
类型的值。这种类型的确切性质因平台和编译器而异,但它始终是 unsigned 类型。通常,它等同于 unsigned long int
或 unsigned long long int
.
因此,为了避免编译器警告初始化您的 int i
,您应该将该循环索引声明为 size_t
变量:for (size_t i = text.size(); ...
.
但是,正如评论中也指出的那样,您的循环测试条件 (i >= 0
) 并不好,因为对于任何 unsigned 类型,该条件可以永远不会是假的。因此,您应该将该条件更改为 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'
// ...
}