目次
条件を満たしている(条件式がTrue)の間、ループ処理を行います。繰り返す回数がわかっている場合はFOR-TO文、条件を満たさなくても一度はループ内の処理を実行させる場合はREPEAT文を使います。
- 構文
- WHILE 式
処理WEND
- 引数
- 戻り値
前判定ループ
WHILE文のように処理を行う前に繰り返し処理を実行するかの条件判定を行う方式を前判定ループといいます。
ループの処理を行う前に判定を行うため、条件が成り立たなければループ内の処理は一度も実行されません。
対して、REPEAT文のようにループ内の処理を一度実行してから判定を行う方式を後判定といいます。
条件式の書き方
条件式は比較演算子または論理演算子を使って書きます。
値の比較
値の大小を比較する場合は比較演算子を使います。
WHILE文では条件が真の間、ループ内の処理が行われます。a、bには数値が代入されているものとします。
比較演算子とは2つの式や値を比較するための演算子で、2つの値が等しい・等しくない、大きい・小さいといった比較ができるようになります。
比較演算子を使うことで、○○と一致したときや○○ではないときといった条件式を書くことができます。
UWSCで使える比較演算子は以下のとおりで、a,bはともに数値が代入されているものとします。
演算子 | 記述例 | 意味 |
---|---|---|
< | a < b | aがbより小さければ真 |
<= | a <= b | aがb以下ならば真 |
> | a > b | aがbより大きければ真 |
>= | a >= b | aがb以上ならば真 |
= | a = b | aとbが等しければ真 |
<> | <> b | aとbが等しくなければ真 |
例
iが10未満の間、ループ内処理を実行します。
DIM i = 1
WHILE i < 10
PRINT i
i = i + 1
WEND
iが10以下の間、ループ内処理を実行します。
DIM i = 1
WHILE i <= 10
PRINT i
i = i + 1
WEND
iが0より大きい間、ループ内処理を実行します。
DIM i = 10
WHILE i > 0
PRINT i
i = i - 1
WEND
iが0以上の間、ループ内処理を実行します。
DIM i = 10
WHILE i >= 0
PRINT i
i = i - 1
WEND
複数条件
複数の条件を指定したい場合は、論理演算子を使います。
以下の例ではa,bともに論理値(TrueまたはFalse)が代入されているものとします。数値の場合はビット演算になるので注意が必要です。
論理演算子とは、論理演算をするための演算子のことで、論理演算子を使うことで○○かつ○○、○○または○○といった比較演算子だけではできない複数の条件式を比較するといった書き方ができるようになります。
以下の例ではa,bともに論理値(TrueまたはFalse)が代入されているものとします。数値の場合は論理演算ではなくビット演算になるので注意が必要です。
演算子 | 記述例 | 意味 |
---|---|---|
AND | a AND b | aとbがともに真の場合に真 |
OR | a OR b | aかbの少なくとも1つが真の場合に真 |
XOR | a XOR b | aかbのいずれか一方が真の場合に真 |
! | !x | xが偽の場合に真 |
WHILE文の使い方
WHILE文とは
WHILE文では、条件式がTrueの間繰り返し処理を行います。FOR文とは違い繰り返す回数がわからないときや条件が成り立つ間というときはWHILE文を使います。条件式が成り立たない場合は一度も実行されずにWEND直後まで処理が移ります。ループ内で条件式の変数を変える、もしくはBREAK文を記述しないと無限ループとなるので注意が必要です。
WHILE文は前判定でループに入る前に条件式の確認を行うので、Falseの場合ループ内の処理が一度も実行されずに処理が進みます。ループ内の処理を必ず一度は実行したい場合は、後判定のREPEAT文を使います。
DIM i = 1
WHILE i <= 5
PRINT i + "回目の処理です"
i = i + 1
WEND
- 結果
1回目の処理です 2回目の処理です 3回目の処理です 4回目の処理です 5回目の処理です
処理の流れとしてはiに1を代入し、WHILE文の条件式(i <= 5)が成り立つかを調べます。条件式のiの値を代入すると1 <= 5で1が5より小さいのが成り立つのでTrueを返します。条件式がTrueなのでループ内に入りWENDまでの処理を行います。
PRINT文で1回目の処理ですと出力し、iの値を+1します。
WENDまで来たらWHILEの行まで戻り、条件式の確認を行います。i <= 5にiの値を代入すると2 <= 5となり、条件式が成り立つのでTrueを返し、再度ループ内の処理を行います。
これを条件式が成り立つ3、4、5回目も同様に繰り返します。
6回目は条件式が6 <= 5でFalseとなり成り立たないので、ループ内の処理は行われずWENDの次まで処理が移ります。
カウンタ変数の宣言と初期化
WHILE文ではFOR文のように繰り返しをカウントするカウンタ変数の宣言や初期化は行われません。そのため、FOR文のような使い方をする場合は、自分で宣言、初期化する必要があります。
このときカウンタ変数の変数名に決まりはありませんが、iを使うのが慣習になっています。この理由としては世界で初めて開発されたプログラミング言語FORTRANで、変数名の先頭がi、j、k、l、m、nの場合デフォルトで整数型になるという暗黙のルールが由来となっています。カウンタ変数は整数なのでiがよく使われるということです。多重ループで既にi が使われている場合は、j、k、…という風に使っていきます。
以下はFOR文でiを1から5の間、処理を繰り返すプログラムです。カウンタ変数(以下ではi)の宣言と初期値の代入、ループ毎に加算する値の代入(STEPの部分)がFOR文内で行なえます。
FOR i = 1 TO 5 STEP 1
PRINT i + "回目の処理です"
NEXT
- 結果
1回目の処理です 2回目の処理です 3回目の処理です 4回目の処理です 5回目の処理です
一方、WHILE文で同じ処理を書くと以下のようになります。カウンタ変数の宣言はWHILE文に入る前に用意しておく必要があり、ループ毎に加算する値の代入(i = i + 1の部分)も忘れずに記載する必要があります。
DIM i = 1
WHILE i <= 5
PRINT i + "回目の処理です"
i = i + 1
WEND
- 結果
1回目の処理です 2回目の処理です 3回目の処理です 4回目の処理です 5回目の処理です
以下のようにカウンタ変数の書き換えを忘れると、条件式の結果が変わらずTrueのままになるため無限ループとなってしまいます。
DIM i = 1
WHILE i <= 5
PRINT i + "回目の処理です"
WEND
- 結果
1回目の処理です 1回目の処理です 1回目の処理です 1回目の処理です 1回目の処理です (略)
無限ループ
ループを終了させる条件を満たすことが決してないため、抜け出すことがないループ構造のことを無限ループといいます。
以下のプログラムの場合、iがマイナス値になるとループを抜けるという条件ですが、ループ毎にiの値が増えているのでループを抜ける条件を満たすことはなく無限ループになります。
DIM i = 1
WHILE i >= 0
i = i + 1
WEND
この場合はUWSCのプログラムを強制終了するしかありません。タスクバーにあるUWSCのアプリから該当するスクリプトを閉じるか、タスクマネージャーから強制終了します。
WHILE文の条件にループ変数がないと無限ループになります。以下は条件にTRUEを指定した例。
WHILE TRUE
SLEEP(0.001)
WEND
この場合WHILE文の中にBREAK文などでループを抜ける処理を書く必要があります。
ループの入れ子(ネスト)
ループの入れ子とはループ処理の中に別のループ処理を入れることで、多重ループのことを指します。ネストともいいます。
以下はWHILE文の中にWHILE文を入れ子にして2数の積を求める例です。
カウンタ変数は必要に応じて、別の変数名で用意します。
DIM i = 1
WHILE i <= 5
DIM j = 1
WHILE j <= 3
PRINT i + "×" + j + "=" + (i * j)
j = j + 1
WEND
i = i + 1
WEND
- 結果
1×1=1 1×2=2 1×3=3 2×1=2 2×2=4 2×3=6 3×1=3 3×2=6 3×3=9 4×1=4 4×2=8 4×3=12 5×1=5 5×2=10 5×3=15
ループを制御
ループ処理の流れを変えたいときにはBREAK文、CONTINUE文を使います。
BREAK
BREAK文以降に記述した処理をスキップし、ループを終了します。WHILE文ではWENDの直後に処理が移ります。
ある条件のときに抜けるという書き方をするのでIF文(IF文またはIFB文)と併用するのが普通です。
以下はiの値を出力、iに1を加算を繰り返すプログラムです。iの値が10になったときはWHILE文を抜けます。
WHILE文の条件式がTrueなので無限ループですが、i = 10のときにBREAK文を実行するのでループを抜けることができます。10でループを抜けているので、11以降の値は出力されません。
DIM i = 1
WHILE TRUE
PRINT i
IF i = 10 THEN BREAK
i = i + 1
WEND
- 結果
1 2 3 4 5 6 7 8 9 10
この場合はFOR文で書き換えることもできます。以下も同じ結果を返します。
FOR i = 1 TO 10
PRINT i
NEXT
CONTINUE
CONTINUE文以降に記述した処理をスキップし、ループの開始位置に処理を移します。WHILE文では条件式が記述されている部分に処理が移ります。
こちらもBREAK文と同じで、毎回ではなくある条件に一致したときのみ実行することになるので、IF文(IF文またはIFB文)と併用することになります。毎回戻るのであればCONTINUE文以降の処理を記述する意味がなくなってしまいます。
以下はiの値が10未満の間、値を出力するプログラムです。iの初期値を1、ループ内に入ったらiの値を1加算し、iの値が5ならばループ開始位置に移ります。iが5でなければループ内の処理を続け、PRINT文で値を出力します。
カウンタ変数の書き換えはCONTINUEよりも前に行います。CONTINUEよりも後に書くと条件式が変更されないため無限ループになってしまいます。
DIM i = 0
WHILE i < 10
i = i + 1
IF i = 5 THEN CONTINUE
PRINT i
WEND
- 結果
1 2 3 4 6 7 8 9 10
WHILE文内の一部を2回目以降のみ実行
WHILE文内で初回は実行せず2回目以降にのみ実行したい処理がある場合、IFB文で処理分けをすることで記述することができます。まずWHILE文の前にboolを宣言しFalseを代入します。WHILE文の中で2回目以降にのみ実行したい処理の箇所にIFB文を記述します。条件式にはboolと記述します。初回はboolがFalseなのでELSE節が実行されboolにTrueが代入されますが、WHILE文の2回目以降はboolにTrueが代入されているのでTHEN節が実行されます。
SETHOTKEY(VK_ESC, EMPTYPARAM, "forceQuit")
DIM bool = FALSE
WHILE TRUE
IFB bool THEN
PRINT "2回目以降に実行"
ELSE
bool = TRUE
ENDIF
PRINT "毎回実行"
PRINT "-----"
SLEEP(1.000)
WEND
//////////////////////////////////////////////////
// 【引数】
//
// 【戻り値】
//
//////////////////////////////////////////////////
PROCEDURE forceQuit()
EXITEXIT
FEND
- 結果
毎回実行 ----- 2回目以降に実行 毎回実行 ----- 2回目以降に実行 毎回実行 ----- 2回目以降に実行 毎回実行 -----