我希望for循环中的iterator变量以#{1}}的形式反向迭代为0,我想不出与unsigned int
的类似比较,就像它是i > -1
那样。 1}}。
signed int
但这似乎很不清楚,因为它依赖于无符号整数的数值溢出大于10.
也许我只是没有清醒的头脑,但是有什么更好的方法来做到这一点......
免责声明:这只是一个简单的用例,10的上限是微不足道的,它可以是任何内容,for (unsigned int i = 10; i <= 10; --i) { ... }
必须是i
。
答案 0 :(得分:31)
您可以使用
for (unsigned int j = n; j-- > 0; ) {}
它从n-1
向下迭代到0
。
答案 1 :(得分:17)
以下是您想要的:
for (unsigned i = 10; i != static_cast<unsigned>(-1); --i)
{
// ...
}
完美定义,实际上有效。有符号类型的算法由标准准确定义。事实上:
从 4.7 / 2 (关于转换为无符号类型):
如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2 ^ n,其中n是用于表示无符号类型的位数)
和 3.9.1 / 4
无符号整数,声明为无符号整数,应遵守算术模2 ^ n的定律,其中n是整数特定大小的值表示中的位数
答案 2 :(得分:3)
我的模式通常是......
for( unsigned int i_plus_one = n; i_plus_one > 0; --i_plus_one )
{
const unsigned int i = i_plus_one - 1;
// ...
}
答案 3 :(得分:3)
你是否真的从大于std::numeric_limits<int>::max()
的某个数字开始迭代?如果没有,我实际上建议您使用普通的int
作为循环变量,并static_cast
将其unsigned
添加到代码中希望无符号的位置>= 0
。通过这种方式,您可以使用直观的> -1
或static_cast
条件,一般来说,我希望它比任何未签名的替代方案更具可读性。
{{1}}只是告诉编译器如何操作变量并且根本没有性能影响。
答案 4 :(得分:2)
我可以认为这两个选项可以是强制数字或者是singed数字(例如,可以隐式地与-1进行比较)或者使用循环条件来检查溢出,如下所示:
for(unsigned i=10;i>i-1;--i){ } // i = 10, 9, ... , 1
for(unsigned i=10;i+1>i;--i){ } // i = 10, 9, ... , 1,0
此循环将继续,直到i溢出(意味着它达到零)。请注意,重复的是我迭代1,否则你可能会以无限循环结束。
答案 5 :(得分:1)
我会使用两个变量:
unsigned int start = 10;
for (unsigned int j = 0, i = start; j <= start; ++ j, -- i) {
// ...
}
你也可以使用while循环:
unsigned int start = 10;
unsigned int i = start + 1;
while (i --) {
// ...
}
答案 6 :(得分:0)
for(unsigned i = x ; i != 0 ; i--){ ...
如果你想在i == 0时执行循环体并在此之后停止。从i = x+1;
答案 7 :(得分: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;
}
你显然无法通过间隙迭代枚举类型。
答案 8 :(得分: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应该可以正常工作。 您认为这种方式安全吗?
答案 9 :(得分:0)
避免下溢
unsigned int i = n;
while (i !=0){
--i;
...
}
答案 10 :(得分:0)
如果i
以1进行迭代,这是避免溢出的简单技巧。
for(unsigned int i = n-1; i+1 >= 1; i--) {;}
如果您希望i
进行1次以上的迭代,则
unsigned int d = 2;
for(unsigned int i = n-1; i+d >= d; i-=d) {;}
答案 11 :(得分:0)
for (unsigned int i = 10; i <= 10; --i)
一口气拿下它。
我不想将您已有十年之久的问题回覆给您,但是尝试避免下溢会混淆您最终想要做的事情。
无符号整数的下溢是您可以依赖的明确定义的行为,希望其他程序员可以理解。任何变通方法都将使您要尝试作用的范围变得更难解析,并且可能会使初学者感到困惑,同时如果他们应该以相反的方式将其作为“课程”,则给他们一个不好的榜样循环
答案 12 :(得分:-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; // ...
}
没有
答案 13 :(得分:-1)
还有一种方法:
for(unsigned i = n-1; i < n ; --i)
{
// Iterates from n-1 to 0
}
Simillarly对于 size_t (无符号整数类型)使用相同的技巧
for(std::size_t i = n-1; i < n ; --i)
{
// Iterates from n-1 to 0
}