Tcl 中的控制流
在 Tcl 教程的这一部分中,我们将讨论流控制。 我们将定义几个命令,这些命令使我们能够控制 Tcl 脚本的流程。
在 Tcl 语言中,有几个命令可用于更改程序流程。 运行程序时,其命令从源文件的顶部到底部执行。 逐一。 可以通过特定命令更改此流程。 命令可以多次执行。 有些命令是有条件的。 仅在满足特定条件时才执行它们。
if
命令
if
命令具有以下一般形式:
if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
if
命令用于检查表达式是否为真。 如果为真,则执行命令主体。 主体用花括号括起来。
if
命令计算一个表达式。 该表达式必须返回一个布尔值。 在 Tcl 中,1,是,true
表示true
,0,no
,false
表示false
。
!/usr/bin/tclsh
if yes {
puts "This message is always shown"
}
在上面的示例中,始终执行由{ }
字符包围的主体。
#!/usr/bin/tclsh
if true then {
puts "This message is always shown"
}
then
命令是可选的。 如果我们认为可以使用它,它将使代码更加清晰。
我们可以使用else
命令创建一个简单的分支。 如果if
命令后方括号内的表达式的计算结果为false
,则将自动执行else
命令后方的命令。
#!/usr/bin/tclsh
set sex female
if {$sex == "male"} {
puts "It is a boy"
} else {
puts "It is a girl"
}
我们有性别变量。 它具有"female"
字符串。 布尔表达式的计算结果为false
,我们在控制台中得到"It is a girl"
。
$ ./girlboy.tcl
It is a girl
我们可以使用elseif
命令创建多个分支。 仅当不满足先前条件时,elseif
命令才会测试其他条件。 请注意,我们可以在测试中使用多个elseif
命令。
#!/usr/bin/tclsh
# nums.tcl
puts -nonewline "Enter a number: "
flush stdout
set a [gets stdin]
if {$a < 0} {
puts "the number is negative"
} elseif { $a == 0 } {
puts "the numer is zero"
} else {
puts "the number is positive"
}
在上面的脚本中,我们提示您输入一个值。 我们测试该值是否为负数或正数或等于零。 如果第一个表达式的计算结果为false
,则对第二个表达式进行计算。 如果不满足先前的条件,则将执行else
命令之后的主体。
$ ./nums.tcl
Enter a number: 2
the number is positive
$ ./nums.tcl
Enter a number: 0
the numer is zero
$ ./nums.tcl
Enter a number: -3
the number is negative
多次运行该示例。
switch
命令
switch
命令将其字符串参数与每个模式参数按顺序进行匹配。 一旦找到与字符串匹配的模式,它就会通过将其递归传递给 Tcl 解释器来求值以下主体参数,并返回该求值结果。 如果最后一个模式参数为默认值,则它匹配任何内容。 如果没有任何模式参数与字符串匹配,并且没有给出默认值,那么switch
命令将返回一个空字符串。
#!/usr/bin/tclsh
# switch_cmd.tcl
puts -nonewline "Select a top level domain name:"
flush stdout
gets stdin domain
switch $domain {
us { puts "United States" }
de { puts Germany }
sk { puts Slovakia }
hu { puts Hungary }
default { puts "unknown" }
}
在脚本中,我们提示您输入域名。 有几种选择。 例如,如果该值等于我们,则将"United States"
字符串打印到控制台。 如果该值与任何给定值都不匹配,那么将执行默认主体,并将unknown
打印到控制台。
$ ./switch_cmd.tcl
Select a top level domain name:sk
Slovakia
我们已将sk
字符串输入到控制台,该程序响应了斯洛伐克。
while
命令
while
命令是一个控制流命令,它允许根据给定的布尔条件重复执行代码。
while
命令在大括号括起来的块内执行命令。 每次将表达式求值为true
时都将执行命令。
#!/usr/bin/tclsh
# whileloop.tcl
set i 0
set sum 0
while { $i < 10 } {
incr i
incr sum $i
}
puts $sum
在代码示例中,我们从一系列数字计算值的总和。
while
循环包含三个部分:初始化,测试和更新。 该命令的每次执行都称为一个循环。
set i 0
我们启动i
变量。 它用作计数器。
while { $i < 10 } {
...
}
while
命令后面大括号内的表达式是第二阶段,即测试。 执行主体中的命令,直到表达式的计算结果为false
。
incr i
while
循环的最后第三阶段是更新。 计数器增加。 请注意,对while
循环的不正确处理可能会导致循环不断。
for
命令
如果在启动循环之前知道周期数,则可以使用for
命令。 在此构造中,我们声明一个计数器变量,该变量在每次循环重复期间都会自动增加或减少值。
#!/usr/bin/tclsh
for {set i 0} {$i < 10} {incr i} {
puts $i
}
在此示例中,我们将数字0..9
打印到控制台。
for {set i 0} {$i < 10} {incr i} {
puts $i
}
分为三个阶段。 首先,我们将计数器i
初始化为零。 此阶段仅完成一次。 接下来是条件。 如果满足条件,则执行for
块中的命令。 然后进入第三阶段; 计数器增加。 现在,我们重复阶段 2 和 3,直到不满足条件并留下for
循环。 在我们的情况下,当计数器i
等于 10 时,for
循环停止执行。
$ ./forloop.tcl
0
1
2
3
4
5
6
7
8
9
在这里,我们看到forloop.tcl
脚本的输出。
foreach
命令
foreach
命令简化了遍历数据集合的过程。 它没有明确的计数器。 它逐个元素地遍历一个列表,并且当前值被复制到构造中定义的变量中。
#!/usr/bin/tclsh
set planets { Mercury Venus Earth Mars Jupiter Saturn
Uranus Neptune }
foreach planet $planets {
puts $planet
}
在此示例中,我们使用foreach
命令浏览行星列表。
foreach planet $planets {
puts $planet
}
foreach
命令的用法很简单。 planets
是我们迭代的列表。 planet
是具有列表中当前值的临时变量。 foreach
命令遍历所有行星并将其打印到控制台。
$ ./planets.tcl
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune
运行上面的 Tcl 脚本将给出此输出。
#!/usr/bin/tclsh
set actresses { Rachel Weiss Scarlett Johansson Jessica Alba \
Marion Cotillard Jennifer Connelly}
foreach {first second} $actresses {
puts "$first $second"
}
在此脚本中,我们迭代列表的值对。
foreach {first second} $actresses {
puts "$first $second"
}
我们在每次迭代时从列表中选择两个值。
$ ./actresses.tcl
Rachel Weiss
Scarlett Johansson
Jessica Alba
Marion Cotillard
Jennifer Connelly
这是actresses.tcl
脚本的输出。
#!/usr/bin/tclsh
foreach i { one two three } item {car coins rocks} {
puts "$i $item"
}
我们可以并行遍历两个列表。
$ ./parallel.tcl
one car
two coins
three rocks
这是parallel.tcl
脚本的输出。
break
和continue
命令
break
命令可用于终止由while
,for
或switch
命令定义的块。
#!/usr/bin/tclsh
while true {
set r [expr 1 + round(rand()*30)]
puts -nonewline "$r "
if {$r == 22} { break }
}
puts ""
我们定义了一个无限的while
循环。 我们使用break
命令退出此循环。 我们从 1 到 30 中选择一个随机值并打印出来。 如果该值等于 22,则结束无穷while
循环。
set r [expr 1 + round(rand()*30)]
在这里,我们计算出 1..30 之间的随机数。 rand()
是内置的 Tcl 过程。 它返回一个从 0 到 0.99999 的随机数。 rand()*30
返回 0 到 29.99999 之间的随机数。 round()
过程将最终数字四舍五入。
$ ./breakcommand.tcl
28 20 8 8 12 22
我们可能会得到这样的东西。
continue
命令用于跳过循环的一部分,并继续循环的下一个迭代。 可以与for
和while
命令结合使用。
在下面的示例中,我们将打印一个数字列表,这些数字不能除以 2 而没有余数。
#!/usr/bin/tclsh
set num 0
while { $num < 100 } {
incr num
if {$num % 2 == 0} { continue }
puts "$num "
}
puts ""
我们使用while
循环遍历数字1..99
。
if {$num % 2 == 0} { continue }
如果表达式num % 2
返回 0,则所讨论的数字可以除以 2。执行continue
命令,并跳过循环的其余部分。 在我们的情况下,循环的最后一个命令将被跳过,并且数字不会打印到控制台。 下一个迭代开始。
在 Tcl 教程的这一部分中,我们正在讨论控制流结构。