質問
[編集]コードに間違いがあったので、質問に対するすべての回答は奇妙に見えますが、基本的にforループはfor(i = 0; i <!> lt; 15; i ++ )。また、質問をより明確にするために編集しました。[/編集]
16要素の配列をチェックするforループを作成しようとしているため、0から15にループします。その後、後でi変数を使用しますが、場合によってはi == 16になり、範囲外になることで問題が発生します。
解決策はありますが、エレガントに見えないため、何かが足りないと思っています。 whileループを試しましたが、0から15までのループを取得したり、15を超える値で終了したりすることはできません。
ループを実行して配列の16個の要素すべてをチェックする方法はありますが、ループの最後で15を超えることはありませんか?
int i;
for(i=0; i<16; i++)
{
someClass.someMethod(i);
if(someClass.Test())
{
break;
}
}
if (i == 16)
{
i = 15;
}
解決
ループの終了後、i
以外の変数を使用することをお勧めします。 whileループの代わりにforループを使用する基準は、forループが実行される回数を正確に事前に知っていることです。すでにこれを知っている場合は、ループの終了値に他の変数を設定し、<=>二重の目的を与える代わりに使用してください。
int j = 15;
for(int i=0; i <= j; i++)
{
someClass.array[i];
}
// continue on using j, which value hasn't changed
他のヒント
さて、サンプルコードは0〜14でループします。しかし、0〜15でループする場合、当然、ループは終了する前でなければなりません。何が起こるかは、16になると、ループが範囲外であり、ブレークアウトすることに気づきます。 15で終了したい場合、正直なところ、最も簡単なことは、ループの終了直後にデクリメントすることです。
iは最後のチェックで16になるようにインクリメントされます。これは15以上であるため、ループはiが16で終了します。
おそらく次のことを知っておくと便利です:
for (before; check; after) { body }
同じ:
before
while(check) {
body
after
}
その用語でforループを考えると、おそらく出口でiが16である理由を簡単に見つけることができます。
アプローチには基本的な欠陥があるようです。
- 実際には、ループのスコープ外でインデックス変数を使用しないでください。
- 変数または関数を使用して、ループの制限を決定する必要があります。
- 数値インデックスの代わりにイテレータを使用することをお勧めします。
- 汎用アルゴリズムにより、ループの必要性を排除できます。
ちょうど$ 2.02
したがって-16要素の配列をチェックしている場合、通常は次のようにします。
for(i=0; i<16; i++)
どのように機能しますか、3つの最初のステートメントから始まります:
i=0
次に、2番目のステートメントでチェックを行います。
i < 16 // True here, since 0 < 16
ループの前に発生します。次に、そのセットでループのブロックを実行します。
someClass.array[i]; //0
最後に、最終ステートメントを実行します:
i++
次に、2番目と3番目のステートメントを順番に繰り返します。
最後の実行の前に、i == 14の場合、i ++を実行し、iを15に設定してブロックを実行します。最後に、i ++を設定します:
i==16
この時点で、条件はもはや真ではありません:
i < 16 // False, since i==16
この時点では、ブロックは実行されませんが、iはまだ16に設定されています。
何かを見逃したに違いない。
このループでは、15にヒットすることさえありません。i= 14になるとすぐに、i <!> lt; = 15と言う必要があります。
for
ループは、次のwhile
ループと同等です:
i = 0;
while(i < 16) {
someClass.array[i];
i++;
} // while
i
は、ループから正しく抜け出すために16に達する必要があります。
技術的には、ループの終了時にi
が15になるようにループを記述する方法がありますが、実行しないでください:
int i = 0;
while (1) {
someclass.someMethod(i);
if (i < 15) {
i++;
} else {
break;
}
}
はい、あなたが尋ねるとおりに行います。しかし、フローは恐ろしいです。
ビルトインループ構造ではこれを達成できません。BillThe Lizardが言ったように、おそらくforループ変数を再利用したくないでしょう。
しかし、本当にしたい場合は、ここでそれを行う方法があります。コツは、ループ条件をループの中央に置くことです:
int i = 0;
while (true)
{
someclass.array[i];
if (i == 15)
break;
++i;
}
ここで理解すべき重要な問題は、質問に対する17の異なる回答があることです。<!> quot; iのどの値がテストを成功させますか?<!> quot;。 iが{0、1、...、15}にあるか、iの値がなくてもテストが成功します。この場合、i == 16で示されます。したがって、16個の値のみに制限されている場合、質問には答えられません。
最後の有効な値を超えたくない正当なケースがあります。たとえば、256個の値があり、何らかの理由でカウントするバイトが1つしかない場合。または、最近私に起こったように、配列のすべてのi番目の要素のみを調べたいので、イテレータに最後に追加すると、配列の終わりをはるかに超えてしまいます。これらの場合、ループの展開が必要です。
ただし、この問題の場合、フラグを使用する方がクリーンです。
bool flag = false;
for (int i = 0; i < 15; ++i)
{
someClass.someMethod(i);
if (someClass.Test())
{
flag = true;
break;
}
}
その後、テストが成功したかどうかは明らかです。
ループがブレークではなく自然に終了する場合、i
は16になります。これを回避する方法はありません。 iが15以下になるようにしたい場合、コードは完全に受け入れられます。
int i;
for (i=0; i<16; i++) {
someClass.someMethod(i);
if (someClass.Test())
break;
}
if (i == 16)
i = 15;
ループ本体の後にsomeClass.Test()
を16から15に変更するすべての処理:
if (i == 16) i = 15;
i = (i == 16) ? 15 : i;
i = MAX (15,i); /* where MAX is defined :-) */
など。
ただし、そのループに関する事後条件として意味のある何かにi == 15
が使用されることを前提としています。私はそれがめったにないことを見つけ、人々は再使用する前にそれを再初期化する傾向があります(別のforループなど)。
さらに、あなたがしていることは、ループが正常に終了したか、または<=>が<=>に対してtrueを返したために途中で終了したかを、事後条件として把握することを非常に困難にします。これは、iを使用してさらに決定を下すことには危険が伴うことを意味します。
私の質問は次のとおりです。なぜ <=>を15以下にしておく必要があると思いますか?
forループを作成しようとしています。 16要素の配列をチェックし、ループします 0から15まで。その後、iを使用します。 後で変数、ただし時々i == 16、外に出て問題を引き起こす 境界の。
forループが中断しなかった場合をチェックする必要があります。この情報は、iでやりたいことが有効かどうかを判断するためです。
これを行うにはいくつかの方法があります。 1つは、<!> quot; foundClass <!> quotなどのブール値で追跡することです。または<!> quot; testSucceeded <!> quot;。デフォルトでfalseに設定してから、休憩時にtrueに設定します。 <!> quot; if(foundClass){} <!> quot;で、関数内のiの使用を後で囲みます。ブロック。
別の方法は、あなたがやったことをすることです。フォールバックはまったく正しく見えませんが。 iを15に設定すると、コードに横たわって、i == 15でsomeClass.Test()が成功したことを伝えますが、これは正しくありません。コードが後でエラーにならないように、値を間違った値に設定しないでください。コードの後半でiの実際の使用方法を境界チェックする方がはるかに優れています。
for(int i=0; i<17; i++)
{
if(i<16)
{
someClass.someMethod(i);
if(someClass.Test())
{
break;
}
}
else if(i==16)
{
i=15;
}
}
16個の要素を持つ配列がある場合は、それを定義する必要はありません。配列を使用してその情報を取得します(情報を重複しないでください)
その後、最後のインデックスを再度取得する場合は、配列を使用してその情報を取得します。
for(int i = 0; i < myArray.length; ++i){
myArray[i].somemethod();
}
// lastindex = myArray.length-1;