这是因为 size 是无符号的。如果从无符号数中减去 0,则得到该数的最大值。试试:
if(foo.size() > 0)
{
for(int i = 0; i < foo.size() - 1; i++)
{
cout << foo[i] << endl;
}
}
或者,更简单的解决方案,只是避免减去。改为添加。
for(int i = 0; i + 1 < foo.size(); i++)
{
cout << foo[i] << endl;
}
如果您在 foo 有 0 个元素时打印出 foo.size() - 1,您可以准确地知道代码中发生了什么。在我这边,它打印 18446744073709551615。这是一个非常大的非负数。
更多关于无符号数的信息
当您从无符号 (0) 中减去 1 时,您的数字位全部变为 1(它们从全 0 变为全 1)。这是因为通常情况下,负数以一种称为二进制补码的形式表示 - 要使一个数为负数,您需要翻转该数的所有位,并将结果加 1。
对于负数(示例为 4 位):
0001 = 4
1110 = flipped
1111 = flipped + 1
因此,在四位二进制补码中,-1 表示为全1。
因此,从 0000 中减去 1 应该得到 1111。
但是计算机如何知道一个数字是否为负数?
简单的。它假定任何设置了最左边位的数字都是负数。
这一切都很好,但这意味着您可以使用更少的位来存储 LARGE 数字。
如果您使用最高有效位来表示 8 位数字的符号,则您可以表示的最大数字从 255 下降到 127。
出于这个原因,我们偶尔会将数字视为无符号数,以便我们可以存储较大的值。不利的一面是,如果我们从 0 中减去任何内容,我们将得到通常表示负数的结果,但会将其解释为非常大的正数。
同样,如果你有一个 32 位整数设置为可以用 32 位表示的最大可能数(假设无符号),并在其上加 1,该数将回绕,回到 0。
这些问题称为上溢和下溢。