对于循环退出条件(size_t与int)

时间:2015-07-27 17:20:23

标签: c++ for-loop int size-t

当我在我的程序中添加以下内容时:

for (size_t i = VectorOfStructs.size()-1; i > 0; i--)

它正常工作但“i”永远不会等于0。  所以,我无法访问第一个元素(VectorOfStructs [0])。

如果我将其更改为:

for (size_t i = VectorOfStructs.size()-1; i > -1; i--)

程序甚至没有进入for循环!但是,如果我将其更改为以下内容:

for (int i = VectorOfStructs.size()-1; i > -1; i--)

它完全符合我的要求(迭代所有元素)。

所以,我的问题是:

(A)为什么第二个代码段无法执行?

(B)为什么第3个代码段会相应地执行而第2个代码片段没有执行?

非常感谢任何见解!

8 个答案:

答案 0 :(得分:4)

所有循环都向前发展,即使是那些向后循环。

你想要的是:

for (std::size_t i = 0, e = VectorOfStructs.size(); i != e; ++i)
{
    std::size_t const ri = e - i - 1;

    // use "VectorOfStructs[ri]"
}

或更好:

for (auto rit = VectorOfStructs.rbegin(); rit != VectorOfStructs.rend(); ++rit)
{
    // use "*rit"
}

(您的第二个代码段失败,因为i是无符号的,因此-1转换为与i相同的类型,并成为最大可表示值,因此比较始终为真。相反,i在第三个片段中签名。)

答案 1 :(得分:3)

在第二个中,你将变量'i'与-1进行比较,这里的类型是size_t,大小不能为负,所以它会失败。

在第三个中,'i'是整数类型,整数的范围是-32568到+32567(对于系统中的int = 2字节)

整体size_t变量不能具有负值,因为物理内存将存在于系统中

答案 2 :(得分:2)

第二个示例使用size_t作为i的类型,这是无符号类型,因此它永远不会有负值;这也意味着它无法与-1

进行正确比较

(int)-1位代表为0xFFFFFFFF,代表2^32-1的相当大的数字(size_t)。 i>0xFFFFFFFF永远不会成为现实,因为0xFFFFFFFsize_t可以容纳的最大值。

第3个示例使用signed int(允许负数,因此测试成功)。

这个应该有效:

for (size_t i = VectorOfStructs.size(); i-- > 0;) {
  use(VectorOfStructs[i]);
}

答案 3 :(得分:2)

  

为什么第二个代码段无法执行?

size_t是无符号的,因此根据定义它永远不会消极。所以你的循环条件总是如此。变量“环绕”到最大值。

答案 4 :(得分:1)

size_t是无符号类型,因此-1size_t可以采用的最大值。在第二个代码段size_t中,不能大于此最大值,因此不会输入循环。

另一方面,int是签名类型,因此与-1的比较符合您的预期。

答案 5 :(得分:0)

Int和size_t都是整数类型,但int可以保留负数和正数。 int的范围是-2 ^ 31 -1到2 ^ 31 -1,而size_t的范围是0到2 ^ 32 -1

现在,当你写一些类似int a = -1的东西时,确实是-1但是当你用size_t这样做时你会得到max int 2 ^ 32 -1

所以在第二个片段中,size_t值不会超过-1,因为它确实是2 ^ 32 -1

在第3个片段中,比较的类型是int,当int与-1比较时,它将其视为-1,因此它按照您计划的方式执行

答案 6 :(得分:0)

当编译器看到i > -1并注意到子表达式i-1具有不同类型时,它会将它们都转换为公共类型。如果两种类型(std::size_tint)具有相同的位数(对于编译器来说似乎是这种情况),则公共类型是无符号类型(std::size_t)。所以表达式相当于i > (std::size_t)-1。但当然(std::size_t)-1size_t的最大可能值,因此比较始终为假。

由于这样的原因,大多数编译器都会发出有关比较的警告,该比较始终为真或始终为假。

答案 7 :(得分:0)

每当您比较'signed'和'unsigned'时,'signed'值将首先转换为'unsigned'。这包括(#1)和(#2),有'unsigned(0-1)'和'some unsigned'>的问题。 'unsigned max'。

然而,通过强制进行“签名”/“签名”比较(#3)使其工作,您将失去“无符号”范围的1/2。

您可以这样做:

for(size_t n = vector.size(); n; /* no -- here */ ) {
   --n;
   // vector[n];
}

注意:unsigned(-1)在许多系统上是最大的无符号整数值。