第4章 制御文

プログラムを作るために欠かせない文法,制御文について説明します.

if elseによる条件分岐

if else構文(英語でifはもし〜だったら,elseはそうでなかったら,という意味) は, 条件分岐をする際に使用する構文です.

if elseの書き方

if ( 条件式) then
    条件式が真であるときの処理
else
    条件式が偽であるときの処理
end

条件式にはカッコが無くても困ません.

では,実際にif else構文を使ってみましょう.

ここでテストの成績を判定するプログラムを作ってみましょう. もし点数が60点以上であったら合格を, そうでなかったら不合格を表示するプログラムを作ります.

result = 70
if result >= 60 then
    print("合格")
else
    print("不合格")
end

実行結果

合格

resultが60以上であるかを比較する際には,関係演算子``>=``を使用します.

elseは書かなくてもかまいません.

hoge = 10
if ( hoge == 10 ) then
    print("Hello world")
end

このプログラムはhogeが10と等しい時にだけ Hello worldを出力します.

ここで注意して欲しいのは, hogeが10と等しいと判定する場合, hoge = 10 ではなく,hoge == 10 であるということです.

また,条件を複数書きたい場合,次のように書きます.

hoge = 8

if( hoge == 10 ) then
--A の処理
elseif( hoge == 9) then
--B の処理
elseif( hoge == 8 ) then
--C の処理
else
--D の処理
end

第2,第3の判定を付けたい場合,elseifを使用します. この場合Cの処理が実行されることになります. ここでもしhogeが9であるならばBの処理が行われますし,6ならばDの処理が実行されることになります.

偽条件の判定

さて,次のようなコードを書いたらどのような実行結果となるでしょうか.

hoge = 1
if ( hoge ) then
   print("first")
end

hoge = 0
if ( hoge ) then
   print("second")
end

hoge = false
if ( hoge ) then
   print("third")
end
hoge = nil
if ( hoge ) then
   print("fourth")
end

実行結果

first
second

カッコの中には何か式を書かなくてはなりませんが, この場合は変数名のhogeとしか書いてありません.これはどういう意味でしょうか.

実はこういった場合,カッコの中の値がfalse,nilであるかfalse,nil以外であるかで判定します. false,nilでない場合は処理を行い,そうでない場合は処理を行いません.

関係演算子

2つの変数を比較して,式が正しいか誤りかを求める時に使う演算子を関係演算子といいます. 例えばTable4.1のようなものが存在しています.

Table4.1: 関係演算子

x <  y xがyより小さかったら真 そうでなかったら偽
x >  y xがyより大きかったら真 そうでなかったら偽
x <= y xがy以下であれば真 そうでなかったら偽
x >= y xがy以上であれば真 そうでなかったら偽
x == y xがyと等しければ真 そうでなかったら偽
x ~= y xがyと等しくなければ真 そうでなかったら偽

whileによる繰り返し

while文の書式

while ( 条件式) do
処理
end

条件式にはカッコが無くてもかまいません.

繰り返し処理を行いたい場合はwhile構文を使います. 条件式が真の場合,処理が繰り返し行われます.

たとえばHello worldと10回表示する プログラムをwhileを使って作ってみます.

i = 1
while i <= 10 do
  print ( i .. "回目:Hello world!" )
  i = i + 1
end

実行結果

1 回目:Hello world!
2 回目:Hello world!
3 回目:Hello world!
4 回目:Hello world!
5 回目:Hello world!
6 回目:Hello world!
7 回目:Hello world!
8 回目:Hello world!
9 回目:Hello world!
10 回目:Hello world!

条件式はifと同じです. ifと同じということは次のようなコードを書いた場合どうなるでしょうか.

while true do
    print ( "Hello world!" )
end

これは,条件は常に真ということになります. つまり無限ループに陥ります.

forによる繰り返し

for構文にはNumeric forとGeneric forの2種類が存在します.Generic forは難しいので,また後の章で説明することとします. ここではNumeric forについて説明していきます.

Numeric forもwhile同様繰り返しの処理を行う場合に使用します. ただし,whileとは違い,終了条件が数値でしか指定できません.

書式

for 初期値, 終了値, 増加量do
    処理
end

増加量は省略することができます. その場合,自動的に増加量は1となります.

前節で登場したHello worldを10回表示するプログラムをfor を使って書き直すと次のようになります.

for i = 1, 10, 1 do
    print( i .. "回目:Hello world!")
end

iが1で始まり,iが10になるまで,iを1ずつ増加させていきます. つまり,iが10以下の場合に繰り返しが行われます.

実行結果

1 回目:Hello world!
2 回目:Hello world!
3 回目:Hello world!
4 回目:Hello world!
5 回目:Hello world!
6 回目:Hello world!
7 回目:Hello world!
8 回目:Hello world!
9 回目:Hello world!
10 回目:Hello world!

増加量は省略することができます. その場合は,自動的に1が割り当てられます.

for i = 1, 10 do
    print( i .. "回目:Hello world!")
end

実行結果は先ほどと同じです. 増加量を4に変更してみましょう.どのような実行結果となるでしょうか.

for i = 1, 10, 4 do
    print( i .. "回目:Hello world!")
end

実行結果

1 回目:Hello world!
5 回目:Hello world!
9 回目:Hello world!

forを使う上で注意しなければならないことがあります. それは,初期値で定義した変数(ループ変数)は for文の中でのみ有効だということです. つまり,forを抜けた時点でループ変数は消滅してしまいます.

例えば次のようなコードを書いたとします.

for i = 1, 10, 4 do
    print( i .. "回目:Hello world!")
end
if i == nil then
    print ("i は定義されていません")
end

for文で使用しているiとif文で使用しているiは別物です.

実行結果は以下のようになります.

実行結果

1 回目:Hello world!
5 回目:Hello world!
9 回目:Hello world!
i は定義されていません

iは定義されていないので,nilとなっています.

repeatによる繰り返し

repeatを使ってループを行うこともできます.

repeatはwhileと違い,repeat内の処理は最低1回は必ず行われます.処理を行ったあと,条件式を判定し, 条件が真の場合,ループが終了します.

書式

repeat
    処理
until (条件式)

条件式が偽の場合,処理が繰り返し行われます. 真の場合ではないので注意してください.

i = 1
repeat
print (i .. "回目:Hello world!")
i = i + 1
until ( i >= 5 )

実行結果

1 回目:Hello world!
2 回目:Hello world!
3 回目:Hello world!
4 回目:Hello world!

breakを使ったループの脱出

繰り返し処理を実行している間にbreak文を使うと, いつでもループから脱出することができます. 例えば次のようなプログラムを書いたとします.

for i = 0, 10 do
    print( "i の値:" .. i )
    if ( i == 5 ) then
        break
    end
end
print("脱出")

実行結果

i の値:0
i の値:1
i の値:2
i の値:3
i の値:4
i の値:5
脱出

breakは必ずブロックの最後でしか使うことができません. ブロックの最後とは,具体的に以下のような場所です.

  • endの手前
  • repeat - until の untilの手前 等

上記の場所以外ではbreakは定義できません. しかしデバッグ中に,例えば処理の途中でbreakしたい場合があるかもしれません. 次のようなコードがあったとします.

for i = 0, 10 do
    print("なにか処理")
    --本当はここでbreak したい
    print("別の処理")
end
print("脱出")

まあ,このようなコードを書くことは普段ないとは思いますが.

とにかく,途中でbreakしたい場合は,ブロックをforの途中に作ればよいのです. ブロックを作るには,do - endを使用します.

書式

do
    処理
end

よって,次のように書き直せば,処理の途中でbreakが行えます.

for i = 0, 10 do
    print("なにか処理")
    do
        break;
    end
    print("別の処理")
end
print("脱出")

実行結果

なにか処理
脱出

Luaに存在しない制御文

多くのプログラミング言語には存在していても,Lua には存在していない制御文があります.

例えばswitch構文はLuaにはありません. switchはテーブルを使うことで表現できますが, ここではその方法は割愛します.

また,繰り返し処理中で使用するcontinue文も存在しません.