似乎实际上是无限的'for'循环

我正在debugging一些代码,我碰到这一行:

for (std::size_t j = M; j <= M; --j) 

(由我的老板写的,正在休假)

我看起来很奇怪

它有什么作用? 对我来说,它看起来像一个无限循环。

std::size_t由C ++标准保证是一个unsignedtypes。 如果你从0递减一个unsignedtypes,标准保证了这样做的结果是该types的最大值。

该缠绕的值总是大于或等于M 1,因此循环终止。

因此当应用于unsignedtypes时, j <= M是一种方便的方式,即“将循环置零然后停止”。

替代方法,比如运行一个比你想要的更大,甚至使用幻灯片运算符 for (std::size_t j = M + 1; j --> 0; ){存在,虽然需要更多的input,但是可以更清楚地说明。 我认为一个缺点(除了在第一次检查时产生的令人眼花缭乱的效果之外)是,它不能很好地适应没有无符号types的语言,比如Java。

还要注意,你的老板挑选的“借用”一个可能的值unsigned集的scheme:在这种情况下,发生M设置为std::numeric_limits<std::size_t>::max()不会有正确的行为。 事实上,在这种情况下,循环是无限的 。 (这是你正在观察的?)你应该在代码中插入一个注释,甚至可能在这个特定的条件下断言。


1M不是std::numeric_limits<std::size_t>::max()

你的老板可能试图做的是从M到零,包括在内,对每个数字执行一些操作。

不幸的是有一个边缘情况,这确实会给你一个无限循环,其中M是你可以拥有的最大size_t值。 而且,虽然它很好的定义了一个无符号的值,当它从零递减时,我认为代码本身就是一个马虎思考的例子,特别是因为有一个完美可行的解决scheme,没有你的老板尝试的缺点。

这个更安全的变体(在我看来,更具可读性,同时仍然保持一个很小的范围限制)将是:

 { std::size_t j = M; do { doSomethingWith(j); } while (j-- != 0); } 

举个例子,看下面的代码:

 #include <iostream> #include <cstdint> #include <climits> int main (void) { uint32_t quant = 0; unsigned short us = USHRT_MAX; std::cout << "Starting at " << us; do { quant++; } while (us-- != 0); std::cout << ", we would loop " << quant << " times.\n"; return 0; } 

这基本上与一个unsigned short的同样的事情,你可以看到它处理一个值:

 Starting at 65535, we would loop 65536 times. 

上面代码中的do..while循环replace了你的老板的基本做法,将导致无限循环。 试试看看:

 for (unsigned int us2 = us; us2 <= us; --us2) { quant++; }