Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用于循环退出条件(大小与整数)_C++_For Loop_Int_Size T - Fatal编程技术网

C++ 用于循环退出条件(大小与整数)

C++ 用于循环退出条件(大小与整数),c++,for-loop,int,size-t,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 = VectorOfStru

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

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)为什么第三个代码段会相应地执行,而第二个代码段不会执行?


如有任何见解,将不胜感激

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

但是
(int)-1
被表示为
0xFFFFFFFF
,它表示
大小的一个相当大的数字(
2^32-1
i>0xFFFFFFFF
永远不可能为真,因为
0xffffff
size\u t
所能容纳的最大值

第三个示例使用了
带符号int
(这允许使用负数,因此测试成功)

这一条应该有效:

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

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

另一方面,
int
是一种有符号类型,因此与
-1
的比较正如您所期望的那样

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


size\u t
是无符号的,因此根据定义,它从不为负。所以你的循环条件总是正确的。变量“环绕”到最大值。

在第二个变量中,您将变量“i”与-1进行比较,这里它的类型是size\u t,大小不能为负数,因此它失败

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


总体
size\t
变量不能有负值,因为物理内存将在系统中存在

所有循环向前,即使是向后的循环

您想要的是:

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
在第三个代码段中被签名。)

Int和size\u t都是整数类型,但Int可以包含负数和正数。 int的范围为-2^31-1到2^31-1,而size\u t的范围为0到2^32-1

现在,当你写像int a=-1这样的东西时,它确实是-1,但是当你用size做的时候,你得到了max int 2^32-1

因此,在第二段代码中,任何大小的值都不会超过-1,因为它实际上是2^32-1


在第三个代码段中,比较的类型是int,当int与-1比较时,它会将其视为-1,因此当编译器看到
i>-1
并注意到子表达式
i
-1
具有不同的类型时,它会将它们转换为公共类型。如果这两种类型(
std::size_t
int
)具有相同的位数(这对于编译器来说似乎是如此),则常见类型是无符号类型(
std::size_t
)。所以这个表达式相当于
i>(std::size\u t)-1
。但是当然
(std::size_t)-1
size_t
的最大可能值,因此比较总是错误的


大多数编译器都有一个关于比较的警告,因为这样的原因,比较总是正确的或错误的。

每当比较“有符号”和“无符号”时,首先将“有符号”值转换为“无符号”。这包括(#1)和(#2),在“unsigned(0-1)”和“some unsigned”>“unsigned max”方面存在问题

但是,如果通过强制进行“有符号的”/“有符号的”比较(#3)使其工作,则失去了“无符号的”范围的1/2

你可以:

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

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

size\u t是一种无符号类型,它永远不会大于
(size\u t)-1
。大多数编译器都会为这类代码生成警告,您可能希望启用它。也许更好:
for(auto-iter=VectorOfStructs.rbegin();iter!=VectorOfStructs.rend();++iter){/*使用*iter*/}
如果要向后迭代,您应该在
for
循环的第二部分中检查
i-->0
,并删除for循环的第三部分,尽管
int
通常具有32位==4字节,早期机器使用2字节存储整数变量,但现在机器根据Systemsure的体系结构将其存储为2字节/4字节;这是非常罕见的这些天;顺便说一句,你能详细说明非物理内存是如何允许负大小的吗?不存在任何非物理内存,就好像你认为虚拟内存也有一些物理存在一样。啊,使用“->运算符”(参见相关的堆栈溢出问题) instead@BenjaminLindley:facepalm:/me不会再使用canonical…@KABoissonneault嘿,在你发表评论之前我已经修复了…你有“use()”函数的链接吗?我从没听说过,搜索结果一无所获。@Donald:那只是你代码的占位符!我不知道如何使用“*rit”。如果我这样做:int Counter=*rit;它给了我“错误:不存在从“VectorOfStructs”到“int”的可补转换函数”@Donald:迭代器允许您访问向量元素,而不是向量下标。