■break和continue命令
在循环体中,可以用break和continue命令中断循环。其中break命令结束整个循环过程,并从循环中跳出,continue只是结束本次循环。 ■switch 命令
和C语言中switch语句一样,TCL中的switch命令也可以由if命令实现。只是书写起来较为烦琐。 switch命令的语法为: switch ? options? string { pattern body ? pattern body ...?}
第一个是可选参数options,表示进行匹配的方式。TCL支持三种匹配方式:-exact方式,-glob方式,-regexp方式,缺省情况表示-glob方式。-exact方式表示的是精确匹配,-glob方式的匹配方式和string match 命令的匹配方式相同(第八节介绍),-regexp方式是正规表达式的匹配方式(第八节介绍)。第二个参数string 是要被用来作测试的值,第三个参数是括起来的一个或多个元素对,例: switch $x { a -
b {incr t1} c {incr t2} default {incr t3} }
其中a的后面跟一个'-'表示使用和下一个模式相同的脚本。default表示匹配任意值。一旦switch命令 找到一个模式匹配,就执行相应的脚本,并返回脚本的值,作为switch命令的返回值。
控制流 > eval命令
eval命令是一个用来构造和执行TCL脚本的命令,其语法为: eval arg ?arg ...?
它可以接收一个或多个参数,然后把所有的参数以空格隔开组合到一起成为一个脚本,然后对这个脚本进行求值。例如: %eval set a 2 ;set b 4 4
控制流 > source命令so
source命令读一个文件并把这个文件的内容作为一个脚本进行求值。例如: source e:/tcl&c/hello.tcl
1 6
注意路径的描述应该和UNIX相同,使用'/'而不是'\\'。
过程(procedure) > 过程定义和返回值
TCL支持过程的定义和调用,在TCL中,过程可以看作是用TCL脚本实现的命令,效果与TCL的固有命令相似。我们可以在任何时候使用proc命令定义自己的过程,TCL中的过程类似于C中的函数。
TCL中过程是由proc命令产生的: 例如:
% proc add {x y } {expr $x+$y}
proc命令的第一个参数是你要定义的过程的名字,第二个参数是过程的参数列表,参数之间用空格隔开,第三个参数是一个TCL脚本,代表过程体。 proc生成一个新的命令,可以象固有命令一样调用: % add 1 2 3
在定义过程时,你可以利用return命令在任何地方返回你想要的值。 return命令迅速中断过程,并把它的参数作为过程的结果。例如: % proc abs {x} {
if {$x >= 0} { return $x } return [expr -$x] }
过程的返回值是过程体中最后执行的那条命令的返回值。
过程(procedure) > 局部变量和全局变量
对于在过程中定义的变量,因为它们只能在过程中被访问,并且当过程退出时会被自动删除,所以称为局部变量;在所有过程之外定义的变量我们称之为全局变量。TCL中,局部变量和全局变量可以同名,两者的作用域的交集为空:局部变量的作用域是它所在的过程的内部;全局变量的作用域则不包括所有过程的内部。这一点和C语言有很大的不同.
如果我们想在过程内部引用一个全局变量的值,可以使用global命令。例如: % set a 4 4
% proc sample { x } { global a incr a
return [expr $a+$x]
17
}
% sample 3 8 %set a 5
全局变量a在过程中被访问。在过程中对a的改变会直接反映到全局上。如果去掉语句global a,TCL会出错,因为它不认识变量a。 过程(procedure) > 缺省参数和可变个数参数TCL还提供三种特殊的参数形式:
首先,你可以定义一个没有参数的过程,例如: proc add {} { expr 2+3}
其次,可以定义具有缺省参数值的过程,我们可以为过程的部分或全部参数提供缺省值,如果调用过程时未提供那些参数的值,那么过程会自动使用缺省值赋给相应的参数。和C\\C++中具有缺省参数值的函数一样,有缺省值的参数只能位于参数列表的后部,即在第一个具有缺省值的参数后面的所有参数,都只能是具有缺省值的参数。 例如:
proc add {val1 {val2 2} {val3 3}}{ expr $val1+$val2+$val3 } 则:
add 1 //值为6 add 2 20 //值为25 add 4 5 6 //值为15
另外,TCL的过程定义还支持可变个数的参数,如果过程的最后一个参数是args, 那么就表示这个过程支持可变个数的参数调用。调用时,位于args以前的参数象普通参数一样处理,但任何附加的参数都需要在过程体中作特殊处理,过程的局部变量args将会被设置为一个列表,其元素就是所有附加的变量。如果没有附加的变量,args就设置成一个空串,下面是一个例子: proc add { val1 args } { set sum $val1 foreach i $args { incr sum $i }
return $sum }
1 8
则:
add 2 //值为2
add 2 3 4 5 6 //值为20 过程(procedure) > 引用:upvar
命令语法:upvar ?level? otherVar myVar ?otherVar myVar ...?
upvar命令使得用户可以在过程中对全局变量或其他过程中的局部变量进行访问。 upvar命令的第一个参数otherVar是我们希望以引用方式访问的参数的名字,第二个参数myVar 是这个过程中的局部变量的名字,一旦使用了upvar 命令把otherVar 和myVar 绑定,那么在过程中对局部变量myVar 的读写就相当于对这个过程的调用者中otherVar 所代表的局部变量的读写。下面是一个例子: % proc temp { arg } { upvar $arg b set b [expr $b+2] }
% proc myexp { var } { set a 4 temp a
return [expr $var+$a] } 则: % myexp 7 13
这个例子中,upvar 把$arg(实际上是过程myexp中的变量a)和过程temp中的变量b绑定,对b的读写就相当于对a的读写。
upvar命令语法中的level参数表示:调用upvar命令的过程相对于我们希望引用的变量myVar在调用栈中相对位置。例如: upvar 2 other x
这个命令使得当前过程的调用者的调用者中的变量other,可以在当前过程中利用x访问。缺省情况下,level的值为1,即当前过程(上例中的temp)的调用者(上例中的myexp)中的变量(上例中myexp的a)可以在当前过程中利用局部变量(上例中temp的b)访问。 如果要访问全局变量可以这样写: upvar #0 other x
那么,不管当前过程处于调用栈中的什么位置,都可以在当前过程中利用x访问全局变量other。
19
字符串操作 > format命令
因为TCL把所有的输入都当作字符串看待,所以TCL提供了较强的字符串操作功能,TCL中与字符串操作有关的命令有:string、format、regexp、regsub、scan等。 format命令
语法:format formatstring ?vlue value...?
format命令类似于ANSIC中的sprintf函数和MFC中CString类提供的Format成员函数。它按formatstring提供的格式,把各个value的值组合到formatstring中形成一个新字符串,并返回。例如: %set name john John
%set age 20 20
%set msg [format \ john is 20 years old 字符串操作 > scan命令
语法:scan string format varName ?varName ...?
scan命令可以认为是format命令的逆,其功能类似于ANSI C中的sscanf函数。它按format提供的格式分析string字符串,然后把结果存到变量varName中,注意除了空格和TAB键之外,string 和format中的字符和'%'必须匹配。例如: % scan \ 2 % set a 26 % set b 34
% scan \ 4
% puts [format \ the value of c is 12,d is 34,e is 56 ,f is 78
scan命令的返回值是匹配的变量个数。而且,我们发现,如果变量varName不存在的话,TCL会自动声明该变量。
字符串操作 > regexp命令
语法:regexp ?switchs? ?--? exp string ?matchVar?\\ ?subMatchVar subMatchVar...? regexp命令用于判断正规表达式exp是否全部或部分匹配字符串string,匹配返回1,否则0。
2 0