使用for循环反向迭代无符号整型数值

51

我想让for循环中的迭代变量以逆序迭代到0,它是一个无符号整数unsigned int,但我想不出类似于i > -1这样的比较方法,如果它是一个有符号整数signed int,你可能会这样做。

for (unsigned int i = 10; i <= 10; --i) { ... }

但是这种方法似乎很不明确,因为它依赖于无符号整数的数值溢出大于10。

也许我只是头脑不清,但还有更好的方法可以做到这一点...

免责声明:这只是一个简单的用例,上限10是微不足道的,它可以是任何值,且i必须是无符号整数。


如果i最初等于0怎么办? - Shamim Hafiz - MSFT
我认为这是正确的方法。当C++引入size_t时,它让我相当烦恼,但我已经习惯了它。 - Viktor Sehr
然后 i = 0; i <= 0; 它按预期迭代一次... - deceleratedcaviar
3
无符号整数i的初始值为10;当i不为0时,执行循环体:每次迭代减小i的值并继续下一次循环。因此,该循环将迭代9到0这10个数字。 - Erik
https://dev59.com/RXI-5IYBdhLWcg3w18d3 - Robᵩ
显示剩余2条评论
14个回答

0
你可以尝试定义以下宏:
#define for_range(_type, _param, _A1, _B1) \
    for (_type _param = _A1, _finish = _B1,\
    _step = static_cast<_type>(2*(((int)_finish)>(int)_param)-1),\
    _stop = static_cast<_type>(((int)_finish)+(int)_step); _param != _stop; \
_param = static_cast<_type>(((int)_param)+(int)_step))

现在你可以使用它:

for_range (unsigned, i, 10,0)
{
    cout << "backwards i: " << i << endl;
}

它可以用于无符号整数、枚举和字符的正向和反向迭代:

for_range (char, c, 'z','a')
{
    cout << c << endl;
}

enum Count { zero, one, two, three }; 

for_range (Count, c, zero, three)
{
    cout << "forward: " << c << endl;
}

尽管它的定义有些笨拙,但它被优化得非常好。我在VC++中查看了反汇编器。 代码非常高效。不要被三个for语句吓到:编译器在优化后只会产生一个循环!你甚至可以定义嵌套循环:

unsigned p[4][5];

for_range (Count, i, zero,three)
    for_range(unsigned int, j, 4, 0)
    {   
        p[i][j] = static_cast<unsigned>(i)+j;
    }

显然,您无法遍历具有间隔的枚举类型。


0

我是C++的新手,我的回答可能很愚蠢,但是我为这种反向循环而做到了这一点;

size_t count = 3;
size_t newCount = 0;
if (count > 0)
    for (size_t i = count - 1; i >= newCount; i--)
    {
        //do your work here

        //and at the end
        if (i == 0)
            break;
    }

它可以工作。由于“i--”部分在循环执行的下一步,因此break应该能够正常工作。 你认为这种方式安全吗?


-1

只是:

int start = 10;
for(unsigned int iPlus1 = start + 1 ; iPlus1 > 0 ; iPlus1--) {
  // use iPlus1 - 1 if you need (say) an array index
  a[iPlus1 - 1] = 123; // ...
}

No?


-1

另一种方法:

for(unsigned i = n-1; i < n ; --i) 
{       
    // Iterates from n-1 to 0
}

同样地,对于 size_t (无符号整数类型),使用相同的技巧

for(std::size_t i = n-1; i < n ; --i) 
{       
    // Iterates from n-1 to 0
}

这与问题本身中的方法相同。OP正在寻找其他东西。 - VLL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接