Tcl – プログラムの命令を繰り返し実行する -反復(ループ)-

プログラムの命令が実行される順番には、順次構造選択構造(条件分岐)反復構造(繰り返し)の3つの基本的な制御構造があります。

この記事では、反復構造(繰り返し)にあたるwhileコマンドとforコマンドについて説明します。

whileコマンド

whileコマンドは条件が成立している間、処理を繰り返します。条件式の評価には、whileコマンド内部でexprコマンドが使われています。

[書式]

while test body

test(条件式)を評価した結果、真(0以外)の場合、bodyを実行します。bodyを実行する度に、testの再評価を行い、偽(0)になるまでbodyの実行を繰り返します。

次の項目でwhileコマンドの使い方を紹介します。

指定回数繰り返す(条件一致の間)

サンプル1は入門書などに出てくるループ処理の典型的な例です。

[サンプル1: loop.tcl] 0から9まで繰り返し表示する

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

set i 0

while {$i < 10} {
    puts "i = $i"
    incr i
}

[実行例]

$ ./loop.tcl
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9

[説明]

変数iを0で初期化。

set i 0

この変数は繰返し回数を制御するものでループ変数とも言います。

メモ

ループ変数の名前は慣例的に「i, j, k」がよく使われます。これは、Fortranというプログラミング言語でi~nで始まる変数名をもつデータ型を持たない変数は暗黙の了解で整数型の変数とされていた名残のようです。

他にも、慣例的に、ループ変数や短い間しか使わない変数は1~3文字程度の短い名前を付け、比較的長い範囲で使う変数や、意味を明確にする必要がある変数には、もっと長い単語を使うようです。

例. 慣例的に使われる短い名前
char型の変数、1文字 –> c,chr
文字列 –> s,str
数値 –> n
中間処理などで一時的に使用する場合 –> buf,tmp

絶対こうしなさいというルールではないので、誰が見ても、分かりやすい名前を付けるようにした方がいいと思います。

whileコマンドは条件式「$i < 10」を評価して、iが10未満の間、ループ本体を実行します。

incr i

incrコマンドは変数iの値を増減します。第2引数を指定しない場合、+1増加します。以下のコマンドと同等の機能を提供します。

set i [expr $i + 1]

第2引数として正または負の整数を与えると変数の保持する値が指定した数だけ増減します。

例. incr i +2, incr i -1 等

サンプル1は次のように1行で書くことも出来ます。

set i 0; while {$i < 10} {puts "i = $i"; incr i}

無限ループ

サンプル2は入力した文字をそのまま画面に出力します。

[サンプル2: echo.tcl] 入力した文字を表示する

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

while {1} {
    set str [gets stdin]
    puts stdout $str
}

[実行例]

$ ./echo.tcl
hello!  <---- hello! を入力
hello!
test!   <---- test! を入力
test!
^C

[説明]

while {1} {...}

条件式に「1」を指定している為、常に真になり、無限にループします。終了させるには「ctrl + c」を入力します。

特定条件で終了する

[サンプル3: echo2.tcl] 入力した文字を表示する

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

puts "入力した文字を表示する。空エンターで終了。"

while {[gets stdin str]} {
    puts stdout $str
}

puts "終了しました。"

[実行例]

$ ./echo2.tcl
入力した文字を表示する。空エンターで終了。
hello!  <---- hello! を入力
hello!
test!   <---- test! を入力
test!
        <---- 空エンター を入力
終了しました。

[説明]

getsコマンドに第2引数を指定すると、入力された文字数を返します。空エンターを入力すると、文字数0を返すので、ループから抜けます。

forコマンド

forコマンドも、繰り返し制御を行うコマンドですが、「初期化、条件、更新」のループ制御を1箇所にまとめて記述できます。

[書式]

for start test next body
(for 初期化 条件 更新 本体)

次の項目でforコマンドの使い方を紹介します。

指定回数繰り返す(条件一致の間)

サンプル1はwhileコマンドの例をforコマンドで実装したものになります。

[サンプル1: loop2.tcl] 0から9まで繰り返し表示する

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

for {set i 0} {$i < 10} {incr i} {
    puts "i = $i"
}

[実行例]

$ ./loop2.tcl
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9

指定回数の間、偶数回目のみ処理をする

サンプル2は、 サンプル1の出力を偶数行のみ出力するように変更したものです。

[サンプル2: loop3.tcl] 偶数回目のみ表示する

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

for {set i 0} {$i < 10} {incr i} {
    if {$i % 2 == 0} {
        puts "i = $i"
    }
}

[実行例]

$ ./loop3.tcl
i = 0
i = 2
i = 4
i = 6
i = 8

その他の制御構造に関連するコマンドは、必要に応じて以下の記事を参考にしてください。

コメント

タイトルとURLをコピーしました