1

indexと呼ぶプロパティがあります。arrayと呼ぶ可変配列があります。このコードがインデックスの範囲外の例外をスローすることにショックを受けましたか?

if(index >= [array count]) return;


for(self.item = [array objectAtIndex:index]; index < [array count]; self.item = [array objectAtIndex:index]) {
        index++;
        //do stuffs
    }

ただし、このバリアントは機能します。

if(index >= [array count]) return;
while(index < [array count];) {
    self.item = [array objectAtIndex:index];
    index++;
    //do stuffs
}

私はループが次のように動作することを期待しています:

for(initialization instructions; condition; next iteration instruction) {...}

私は次のシーケンスを期待しています:

  1. 初期化命令が実行されます
  2. forループでコードを実行する
  3. 条件がfalse/0を返す場合は中断します。それ以外の場合は、次の反復命令を実行します。次に、2に進みます。

これは、forループが次の反復コードを実行する前に必ずしも条件をチェックしないことを示しています(C / C ++の場合のように)。ですから、forループの演算の順序について複数の考え方があるのか​​どうか知りたいです。そうでない場合、これは私が対処すべきより複雑な問題があることを私に教えてくれます。

ありがとう。

4

3 に答える 3

6

index最初のケースでは、forループ内でインクリメントしていますか?

for(self.item = [array objectAtIndex:index]; index < [array count]; self.item = [array objectAtIndex:index]) { 
    //do stuffs 
    index++;
} 

この場合、forループの3番目のセクションで構文が混乱し、設定self.item = [array objectAtIndex:index]した場所で例外がスローされます。これは、比較が行われる前にこの部分が実行されループからindex < [array count]抜け出すためです。 。

forループをこのように定義してみませんか?

for(self.item = [array objectAtIndex:index]; index < [array count]; index++) { 
        //do stuffs 
    } 

最初はCONDITIONが最初にチェックされますが、ループの各反復の最後にインクリメンターが実行されます。その時点で、INCREMENTER->CONDITION->loop_bodyになります。

これは、次と同等です。

initialize; 
while(condition) { 
    // do stuffs
    index++;
    LOOP_INCREMENTER; // this is your assignment statement, self.item = [array objectAtIndex:index]; 
} 
于 2012-04-28T05:08:51.707 に答える
2

ループがどのように機能するかについてのあなたの期待forは正しくありません。

for(initialization instructions; condition; next iteration instruction) {...}

シーケンスは次のとおりです。

1. initialization instructions
2. test condition, if condition is true do the following:
    2a. execute loop body
    2b. execute next iteration instruction
    2c. goto step 2

したがって、問題は、がindex == ([array count] - 1)、を評価するループ本体が実行されることindex++ですindex == [array count]

ループ本体が終了すると、「次の反復命令」は1つ大きすぎる[array objectAtIndex:index]と評価しようとします。indexこのステップは、ループ本体が実行された後、条件がテストされる前に行われることに注意してください。これが、Cが常にforループを処理してきた方法です。

代わりに、次のループを試してください。

for(; index < [array count]; ++index) {
    self.item = [array objectAtIndex:index];

    //do stuffs
}

もちろん、ループ本体indexの領域での既存の使用法を調整する必要がある場合もあります。//do stuffs

于 2012-04-28T06:43:24.123 に答える
-1

あなたが書いたコードはあなたが期待するものではありません。

配列を反復処理するには、for-inループを検討する必要があります。

for (MyObject* obj in array) {
   // do something with obj
   self.item = obj;
}

使用しているforループはいくつかの点で間違っており、配列の制限を超えている理由は(非常に)明らかです。

最後の有効なサイクルでインデックスを増やしていると、for-instructionはforの3番目の引数を実行します。

self.item = [array objectAtIndex:index]

その瞬間、条件(for-instructionの2番目の引数)が後で実行されるため、indexは配列の境界よりも大きくなります。

于 2012-04-28T07:26:41.437 に答える