WHILE文

本ページには広告が含まれています。

条件を満たしている(条件式がTrue)の間、ループ処理を行います。繰り返す回数がわかっている場合はFOR-TO文、条件を満たさなくても一度はループ内の処理を実行させる場合はREPEAT文を使います。

構文
WHILE 式
処理
WEND
引数
戻り値

前判定ループ

WHILE文のように処理を行う前に繰り返し処理を実行するかの条件判定を行う方式を前判定ループといいます。

ループの処理を行う前に判定を行うため、条件が成り立たなければループ内の処理は一度も実行されません。

対して、REPEAT文のようにループ内の処理を一度実行してから判定を行う方式を後判定といいます。

条件式の書き方

条件式は比較演算子または論理演算子を使って書きます。

値の比較

値の大小を比較する場合は比較演算子を使います。

WHILE文では条件が真の間、ループ内の処理が行われます。abには数値が代入されているものとします。

比較演算子とは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が等しくなければ真

i10未満の間、ループ内処理を実行します。

UWSC
DIM i = 1

WHILE i < 10
	PRINT i
	i = i + 1
WEND

i10以下の間、ループ内処理を実行します。

UWSC
DIM i = 1

WHILE i <= 10
	PRINT i
	i = i + 1
WEND

i0より大きい間、ループ内処理を実行します。

UWSC
DIM i = 10

WHILE i > 0
	PRINT i
	i = i - 1
WEND

i0以上の間、ループ内処理を実行します。

UWSC
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文を使います。

UWSC
DIM i = 1
WHILE i <= 5
	PRINT i + "回目の処理です"
	i = i + 1
WEND
結果
プレーンテキスト
1回目の処理です
2回目の処理です
3回目の処理です
4回目の処理です
5回目の処理です

処理の流れとしてはi1を代入し、WHILE文の条件式(i <= 5)が成り立つかを調べます。条件式のiの値を代入すると1 <= 515より小さいのが成り立つのでTrueを返します。条件式がTrueなのでループ内に入りWENDまでの処理を行います。

PRINT文で1回目の処理ですと出力し、iの値を+1します。

WENDまで来たらWHILEの行まで戻り、条件式の確認を行います。i <= 5iの値を代入すると2 <= 5となり、条件式が成り立つのでTrueを返し、再度ループ内の処理を行います。

これを条件式が成り立つ3、4、5回目も同様に繰り返します。

6回目は条件式が6 <= 5Falseとなり成り立たないので、ループ内の処理は行われずWENDの次まで処理が移ります。

カウンタ変数の宣言と初期化

WHILE文ではFOR文のように繰り返しをカウントするカウンタ変数の宣言や初期化は行われません。そのため、FOR文のような使い方をする場合は、自分で宣言、初期化する必要があります。

このときカウンタ変数の変数名に決まりはありませんが、iを使うのが慣習になっています。この理由としては世界で初めて開発されたプログラミング言語FORTRANで、変数名の先頭がi、j、k、l、m、nの場合デフォルトで整数型になるという暗黙のルールが由来となっています。カウンタ変数は整数なのでiがよく使われるということです。多重ループで既にi が使われている場合は、jk、…という風に使っていきます。

以下はFOR文でi1から5の間、処理を繰り返すプログラムです。カウンタ変数(以下ではi)の宣言と初期値の代入、ループ毎に加算する値の代入(STEPの部分)がFOR文内で行なえます。

UWSC
FOR i = 1 TO 5 STEP 1
	PRINT i + "回目の処理です"
NEXT
結果
プレーンテキスト
1回目の処理です
2回目の処理です
3回目の処理です
4回目の処理です
5回目の処理です

一方、WHILE文で同じ処理を書くと以下のようになります。カウンタ変数の宣言はWHILE文に入る前に用意しておく必要があり、ループ毎に加算する値の代入(i = i + 1の部分)も忘れずに記載する必要があります。

UWSC
DIM i = 1
WHILE i <= 5
	PRINT i + "回目の処理です"
	i = i + 1
WEND
結果
プレーンテキスト
1回目の処理です
2回目の処理です
3回目の処理です
4回目の処理です
5回目の処理です

以下のようにカウンタ変数の書き換えを忘れると、条件式の結果が変わらずTrueのままになるため無限ループとなってしまいます。

UWSC
DIM i = 1
WHILE i <= 5
	PRINT i + "回目の処理です"
WEND
結果
プレーンテキスト
1回目の処理です
1回目の処理です
1回目の処理です
1回目の処理です
1回目の処理です
(略)

無限ループ

ループを終了させる条件を満たすことが決してないため、抜け出すことがないループ構造のことを無限ループといいます。

以下のプログラムの場合、iがマイナス値になるとループを抜けるという条件ですが、ループ毎にiの値が増えているのでループを抜ける条件を満たすことはなく無限ループになります。

UWSC
DIM i = 1
WHILE i >= 0
	i = i + 1
WEND

この場合はUWSCのプログラムを強制終了するしかありません。タスクバーにあるUWSCのアプリから該当するスクリプトを閉じるか、タスクマネージャーから強制終了します。

WHILE文の条件にループ変数がないと無限ループになります。以下は条件にTRUEを指定した例。

UWSC
WHILE TRUE
	SLEEP(0.001)
WEND

この場合WHILE文の中にBREAK文などでループを抜ける処理を書く必要があります。

ループの入れ子(ネスト)

ループの入れ子とはループ処理の中に別のループ処理を入れることで、多重ループのことを指します。ネストともいいます。

以下はWHILE文の中にWHILE文を入れ子にして2数の積を求める例です。

カウンタ変数は必要に応じて、別の変数名で用意します。

UWSC
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の値を出力、i1を加算を繰り返すプログラムです。iの値が10になったときはWHILE文を抜けます。

WHILE文の条件式がTrueなので無限ループですが、i = 10のときにBREAK文を実行するのでループを抜けることができます。10でループを抜けているので、11以降の値は出力されません。

UWSC
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文で書き換えることもできます。以下も同じ結果を返します。

UWSC
FOR i = 1 TO 10
	PRINT i
NEXT
CONTINUE

CONTINUE文以降に記述した処理をスキップし、ループの開始位置に処理を移します。WHILE文では条件式が記述されている部分に処理が移ります。

こちらもBREAK文と同じで、毎回ではなくある条件に一致したときのみ実行することになるので、IF文(IF文またはIFB文)と併用することになります。毎回戻るのであればCONTINUE文以降の処理を記述する意味がなくなってしまいます。

以下はiの値が10未満の間、値を出力するプログラムです。iの初期値を1、ループ内に入ったらiの値を1加算し、iの値が5ならばループ開始位置に移ります。i5でなければループ内の処理を続け、PRINT文で値を出力します。

カウンタ変数の書き換えはCONTINUEよりも前に行います。CONTINUEよりも後に書くと条件式が変更されないため無限ループになってしまいます。

UWSC
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と記述します。初回はboolFalseなのでELSE節が実行されboolTrueが代入されますが、WHILE文の2回目以降はboolTrueが代入されているのでTHEN節が実行されます。

UWSC
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回目以降に実行
毎回実行
-----

関連記事

FOR-TO文
条件が真の間、処理を繰り返し実行します。途中でループを抜けたいときはBREAK文を使います。
FOR-IN文
配列やコレクションなどのグループの各要素に対して繰り返し処理を行います。
REPEAT文
REPEAT文では、条件式がTRUEになるまで処理を行います。WHILE文と同様処理を繰り返す回数がわからないときREPEAT文を使います。ループ内で条件式の変数の値を変えないと無限ループとなるので注意が必要です。 REPEAT文は後判定でループ内の処理を実行してから条件式の確認を行うので、最低一度は処理が実行されます。