- ベストアンサー
objective-cの多重ループbreak
objective-cの多重forループの内側でbreakすると外のforまで抜けるようです。 では、内側のforだけ抜けて外側のforの中に戻るにはどう書けばいいのでしょうか? あと、この件について、c言語とobjective-cの文法の違いについて教えていただけるとうれしいです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
プログラムの流れを見るなら、一行ずつではなく、ある程度の機能でわけて考えるといいでしょう。 for (int i=0; i<4; i++) { //乱数を発生 for (int j=i-1; j>=0; j--) { if (重複があったら) { i--; break; // →ループを抜け(a)へ } } // →ループを抜けた先(a) //イメージファイル名を作る } こうすれば、「イメージファイル名を作る」のは、重複があっても毎回実行されていることがわかりやすいと思います。 あとは、デバッガでのステップ実行とか、printf使うとかで、実行の流れと変数の中身を確認すればいいでしょう。 余談。 このシャフル、(疑似)乱数列によっては無限ループになる可能性もあります。 http://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E5%90%88%E5%90%8C%E6%B3%95#.E7.9F.AD.E6.89.80 そうでなくとも、何回もループする可能性があり、非効率的です。 「シャフル アルゴリズム」で検索するといろいろと出てます。 randomNumberに順番に記録されているのですから、「乱数を作りながらファイル名も作る」のではなく、乱数発生とファイル名作成を別のループにするのがよいでしょう。
その他の回答 (3)
- m-take0220
- ベストアンサー率60% (477/782)
breakしたときに、提示されたソースの > //イメージファイル名を作る > NSNumber *imageNumber = [NSNumber numberWithInt:randomNumber[i]]; > NSString *imageNumberString = [imageNumber stringValue]; > NSString *imageFileName = [@"image" stringByAppendingString:imageNumberString]; > selectedImageFile[i] = [imageFileName stringByAppendingString:@".jpg"]; の部分を処理するかどうかという話なら、処理するでしょう。 処理せずにループを続行したいなら、continueを使うなどする必要がありますから。 無駄な処理をしていると思うのであれば、回避するようにコードを書けばいいのです。 このソースを記述した人は、大したことじゃないと思ったか、そこまで考えが及ばなかっただけです。
- m-take0220
- ベストアンサー率60% (477/782)
> もしbreakが1個外へ抜けると仮定すると、内のforを抜ける→下の文に移る で1個前のiの処理がやり直されてしまうことになり、本の記述とくいちがう。 i--でiが1つ前に戻る ↓ breakで内側のforを抜ける ↓ 外側のforの最後まで行くのでfor文に記述されたi++が実行される ↓ 外側のfor内の処理が行われる なので、ループ変数iに細工をして、同じiに対する処理を繰り返させているものです。なので、「1個前のiの処理がやり直されてしまうことになり」ではありません。
補足
>breakで内側のforを抜ける >↓ >外側のforの最後まで行くので 確認したいのですが、breakの直後は//イメージファイル名を作る//イメージを表示をスルーするということですか? つまり、 ・for文が1つだけしかないプログラムの場合、単にそのforをストップし、抜けて直下の文へ移るだけ。 ・for文が2重のプログラムの場合、内のbreakで内のforをストップし、抜けた後、『内のfor直下にある文は外のforの最終行まですべてスキップし』、外のfor文を続ける。 でよろしいでしょうか?
- Tacosan
- ベストアンサー率23% (3656/15482)
え? いくらなんでもそんな仕様にはしないと思うけど.... どんなプログラムで試したんでしょうか?
補足
srand(time(nil)); NSString *selectedImageFile[4]; int randomNumber[4]; for (int i=0; i<4; i++) { //乱数を発生 randomNumber[i] = rand() % 4; for (int j=i-1; j>=0; j--) { if (randomNumber[j]==randomNumber[i]) { i--; break; } } //イメージファイル名を作る NSNumber *imageNumber = [NSNumber numberWithInt:randomNumber[i]]; NSString *imageNumberString = [imageNumber stringValue]; NSString *imageFileName = [@"image" stringByAppendingString:imageNumberString]; selectedImageFile[i] = [imageFileName stringByAppendingString:@".jpg"]; //イメージを表示 //ImageView0.image = [UIImage imageNamed:selectedImageFile[i]]; } //イメージを表示 ImageView0.image = [UIImage imageNamed:selectedImageFile[0]]; ImageView1.image = [UIImage imageNamed:selectedImageFile[1]]; ImageView2.image = [UIImage imageNamed:selectedImageFile[2]]; ImageView3.image = [UIImage imageNamed:selectedImageFile[3]]; 以上が該当部分のソースです。画像ソースが4つあってそれがかぶらないように処理をするプログラムだそうです。 i=0だと内のforは偽、i=1~3で内のforに入りますがそこのifが真だとi--されてその時点の乱数(i番目の乱数)を取得し直されると本に書かれています。 これを私が今想像している内容は、 もしbreakが1個外へ抜けると仮定すると、内のforを抜ける→下の文に移る で1個前のiの処理がやり直されてしまうことになり、本の記述とくいちがう。 もしbreakが2個外へ抜けると仮定すると、外のforを抜ける→下の文に移る で画像を4つ表示できなくなる。 …わからなくなってきました。 もしbreakが1個外へ抜けてその抜けた先がfor文の中の場合、for文をやり直す? …混乱しています。 いただいた回答をみるとどこか私の勘違いの可能性もありそうですね。 ifが真だった場合のbreakの行の後の挙動を教えてください。
補足
>このソースを記述した人は、大したことじゃないと思ったか、そこまで考えが及ばなかっただけです。 ソース自体は教本といえど十分なものはないと認識しています。が今回は、ソースの説明文の記述までも語弊があったのが災いしたようですね。 今回の例だと、 randomNumber[0] =2 1.selectedImageFile[0]に image2.jpg ● randomNumber[1] =2(重複) 2.selectedImageFile[0]に image2.jpg(1つ前までやり直す) randomNumber[1] =3 3.selectedImageFile[1]に image3.jpg ● randomNumber[2] =0 4.selectedImageFile[2]に image0.jpg ● randomNumber[3] =2(重複) 5.selectedImageFile[2]に image0.jpg(1つ前までやり直す) randomNumber[3] =1 6.selectedImageFile[3]に image1.jpg ● のようになり、重複が発生しようとすると、一つ前のi、つまりi-1の処理を、前回i-1を処理した通りに再度処理するところから始めるということですね。 ありがとうございました。すっきりしました。