当我在程序中输入以下内容时:
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)为什么第三个代码片段相应地执行而第二个代码片段没有执行?
任何见解将不胜感激!
所有的循环都是向前的,即使是向后的。
你想要的是:
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
在第三个代码片段中被签名。)
第二个例子使用size_t
作为i
的类型,这是一个unsigned类型,因此它永远不会有负值;这也意味着它不能恰当地与-1
但是(int)-1
是位表示为0xFFFFFFFF
的,这对于size_t
来说代表了一个相当大的数字(2^32-1
)。i>0xFFFFFFFF
不可能为真,因为0xFFFFFFF
是size_t
所能容纳的最大值。
第三个例子使用signed int
(允许负数,因此测试成功)。
这个应该可以工作:
for (size_t i = VectorOfStructs.size(); i-- > 0;) {
use(VectorOfStructs[i]);
}
在第二个例子中,你将变量'i'与-1进行比较,这里它的类型是size_t, size不能为负,所以它失败了。
在第三个例子中,'i'是整数类型,整数的范围从-32568到+32567(对于int=2字节的系统)
总的size_t
变量不能为负值,因为物理内存将在系统中存在
为什么第二个代码段执行失败?
size_t
是无符号的,所以根据定义它永远不是负的。所以循环条件总是为真。变量"wrap around"为最大值
size_t
是unsigned类型,所以-1
是size_t
可以接受的最大值。在第二个代码片段中,size_t
不能大于这个最大值,因此不进入循环。
另一方面,int
是有符号类型,因此与-1
的比较如您所料。
Int和size_t都是整数类型,但Int既可以保存负数也可以保存正数。Int的取值范围是-2^31 -1到2^31 -1,size_t的取值范围是0到2^32 -1
现在,当你写int a = -1时它确实是-1但是当你用size_t这样做时你得到的是int的最大值2^32 -1
所以在第二段代码中size_t的值不会超过-1因为它实际上是2^32 -1在第三个代码片段中,比较的类型是int,当将int与-1比较时,它会将其视为-1,因此它按照您计划的方式执行
当编译器看到i > -1
并注意到子表达式i
和-1
具有不同的类型时,它将它们都转换为通用类型。如果这两种类型(std::size_t
和int
)具有相同的位数,这似乎是您的编译器的情况,则通用类型是无符号类型(std::size_t
)。因此表达式等于i > (std::size_t)-1
。但是当然(std::size_t)-1
是size_t
的最大值,所以比较总是假的。
大多数编译器都有一个关于总是为真或总是为假的比较的警告,原因如下。
当你比较'signed'和'unsigned'时,'signed'值首先被转换为'unsigned'值。这包括(#1)和(#2),有一个问题'unsigned(0-1)'和'some unsigned'> 'unsigned max'。
然而,通过强制'signed'/'signed'比较(#3)使其工作,您将失去'unsigned'范围的一半。
你可以这样做:
for(size_t n = vector.size(); n; /* no -- here */ ) {
--n;
// vector[n];
}
注意:unsigned(-1)在很多系统上是最大的无符号整数值。