用无符号循环variables反向迭代
我一直在和同事讨论如何使用size_t。 已经出现的一个问题是循环递减循环variables,直到达到零。
考虑下面的代码:
for (size_t i = n-1; i >= 0; --i) { ... }
这会由于无符号整数环绕而导致无限循环。 你在这种情况下做什么? 写上面的代码似乎很容易,而且没有意识到你犯了一个错误。
我们团队的两个build议是使用以下样式之一:
for (size_t i = n-1; i != -1 ; --i) { ... } for (size_t i = n; i-- > 0 ; ) { ... }
但我不知道还有其他的select…
我个人喜欢:
for (size_t i = n; i --> 0 ;)
它有a)没有滑稽的-1
,b)条件检查是助记符,c)以一个合适的笑脸结束。
无符号整数保证很好地包装。 他们只是执行算术模2 N。 所以一个容易阅读的习惯是这样的:
for (size_t i = n-1; i < n ; --i) { ... }
这将variables设置为您想要的初始值,显示迭代的意义(向下),并精确地给出您要处理的值的条件。
- 用algorithmreplace循环。
- 使用反向迭代器而不是整数。
- 从n到1倒数,但在循环内使用
i-1
而不是i
。
如果你担心不小心编写了这样的循环,一些编译器会警告这样的事情。 例如,gcc有一个由-Wtype-limits
选项启用的警告(也由-Wextra
启用):
xc:42: warning: comparison of unsigned expression >= 0 is always true
你在使用标准库容器吗? 如果是的话,我喜欢reverse_iterator
vector<int> ivect; // push, push, push... vector<int>::reverse_iterator riter; for(riter=riter.rbegin(); riter!=ivect.rend(); ++riter) { //... }
对于一个原始数组,你可以使用std::reverse_iterator
这个键是一个指针是一个迭代器:
int i[] = {1, 2, 3, 4}; typedef std::reverse_iterator<const int*> irevit; irevit iter(i+4); irevit end(i); for(; iter != end; ++iter) { cout << *iter; } // Prints 4321
非连续的对象迭代可以通过将对象指针存储在容器或数组中来完成:
struct Foo { Foo(int i) I(i) { } int I; } vector<Foo*> foos; for(int i = 0; i < 10; ++i) foos.push_back(new Foo(i)); typedef vector<Foo*>::const_reverse_iterator frevit; frevit iter(foos.rbegin()); for(; iter != foos.rend(); ++iter) { cout << (*iter)->I; } // Prints 9876543210
如果你真的想使用一个裸体size_t
那么为什么在其他答案中使用所有这些隐含混淆-1的诡计? size_t
的最大值明确可用作终止值:
int is[] = {1, 2, 3, 4}; int n = 3; for (size_t i = n; i != std::numeric_limits<size_t>::max(); --i) { cout << is[i] << endl; } // prints 4321
i != -1
依靠-1
被默默地投给了size_t
,这对我来说似乎很脆弱,所以,在你select的选项中,我肯定会用后一个。 另一种可能性(尤其是如果你实际上并不需要i
在循环体中,而只需要以相反的顺序迭代数组),将数组包装在std::
-like容器中,并在包装器上使用迭代器,使用rbegin
和rend
方法。 例如, Boost.Array将支持后者的select。
这里是一个关于这个主题的良好讨论的指针。
我会尝试:
for( size_t i = n; i != 0; i-- ) { // do stuff with array[ i - 1 ] }
size_t i = n-1; do { ... } while ( i-- != 0);
如果需要,你可以用if (n > 0)
来包装它。
另一种方式(无签名/无签名比较):
for (size_t i = n-1; i + 1 > 0; i--)
以来
(i + 1 > 0) === (i > -1)