2013-05-26 119 views
0

所以,我正在开发一个检测点坐标的项目。为什么我会在“For”和“While”之间得到不同的结果?

我从std::vector<cv::Point> dots中提取检测到的坐标,并将每个x和y坐标存储为std::vector<int> dotsXstd::vector<int> dotsY。 (我知道我可以用dots.xdots.y代替,但是这不是我想要的)

每当我想打印输出,我得到一个for环路和while循环,显示值向量之间不同的结果。举一个例子:

检测到的X坐标是15,20,50和所检测的Y坐标是2,10,20

如果我使用for循环:

for(int x=0;x < dotsX.size();x++) 
{ 
    std::cout << dotsX[x] << std::endl; 
} 

输出是一样的:15,20,50。

但是,如果我使用while循环:

int x=0; 
while(dotsX[x]) 
{ 
    std::cout << dotsX[x] << std::endl; 
    x++; 
} 

输出是怪异:15,20,50,32总是有在它(一个额外的值等的值32,有时10201或4等)。

我不知道为什么会发生这种情况。

任何帮助将不胜感激。 谢谢

+0

你'while'循环正在检查**值**。 'for'循环正在检查**数量**。两个截然不同的概念。 –

回答

6

第二个示例具有未定义的行为,因为它总是最终访问dotsX的超出边界元素。

为了使其等同于for循环,它变成:

while(x < dots.size()) 
{ 
    // ... 
} 

还要注意,即C++有迭代的容器的更惯用的方式。特别是,C++ 11具有基于范围的for环,这使得它不可能为你惹指数或迭代器:

for (int x : dotsX) { std::cout << x << std::endl; } 
+0

但是,只要while循环访问一个不存在的值,它就会停止循环,不是吗? – anarchy99

+1

@ anarchy99:不,它不会停止。访问超出界限元素是未定义的行为。另外,在你的例子中,判断循环是否被输入的条件是基于正在读取的*值*('dotsX [x]')。因此,如果'dotsX [i]'对于某些'i'具有值'0',那将停止循环,不管'dotsX'是否具有多于'i'的元素 –

+0

只会增加while循环的唯一原因终止是它运行到超出数组末尾的连续块内存,恰好设置为0x0000 – qwwqwwq

1

你的循环没有相同的条件。 while循环版本至少有一个访问超过向量的末尾。这样做会导致未定义的行为,并且可能发生任何事情。在你的情况下,它看起来像你只是得到一些额外的无效输出。

如果你改变的条件相匹配,你会得到匹配(正确的)行为:

while (x < dotsX.size()) 
1

载体维持大小有一个内部能够检索大小的矢量:: size()方法。因此,在for循环中,只要x小于dotX.size(),就增加x。准备好后,您的前循环将中止。 您在while循环中不检查x是否大于向量中的cv :: Dot的总数,因此您可以在while版本中获得比在for循环中更多的输出。 while循环只会在偶然dotX等于零时退出,但很可能您的程序过早结束,因为您访问了未分配的内存。

你可以尝试这样的while循环,但对于循环表达了这一点要好得多:

int x = 0; 
while (true){ 
    if (! (x < dotsX.size()) break; 
    std::cout << dotsX[x] << std::endl; 
    x++; 
} 
0

for循环检查数量:

x < dotsX.size() 

while回路校验值:

dotsX[x] 

while表达式相同:

while (dotsX[x] != 0) 

这可能是一个错字。

相关问题