- Tcl全称是Tool command language,它是一种可嵌入的命令脚本化语言,由John Ousterhout发明于1988年。
- Tcl是一个基于字符串的命令语言,数据结构和语法非常简单,代码可重用性高,功能强大并且简单易学,因此经常被用于快速原型开发、脚本编程、GUI和测试等方面,在信息产业领域具有广泛的应用。
- 使用%为Tcl的命令提示符,并在接着的下一行显示命令执行结果。*后面的内容为注释说明。
10.1 Tcl语法
- Tcl语法是Tcl解释器怎样对Tcl命令进行分析的规则的集合。
10.1.1 命令格式
-
一个Tcl脚本可以包含一个或多个命令。命令之间必须用换行符或分号隔开
-
Tcl的每一个命令字符串由一个或者几个字符单元组成
-
命令名+参数变量部分(空格隔开)
-
在分析阶段,Tcl解释器基于分析规则把命令分成独立的字符单元,同时根据变量定义进行必要的变量替换;
-
在执行阶段,Tcl解释器会把开头的字符单元当作命令名,并检查这个命令名是否正确,如果该命令名正确,则激活这个命令对应的程序,并把所有的字符单元作为参数变量传递给该命令,通过在执行命令过程中进行参数变量处理完成求值过程。
-
(1)输出:输出字符串通过命令puts来实现
-
如果需要输出多于一个单词的字符串,则需要把这个字符串用双引号或者大括号包含起来
-
输出命令puts的默认行为是在输出文本结束后输出一个对应换行符return,可以通过调用参数-nonewline选项告诉puts命令不输出回车换行。
-
(2)赋值:Tcl的赋值命令是set,其变量的类型是字符串
10.1.2 替换
- Tcl解释器在分析命令时,把所有的命令参数变量都当作字符串看待,不管在内部它可能被表示成列表、整型、浮点或者其他类型,这样可以提高Tcl语言的效率
(1)变量替换
- 变量替换功能使用$符号来实现,变量替换会把变量的值导入字符单元中
(2)命令替换
- 命令替换是由中括号[]、Tcl命令和其参数组成,命令替换会使某一个命令的所有或部分字符单元被另一个命令的结果所代替
- 中括号[]内的Tcl脚本的值为最后一个命令的返回值
- 通过命令置换,可以完成命令之间的嵌套执行,即一个命令的结果可以作为另外一个命令的参数值。
(3)反斜杠替换
- Tcl脚本中的反斜杠替换用于在字符单元中插入诸如换行符、空格、[、$等这些被Tcl解释器当作特殊符号对待的字符
- 反斜杠替换命令
10.1.3 双引号和花括号
- Tcl解释器对双引号中的各种分隔符将不作处理,除了对换行符及$和[]两种替换符会按替换操作处理
- 在大括号{}中,所有特殊字符单元都将成为普通字符单元,失去其特殊意义,Tcl解释器不会对其做特殊处理
10.1.4 注释
- 编写Tcl脚本过程中,对重要的代码进行注释说明是必要的,Tcl中的注释符是#
- #必须出现所在命令的第一个,才被Tcl解释器识别为注释,否则Tcl解释器会把#当作字符单元解析,如果不符合Tcl语法格式则会报错
10.2数据结构
- Tcl支持两种类型的数据结构:变量和数组。
10.2.1 简单变量
- Tcl中变量由两个部分组成:变量名字和变量值。变量名字和变量值都可以定义成任意字符串
- Tcl解释器只把$符号之后直到第一个不是字母、数字或下划线的字符(这里是’.‘)之间的单词符号(这里是’a’)当作要被替换变量的名字,因此Tcl解释器把a置换成20,然后把字符串“20.1”赋值给变量b
10.2.2 数组
- 数组是一些元素的集合,Tcl中定义一个数组需要连数组元素一起定义。因此在数组中,数组元素的变量名包含两部分:数组名和数组元素的名字。Tcl中数组元素的名字(下标)可以定义为任何字符串
10.3表达式
- Tcl中的表达式类似于ANSI C的表达式。表达式由操作数和操作符构成
10.3.1 操作数
- Tcl表达式的操作数通常是整数(int)、浮点数(float)和字符串(string)。整数一般是十进制的,但如果整数的第一个字符是0(zero),那么Tcl将把这个整数看作八进制的,如果前两个字符是0x则这个整数被看作是十六进制的。
10.3.2 运算符和优先级
- 运算符是按优先级从高到低往下排列的,同一格中的运算符优先级相同。
10.3.3 数学函数
- 主要数学函数
10.3.4 列表集合
- Tcl中list表示列表集合,它是由一堆元素组成的有序列表集合。list可以嵌套定义,list每个元素可以是任意字符串,也可以是list。
1.list命令
- 语法
- list命令定义一个列表集合,list的元素就是所有的值
2.concat命令
- 语法
- concat命令把多个list合成一个list,每个list变成新list的一个元素
3.lindex命令
- 语法
- lindex命令返回list的第index个元素,其中初始值从0开始
4. llength命令
- 语法
- llength命令返回list的元素个数
5. linsert命令
- 语法
- linsert命返回一个新串,新串把所有的value参数值插入list的第index个(0-based)元素之前得到
6.lreplace命令
-
语法
-
lreplace命令返回一个新串,新串是把list的第first到第last个元素用所有的value参数替换得到的。如果没有value参数,就表示删除第first到第last个元素
7.lrange命令
- 语法
- lrange命令返回list的第first到第last元素组成的集合串,如果last的值是end,就是从第first个直到串的最后
8.lappend命令
- 语法
- lappend命令把每个value的值作为一个元素附加到变量varname后面,并返回变量的新值,如果varname不存在,就生成这个变量
9. lsearch命令
- 语法
- lsearch命令返回list中第一个匹配模式pattern的元素的索引,如果找不到匹配就返回-1
- -exact表示精确匹配
- glob的匹配方式和string match命令的匹配方式相同
- -regexp表示正则表达式匹配
- lsearch支持通配符*格式,但可以使用-exact选项将其屏蔽而进行精确匹配,缺省时使用-glob匹配
10.lsort命令
-
语法
-
lsort命令用于返回把list进行排序后的列表集合串。
-
options可以使用如下值:
-
-ascii按ASCII字符的顺序排序比较,这是缺省情况。
-
-dictionary按字典排序,与-ascii不同的地方是:
- ❑不考虑大小写。
- ❑如果元素中有数字的话,数字被当作整数来排序。
-
-integer把list的元素转换成整数,按整数排序。
- 把list的元素转换成浮点数,按浮点数排序。-real
- -increasing升序(按ASCII字符比较)
- -decreasing降序(按ASCII字符比较)
- -command command TCL自动利用command命令把每两个元素一一比较,然后给出排序结果
11.split命令
- 语法
- split命令把字符串string按分隔符splitChars分成一个个单独的字符单元,返回由这些字符单元组成的串。如果splitChars是一个空字符{}, string被按字符分开。
12.join命令
- 语法
- join命令是命令split的反向操作。这个命令把list的所有元素合并到一个字符串中,中间加入分隔符joinString来分开字符串。缺省的joinString是空格
10.4控制流
- Tcl中的控制流和C语言类似,包括if、while、for、foreach、switch、break、continue等命令
10.4.1 if命令
- 语法
- if命令先把test1当作一个表达式求值,如果值非0,则把body1当作一个脚本执行并返回所得值,否则把test2当作一个表达式求值,如果值非0,则把body2当作一个脚本执行并返回所得值,以此类推。
- 大括号“{”一定要和if命令在同一行上,因为如果不这样做,Tcl解释器会认为if命令在换行符处已结束,下一行会被当成新的命令,从而导致错误的结果。
- if和大括号之间应该有一个空格,否则Tcl解释器会把“if{”作为一个整体,当作一个命令名,从而导致错误。
10.4.2 循环命令
1. while命令
- 语法
- while命令中参数test是一个表达式,body是一个脚本,如果表达式的值非0,就运行脚本,直到表达式为0才停止循环,此时while命令中断并返回一个空字符串
2. for命令
- 语法
- for命令中参数init是一个初始化脚本,第二个参数test是一个表达式,用来决定循环什么时候中断,第三个参数reinit是一个重新初始化的脚本,第四个参数body也是脚本,代表循环体。for循环需要预置条件或者初始化命令,告诉for命令起始执行条件
3.foreach命令
- foreach命令会遍历整个列表,依次取出列表的每个元素的值放到指定变量中。
- (1)foreach varName list body
- foreach命令用法1中的第一个参数varName是一个变量,第二个参数list是一个表(有序集合),第三个参数body是循环体。每次取得链表的一个元素,都会执行循环体一次
- (2)foreach varlist1 list1 ? varlist2 list2 …? Body
- foreach命令用法2的这种形式包含了第一种用法。第一个参数varlist1是一个循环变量列表,第二个参数是一个列表list1, varlist1中的变量会分别取list1中的值。body参数是循环体
- (3)break和continue命令
- 在循环体中,可以用break和continue命令中断循环。其中break命令结束整个循环过程,并从循环中跳出
- continue只是结束本次循环
- (4)switch命令
- 语法
- switch命令的第一个是可选参数options,表示进行匹配的方式。
- Tcl支持3种匹配方式:-exact方式,-glob方式,-regexp方式,缺省情况表示-glob方式。
- -exact方式表示的是精确匹配。
- 第二个参数string是要被用来作测试的值,第三个参数是括起来的一个或多个元素对
- a的后面跟一个’-’表示使用和下一个模式相同的脚本。default表示匹配任意值。一旦switch命令找到一个模式匹配,就执行相应的脚本,并返回脚本的值,作为switch命令的返回值。