Weitere ähnliche Inhalte
Mehr von XMLProJ2014 (20)
Hinweis der Redaktion
- ここからプログラムの動きが多少複雑になってくる
覚えることは少ないけれど、流れをきちんと追えるよう、頭を使う
- 条件式がtrueである限り、処理を繰返し続けるので、whileの中で条件式に何らかの影響を与えていかないと、いわゆる「無限ループ」に陥る
逆に言えば、whileで無限ループが作れる。たまにやる。
そういうときはswitch文で使ったbreakが役立つ
breakは{}から抜け出す命令
- 形は何となく似てる
でも「繰り返す」ので、プログラムの動きはちょっと複雑
- フローチャート:プログラムの流れを図で示したもので、決まった書き方や図の使い方がある。結構使われるけど複雑なものではなく、詳しくなくても何となくわかるので何かと便利。
whileが開始されると、まず条件式の判定
trueなら処理が行われ、falseなら終わる
判定→処理の流れが、falseになるまで繰り返される
そのため、条件式が最初からfalseだった場合、処理を行わずに終了する
- 条件式の判定に関わらず、最低でも1回は処理を必ず行ってほしい、という場合に使える
最後に「;」をつけなければならないことに注意
- do-whileが開始されると、まず処理が行われる
そのあとに条件式の判定が行われ、trueならもう一度処理、falseなら終わる
whileでは判定→処理の流れだったが
do-whileでは処理→判定の流れなので、確実に一度は処理が行われる
- 0から始まって1ずつ増えていくので0~9の10回であることに注意
- 10回繰り返すために使う
変数、条件、処理
がバラバラになっている
今は短くてシンプルだからいいけど、もっと複雑なプログラムになってくると、わかりにくい
- 初期化:繰り返しの軸となる変数を作る
繰り返し条件:処理をするかどうか、初期化した変数を基準に判定するための条件式
繰り返し時の処理:繰り返す処理が行われた後、繰り返し条件に影響を与えるような変化を初期化した変数に与える
いまいちピンとこないかもしれないので、whileで見てみる
- 初期化:繰り返しの軸となる変数を作る
繰り返し条件:処理をするかどうか、初期化した変数を基準に判定するための条件式
繰り返し時の処理:繰り返す処理(今回はsysoutで文字列を出力)が行われた後、繰り返し条件に影響を与えるような変化を初期化した変数に与える
これらをforにしてみると
- 初期化:繰り返しの軸となる変数を作る
繰り返し条件:処理をするかどうか、初期化した変数を基準に判定するための条件式
繰り返し時の処理:繰り返す処理(今回はsysoutで文字列を出力)が行われた後、繰り返し条件に影響を与えるような変化を初期化した変数に与える
ちなみに、「i」というのも変数だから名前はなんでもいい。繰り返しの基準にするだけだから適当に1文字でもいい、という感じなだけ
ただし、この「初期化」「繰り返し条件」「繰り返し時の処理」の説明はあくまで「基本的にはこういうもの」というだけ
- 「初期化」、「繰り返し条件」、「繰り返し時の処理」の基本的な役割を全て無視して、こんなことをしても大丈夫
初期化:「i」は繰り返しの軸になってない
繰り返し条件:初期化した変数使ってない
繰り返し時の処理:繰り返し条件に影響を与えない
今回は全く無意味なものだが、場合によっては、あえて無視することで良くなることもある
要するに、基本的な書き方だけでなく、色々と手を加えて柔軟な処理が行えることも覚えておこうという話
- 実行結果はjが10で初期化されているので、もちろん「何も表示されない」
- 左上から始まり、右下で終わる
同じ色の丸へ繋がっている
「初期化」はforの最初に1回だけ実行される
「繰り返し条件」は「繰り返す処理」の前。forでは、do-whileのように後で判定することはできない。
「繰り返し時の処理」は「繰り返す処理」が終わった後に実行される。
- さっきまでは0から1ずつ増えていたが、減らしていくことももちろんできる
- 10から始まり、変数「i」の値を出力した後、2ずつ減らされている
- 全く意味がないけれど、whileっぽく書くことだってできる
「初期化」と「繰り返し時の処理」が省略され、それぞれ別の場所に書かれている
ちなみに、「初期化」「繰り返し条件」「繰り返し時の処理」の3つすべてを省略して、2つの「;」だけを書くと、while(true)のときと同じように無限ループになる
- さりげなく使っている「i」だが、使える範囲は限られている
10回繰り返した後、最後に「10回繰り返した」と出力しようと思って、「i」を使おうとした
forの中なら何も言われないけど、forの外だと赤い波線が引かれる
- 赤い波線が引かれた状態で実行すると、このようにエラーが出る
「iを変数に解決できません」とはつまり、「iなんて名前の変数は存在しないので使えない」ということ
⇒「i」(forの最初で初期化した変数)はforの中でしか使えない!
実は、今まで使ってきた普通の変数にも、「使える範囲」というものが存在する
- ブロックという新しい単語が出てきたが、なんてことはない、「{}」の中、という意味
詳しくは次のページ
- 分かり易いifで考える
変数numを用意して、それが0のときはifの中に入り、sumという変数を用意して、sumの値ぶんnumに足す。最後に、sumぶん足した結果numはどれくらいになったかを出力しようとした
赤い枠はmainのブロック、水色の枠はifのブロック
変数numはmainのブロックに所属しているため、消滅するのはmainの「}」の後
しかし変数sumはifのブロックに所属しているため、消滅するのはifの「}」の後
そのあとでsumを使おうとしても、消滅してしまっているから使えない、ということ
- forの場合、「i」は一見、forのブロックには所属していないように見えるが、フローチャートにも書いたように、この「i」はforの処理が開始された後に作られる。そのため、厳密にはブロックに入っていないものの、スコープはforが終わるまで、となっている。
- ifとforしか出てないけど、もちろんswitchやwhileでもOK
これはもう見た方が早い
- numが0なら、10回、2を足す
- numが0なら、canSumがtrueのときインクリメント、falseならデクリメント
- 5回繰り返すうち、iが0のときとそうでないときで出力が変わる
- 「i」を使うforの繰り返しを行う中で、「j」を使うforの繰り返しが行われる
⇒3×3=9
- 「i」を使うforの繰り返しを行う中で、「j」を使うforの繰り返しが行われる
⇒「i」は3回しか出てこないが、「i」1回ごとに「j」は3回繰り返されるので、「j」は9回出てくる。
- ifを7つ連ねてみた。この状態でもパッと見で何個あるか見辛いのに、さらに条件式とか処理とかが入ってくるとなると、とんでもない見辛さになる。
⇒ネストを深くすることは極力避ける。これもまた、見やすいソースコードを作るため。
- forやwhileから途中で抜け出す方法が、2つある
- switchでも使ったbreakという命令は、そのbreakを囲んでいる最も内側の繰り返しブロックから抜け出す、というもの
これを使えば無限ループからでも簡単に抜けられる
使い方は「break;」と書くだけ
- forの2重ループになっている
さらに「j」を使うforは100回も繰り返すことになっている!
が、「j」を使うforに入って文字列を出力した後にすぐbreakが入る
このbreakを囲んでいる最も内側の繰り返しブロックは「j」を使うfor
なので、結局「すぐ脱出」と5回出力されて終わる
- continueは「今の周回を中断して、同じ繰り返しの次の周回に進む」
breakはブロックから一気に抜け出してしまったが、continueはその周回だけを中断させる
使い方はbreakと同じでただ書くだけ
- 最初、「i」が0のときはifに入らないので「0回目」と出力されるが、そのあと、「i」の値がインクリメントされるとifの中に入るようになり、その都度continueにより中断されてsysoutまでたどり着けないので、それ以降はforが終わるまで何も出力されない