繰り返し処理
繰り返し処理は、読んで字のごとく、同じ処理を繰り返し実行したい場合に使います。
繰り返し処理は、「ループ」とも呼ばれます。
ここでは、「while文」と「for文」を使った「繰り返し処理」を具体的に見ていきましょう。
目次
1. 繰り返し処理
繰り返し処理には、「while文」または「for文」を使います。
1-1. while文
while文には「ブロック実行条件式」を指定します。
while( ブロック実行条件式 ) {
実行ブロック
}
この「ブロック実行条件式」が「真」の間、whileのブロック内が実行され続けます。
下は、whileを使って変数「i」の内容を5回繰り返し表示しています。
let i=0
while( i < 5 ) {
print( i + "\n" )
i = i + 1
}
1
2
3
4
繰り返し処理(ループ)には、「ブロック実行条件式」を指定しなければなりません。
上の例では、「i < 5」が「ブロック実行条件式」です。
これは、変数「i」の値が、5より小さければ、whileブロック内が実行されるということです。
ブロック内の「i = i + 1」は、ブロック内が実行されるたびに、変数「i」に「1」を足して「i」の値を更新しています。
変数に1ずつ足し込んでくことを「インクリメント」とか「カウントアップ」などと呼んだりします。
(「i=i+1」は短縮した形で「i++」と書くことが多いです。)
ループのたびに「i」をインクリメントすることによって「ブロック実行条件」を更新していると言えます。
(ブロック実行条件式を適切に更新しないと、無限ループになってしまう!)
下はループのイメージです。
ループのたびに、「i」の値が増えていき、それまで「真」だった「ブロック実行条件」が、やがて「偽」となります。
「ブロック実行条件」が「真」の間はブロック内が実行され、「偽」となった時点でループが終わります。
ループ1回目
while( i < 5 ) { i=0 真(true)
実行される
i=i+1
}
ループ2回目
while( i < 5 ) { i=1 真(true)
実行される
i=i+1
}
ループ3回目
while( i < 5 ) { i=2 真(true)
実行される
i=i+1
}
ループ4回目
while( i < 5 ) { i=3 真(true)
実行される
i=i+1
}
ループ5回目
while( i < 5 ) { i=4 真(true)
実行される
i=i+1
}
ループ6回目
while( i < 5 ) { i=5 偽(false)
実行されない!!
i=i+1
}
ループのたびに、iの値が更新されていき、iが5になるとブロック実行条件「i < 5」の評価が「偽」になりループが終了します。
ちなみに、ループの処理が終わることを「ループから抜ける」などと言ったりします。
1-2. for文
「for文」も繰り返し処理に使われます。
for( let 変数=初期値; ブロック実行条件式; 変数増分 ) {
実行ブロック
}
下のプログラムを実行してみてください。
先ほどのwhile文の例と同じことをしています。
for( let i=0; i<5; i++ ) {
print( i + "\n" );
}
1
2
3
4
for文は、ループに必要な「変数宣言」と「ブロック実行条件」と「変数増分」を「;(セミコロン)」で区切って同時に指定します。
for文のカッコ内左から、「let i=0」でループに使用する変数を宣言して初期値に「0」を代入しています。
次に、ブロック実行条件に「i < 5」を、
最後に、iの値を更新するために「i++(i=i+1と同じ意味)」を設定しています。
結果、iの値は0からスタートして、ループのたびに、1が足された値に更新されます。
要するに、iの値はループのたびに「0,1,2,3,4,5...」と更新されていきます。
while文と同じように、ブロック実行条件式「i < 5」が「真」の間は、ブロック内が実行され、「偽」になった時点でループから抜けます。
1-3. 入れ子のループ
ループは入れ子(ネスト)にすることもできます。
ループの中に、ループを作るということです。
下は、外側のforループと内側のforループともに3回ループするプログラムです。
for(let x=0; x<3; x++) {
print("x(外)=" + x + "\n")
for(let y=0; y<3; y++) {
print("y(内)=" + y + "\n")
}
}
y(内)=0
y(内)=1
y(内)=2
x(外)=1
y(内)=0
y(内)=1
y(内)=2
x(外)=2
y(内)=0
y(内)=1
y(内)=2
ループを入れ子(ネスト)にすると、外側のループ1回ごとに、内側のループ動作します。
この例の場合、外側のループ1回ごとに、内側のループが3回実行されます。
上の結果から外側1回分のループを抜き出すと、下のように外側1回のループにつき、内側が3回ループされているのがわかります。
内側1回目「y(内)=0」
内側2回目「y(内)=1」
内側3回目「y(内)=2」
内側3回目のループが終わると、外側2回目のループに突入します。
外側2回目のループに突入すると、内側のループはリセットされてまた3回ループします。
内側1回目「y(内)=0」
内側2回目「y(内)=1」
内側3回目「y(内)=2」
内側3回目のループが終わると、外側3回目のループに突入します。
外側3回目のループに突入すると、内側のループはリセットされてまた3回ループします。
内側1回目「y(内)=0」
内側2回目「y(内)=1」
内側3回目「y(内)=2」
内側3回目のループが終わると、外側のループも3回目を終えるので、ようやく全てのループが終了します。
文章で書くとややこしくていやになりますが、入れ子のループはごく普通に利用されるものです。
実際にプログラムを動かして動作を確認すれば、すぐに慣れてしまうと思います。
1-4. 無限ループに注意
無限ループとは、「ブロック実行条件式」に間違いがあるなどして、永久にループが終わらなくなることを言います。
例えば、下は「無限ループ」の例です。
「i」の値の更新を忘れている!(i=i+1がない!)
let i=0
while( i < 5 ) {
print( i + "\n" )
// i=i+1がない!!
}
iの更新をしていないので、常にブロック実行条件「i < 5」が「真(true)」となり、一生ループから抜けることができません!
この場合、printが無限に実行され続け、コンピュータが応答不能になってしまいます。
(固まるとか、重くなるとか言ったりします)
もし、ループ処理を試していて「無限ループ」になってしまったら、砂場JSを終了(ブラウザを閉じること)させてください。
再度、砂場JSを立ち上げれば、復帰することができます。
1-5. ループを強制的に終わらせる
ループ内で、「break」を使うとループを途中で抜けることができます。
下は、無限ループするwhile文です。「break」でループから脱出します!
プログラムを実行してみてください。
while( true ) {
print( "無限ループ突入\n" )
break
}
print( "無限ループから抜けました" )
下は、100万回ループするfor文ですが、iの値が3になったら「break」しています。
for(let i=0; i<1000000; i++) {
print( i + "\n" )
if( i == 3 ) {
break
}
}
print( "ループから抜けました" )
注意点としては、「break」は、「対象のループから抜ける」ということです。
例えば、入れ子になっているループでは、「break」が指定されている内側のループは抜けますが、外側のループは抜けません。
for(let x=0; x<3; x++) {
print("x(外)=" + x + "\n")
for(let y=0; y<3; y++) {
print("y(内)=" + y + "\n")
break
}
}
「break」が指定されている内側のforループは、1回で抜けていますが、外側のforループはしっかり3回ループしています。
y(内)=0
x(外)=1
y(内)=0
x(外)=2
y(内)=0
結果を見ると、内側のyはループ1回目の「0」のみですが、外側のxは「0~2」に変化しています。
外側、内側のループを1回で抜けるには、下のように、両方のforループに「break」が必要です。
for(let x=0; x<3; x++) {
print("x(外)=" + x + "\n")
for(let y=0; y<3; y++) {
print("y(内)=" + y + "\n")
break
}
break
}
y(内)=0
1-6. ループを強制的に次に進める
ループ内で「continue」を使うと、ループ途中で次のループに進めることができます。
下は、5回ループするfor文です。
ループのたびにiの値を表示しますが、i=3の時のみ「continue」でループを次に進めています。
ループを次に進められてしまったので、「3」のみ表示されません。
for(let i=0; i<5; i++) {
if( i == 3 ) {
continue
}
print( i + "\n" )
}
1
2
4
こちらも、「break」のときと同じように、「対象のループ」にしか「continue」が効きませんので注意してください。
for(let x=0; x<3; x++) {
print("x(外)=" + x + "\n")
for(let y=0; y<3; y++) {
if( y == 1 ) {
continue
}
print("y(内)=" + y + "\n")
}
}
「continue」が指定されている内側のforループは、1が表示されませんが、外側のforループはしっかり「1~3」までが表示されている。
y(内)=0
y(内)=2
x(外)=1
y(内)=0
y(内)=2
x(外)=2
y(内)=0
y(内)=2
外側、内側のループそれぞれの値が1の時のみループを進めたければ、下のように、両方のforループに「continue」が必要です。
for(let x=0; x<3; x++) {
if( x == 1 ) {
continue
}
print("x(外)=" + x + "\n")
for(let y=0; y<3; y++) {
if( y == 1 ) {
continue
}
print("y(内)=" + y + "\n")
}
}
y(内)=0
y(内)=2
x(外)=2
y(内)=0
y(内)=2
2. おわりに
whileとfor文、どちらを使えばいいのかは、ケースバイケースです。
for文は、ループに関する条件を一度に指定するので、無限ループになることは少ないと思います。
個人的には、配列などを取り扱う単純なループはfor文、複雑なブロック実行条件が必要な場合は、while文を多く使っています。
いずれにしても、繰り返し処理(ループ)を書く際は、「無限ループ」にならないよう注意が必要です。
3. 試してみよう
while文、for文を使って、10回ループするプログラムを作ってください。
ループするたびに、「こんにちは」と表示してください。
3-1. 答え例
while文の場合
let i=0
while( i<10 ) {
print("こんにちは\n")
i++
}
for文の場合
for(let i=0; i<10; i++) {
print("こんにちは\n")
}
4. まとめ
繰り返し処理は、ループとも言います。
繰り返し処理には、while文、for文を使います。
繰り返し処理には、繰り返し(ループ)の終了条件が必要です。
終了条件に間違いなどがあると、無限ループになるので注意が必要です。
ループ内でbreakを使うと、強制的に対象ループから抜けることができます。
ループ内でcontinueを使うと、強制的に対象ループを次に進めることができます。
繰り返し処理については、以上です。
次は、「関数」についてです。