带有size_t循环变量的后向循环
backward loop with size_t loop variable
以下是代码定义的行为,我的意思是I——当I为0时,它将始终是size_t表示的最大无符号int,对吗?那么在我的代码中使用它完全安全吗?
size_t NPOS = -1;
for(size_t i = vec.size()-1; i!= NPOS; i--)
这是一个使用绝妙的go-to运算符的经典场景:
for (size_t i = vec.size(); i --> 0; )
在类std::basic_string
中,静态数据成员npos
的定义方式如下
static const size_type npos = -1;
考虑成员函数size()
的返回值的类型为size_type
。所以你的代码是有效的
size_t NPOS = -1;
for(size_t i = vec.size()-1; i!= NPOS; i--)
条件是表达式vec.size()-1
的值可以存储在类型size_t
中
所以更有效的代码将看起来像
for ( std::vector<T>::size_type i = vec.size()-1; i != std::vector<T>::npos; i-- )
尽管我会用以下方式写循环
for ( std::vector<T>::size_type i = vec.size(); i != 0; )
{
//...
// using expression vec[--i]
// or
// --i
// vec[i]
//...
}
从技术上讲,它是有效的,因为-1
到无符号类型保证产生尽可能大的值,从0
开始递减。但事实并非如此我会考虑好的做法。如果你只想迭代在一个矢量上反向:
for ( auto current = vec.rbegin(); current != vec.rend(); ++ current ) {
// Do something with *current
}
如果出于某种原因你确实需要索引:
int i = vec.size();
while ( i != 0 ) {
-- i;
// Do something with vec[i]
}
这个循环要干净得多,并且避免了未签名的任何问题类型包装(尽管如果您需要索引意味着你需要它作为一个算术值,所以你应该避免以无符号类型开头)。
对于给定的整数类型T
,所有这些都是相同的值,有符号或无符号:
T a = -1;
T b = 0 - 1;
T c = 0; c = c - 1;
T d = 0; d --;
T e = 0; -- e;
assert(a == b);
assert(a == c);
assert(a == d);
assert(a == e);
这涵盖了您在代码片段中的所有用法。整数的内部表示并不重要。有符号-1转换为类似的无符号整数的最大值这一事实很有趣,但并不直接重要。如果算术不起作用,则上述情况成立。
相关文章:
- 是否可以禁止在for循环体内部修改循环变量
- 使用 size_t 初始化循环变量时的整数下溢
- 在循环中重新声明 for 循环变量时出错
- 为什么这个循环变量在循环范围之外是可访问的
- 关于循环变量优化的标准合规行为是什么?
- 用于 C/C++ 中的循环变量优化
- C++循环变量按另一个变量递增
- 使用循环变量作为C++数组的索引
- 如何循环变量
- 如何在字符串(名称)中使用循环变量
- strlen函数与循环不兼容,循环变量不兼容
- 使用浮点/双精度作为循环变量
- C 或 C++ :表示循环变量
- 为循环变量声明键入 int32_t
- 使用 if 语句交换循环变量
- OpenMP中调度程序对循环变量的处理
- 对于C++中的循环-变量没有正确递增
- C++11 基于范围的 for 循环,无循环变量
- 在循环之外使用for循环变量是错误的吗?
- For循环变量无缘无故地下地狱