迭代无符号整数的所有值的最佳方法

Sun*_*ius 5 c++ iteration c++11

我想迭代一个整数的所有可能值。此代码不起作用,因为终止条件永远不会变为假:

for (uint32_t i = 0; i <= 0xFFFFFFFF; i++)
    std::cout << i << std::endl;
Run Code Online (Sandbox Code Playgroud)

我想出了这个:

auto loopBody = [](uint32_t value)
{
    std::cout << value << std::endl;
};

uint32_t last = 0xFFFFFFFF;
for (uint32_t i = 0; i < last; i++)
    loopBody(i);

loopBody(last);
Run Code Online (Sandbox Code Playgroud)

不过,它相当丑陋。有没有更漂亮的方法来做到这一点?

Hol*_*Cat 5

我会使用这样的东西:

uint32_t i = 0;
do
{
    // Your code here.
    i++;
}
while (i != 0);
Run Code Online (Sandbox Code Playgroud)

我个人认为它比涉及std::numeric_limits.


正如@NicosC 所说,请记住,您不应该对有符号整数执行相同的操作,因为有符号溢出是未定义的行为。

  • 请注意,这是带符号整数的 UB。但无签名就可以了。 (3认同)

Nik*_* C. 1

您无法检查循环头中的中断条件,因为为此您需要排除最大值。

相反,在循环体中进行检查并将标头中的检查留空:

for (auto i = std::numeric_limits<int>::lowest(); ; ++i) {
    std::cout << i << '\n';
    if (i == std::numeric_limits<int>::max())
        break;
}
Run Code Online (Sandbox Code Playgroud)

使用 do-while 循环,不需要在循环体内进行检查,但需要将计数器变量移到外部作用域,如果想避免未定义的行为,只能使用无符号整数类型:

auto i = std::numeric_limits<unsigned>::lowest();
do {
    std::cout << i << '\n';
} while (i++ < std::numeric_limits<unsigned>::max());
Run Code Online (Sandbox Code Playgroud)

请注意,i++将会溢出,但这仅在获取当前值之后发生(我们使用后缀增量)。但是,对于有符号整数,这种溢出将是未定义的行为,即使我们在溢出发生后没有使用该值,未定义的行为可能会产生不可预测的结果,甚至在它实际发生之前也是如此。

  • 自 2016 年以来重新发明了“do{}whie()”。 (7认同)