0

だから、ドットの座標を検出するプロジェクトに取り組んでいます。

から検出された座標を抽出しstd::vector<cv::Point> dots、x 座標と y 座標をそれぞれ と に格納std::vector<int> dotsXstd::vector<int> dotsYます。(代わりにdots.xorを使用できることはわかっていますが、それは私が望んでいるものではありません)dots.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 など)。

なぜそれが起こっているのかわかりません。

どんな助けでも大歓迎です。ありがとうございました

4

4 に答える 4

6

2 番目の例は、常に の範囲外の要素にアクセスすることになるため、動作は未定義ですdotsX

forループと同じにするには、次のように変更します。

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

また、C++ にはコンテナーを反復処理するより慣用的な方法があることにも注意してください。特に、C++11 には範囲ベースのforループがあるため、インデックスや反復子をいじることはできません。

for (int x : dotsX) { std::cout << x << std::endl; }
于 2013-05-26T15:00:05.650 に答える
1

ベクトルは内部でサイズを維持し、 vector::size() メソッドでサイズを取得できます。したがって、for ループでは、x が dotX.size() より小さい限り、x をインクリメントします。準備ができたら、前ループは中止されます。x がベクトル内の cv::Dot の合計よりも大きいかどうかを while ループでチェックしないため、ループ内の for バージョンよりも while バージョンでより多くの出力が得られます。while ループは、偶発的に dotX がゼロに等しい場合にのみ終了しますが、割り当てていないメモリにアクセスするため、プログラムが途中で終了する可能性が最も高くなります。

次のように while ループを試すこともできますが、for ループはこれをより適切に表現します。

int x = 0;
while ( true ){
    if ( ! (x < dotsX.size() ) break;
    std::cout << dotsX[x] << std::endl;
    x++;
}
于 2013-05-26T15:10:44.657 に答える
1

あなたのループには同じ条件がありません。ループ バージョンではwhile、ベクトルの末尾を越えて少なくとも 1 回アクセスします。これを行うと、未定義の動作が発生し、何かが起こる可能性があります。あなたの場合、余分な無効な出力が得られたようです。

一致するように条件を変更すると、一致する (正しい) 動作が得られます。

 while (x < dotsX.size())
于 2013-05-26T15:01:03.410 に答える
0

あなたのforループは数量をチェックしています:

x < dotsX.size()  

あなたのwhileループは値をチェックしています:

dotsX[x]  

while式は次と同じです 。

while (dotsX[x] != 0)

これはおそらくタイプミスです。

于 2013-05-26T17:29:42.553 に答える