TCL脚本语言-8-控制结构
- 格式:pdf
- 大小:487.91 KB
- 文档页数:20
Tcl语言快速参考手册Tcl("Tool Command Language",即工具命令语言;Tcl念作"tickle"即“踢叩” )是一种简单易用易于扩展的嵌入式脚本语言, 主要用于发布命令给交互式程序(如文本编辑器、调试器),及完成自动化批处理工作。
Tcl语言不同于其他语言的最大的特点是:Tcl程序由Tcl命令序列组成,其每条语句都是一条指令。
由于其极易扩展的特性,Tcl有大量的用C/C++编写的扩展用于提供Tcl本身不具有的功能。
其中使用最广泛的扩展是TK,TK提供了各种OS平台下的图形用户界面GUI(连强大的Python 语言都不单独提供自己的GUI,而是提供接口适配到TK上)。
另一个流行的扩展包是Expect,它提供了通过终端自动执行命令的能力,例如passwd, ftp, telnet等命令驱动的外壳。
一、Tcl程序基本结构1、基本语法Tcl的语法类似于shell:一条Tcl的命令串包含若干条命令,命令使用换行符或分号来隔开;而每一条命令包含若干个域(field),域使用空白(空格或TAB)来隔开——第一个域是命令的名字,其它的域是该命令的参数。
Tcl解释器对一个命令的执行过程分为两步:分析阶段和执行阶段。
在分析阶段,Tcl 解释器运用规则识别出命令并把命令分成一个个独立的单词,同时进行必要的置换(substitution);在执行阶段,Tcl 解释器会把第一个单词当作命令名,并查看这个命令是否有定义,如果有定义就激活这个命令对应的C/C++过程,并把所有后面的单词作为参数传递给该命令过程,让命令过程进行处理。
Tcl解释器既可以执行Tcl内建命令亦可执行用户自己通过C/C++函数实现的新建命令,在应用程序中可用函数Tcl_CreateCommand来完成命令的创建。
所有命令参数都被作为字符串来传递,命令自己会按其所需来解释参数。
另外关于Tcl的注释有一个特殊的要求:'#'必须出现在Tcl解释器期望命令的第一个字符出现的地方,才被当作注释。
Tcl脚本测试入门Tcl简介Tcl是一种非常简单的编程语言,如果你以前曾经学过编程,那么你只要学习几个小时就可以编写出一些有趣的Tcl程序。
本文将对Tcl的功能做一个大概的介绍。
一般来说,读完本文之后,你就可以开始独立的编写一些简单的Tcl 脚本了;不过,要想获得更全面的认识,我们建议你还是去参考几本目前已经出版的 Tcl书籍。
基本语法Tcl脚本由一些被换行符或是分号分开的命令所组成。
命令都有相同的基本格式,如下面的例子所示:expr 20 + 10该命令计算20加10的和,并返回结果30。
你可以把这个例子以及本文中的所有其它的例子键入到tclsh这样的Tcl应用程序中来验证它们;在一个命令结束后,tclsh将打印出它的结果。
每个Tcl命令都含有一个或多个被空格分开的单词,在这个例子中有4个单词:expr,20,+,和10。
第一个单词是一个命令名,其余的单词是这个命令的参数。
所有的Tcl命令都含有一些单词,但不同的命令对他们的参数有不同的处理方式。
expr命令把它的所有参数看作是一个算术表达式,计算表达式的结果,并以字符串的形式返回结果。
在expr命令中,单词之间的分隔不是很重要:同样的命令你可以写成这种形式:expr 20+10不过,对大部分的命令来说,单词的结构是很重要的。
每个单词都会用于不同的目的。
所有的Tcl命令都返回结果。
如果一个命令产生了没有意义的结果,那么它将返回一个空字符串作为它的结果。
变量Tcl允许你在变量中保存数值,并且可以在后续的命令中使用这些数值。
set命令用于对变量进行读写操作。
比如,下面的命令对变量x赋值为32。
set x 32这个命令返回变量的新值。
你可以让set只带一个参数来读出变量的数值:set x你不需要在Tcl中声明变量:变量在第一次set的时候被自动创建。
Tcl变量没有类型:任何值可以赋给任何变量。
要想在一个命令中使用变量的值,可以采用变量替代,如下例所示:expr $x*3当一个字符$出现在一个命令中的时候,Tcl把跟在它后面的字母和数字看作是一个变量名并且将其替换成变量的值。
今天,在无意间看到了“TCL语言”,以前没有听过,也没有看过,上网搜了一下,对它简单的了解学习了一下。
需要详细了解请打开下面网址了解,学习。
/TCL(Tool Command Language)是一种解释执行的脚本语言(scrīpting Language)。
它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。
由于TCL的解释器是用一个C\\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作一个C库,这个库中有丰富的用于扩展TCL命令的C\\C++过程和函数,可以很容易就在C\\C++应用程序中嵌入TCL,而且每个应用程序都可以根据自己的需要对TCL语言进行扩展。
我们可以针对某一特定应用领域对TCL语言的核心命令集进行扩展,加入适合于自己的应用领域的扩展命令,如果需要,甚至可以加入新的控制结构,TCL解释器将把扩展命令和扩展控制结构与固有命令和固有控制结构同等看待。
扩展后的TCL 语言将可以继承TCL 核心部分的所有功能,包括核心命令、控制结构、数据类型、对过程的支持等。
根据需要,我们甚至可以屏蔽掉TCL的某些固有命令和固有控制结构。
通过对TCL的扩展、继承或屏蔽,用户用不着象平时定义一种计算机语言那样对词法、语法、语义、语用等各方面加以定义,就可以方便的为自己的应用领域提供一种功能完备的脚本语言。
TCL良好的可扩展性使得它能很好地适应产品测试的需要,测试任务常常会由于设计和需求的改变而迅速改变,往往让测试人员疲于应付。
利用TCL的可扩展性,测试人员就可以迅速继承多种新技术,并针对产品新特点迅速推出扩展TCL命令集,以用于产品的测试中,可以较容易跟上设计需求的变化。
另外,因为TCL是一种比C\\C++ 语言有着更高抽象层次的语言,使用TCL可以在一种更高的层次上编写程序,它屏蔽掉了编写C\\C++程序时必须涉及到的一些较为烦琐的细节,可以大大地提高开发测试例的速度。
tcl语法认识TCL(Tool Command Language)是一种基于字符串的命令语言,语法结构简单明了。
下面是对TCL 语法的一些基本认识:1.命令与参数:•TCL中每个命令由一个或多个单词组成,第一个单词是命令名,后面的单词是该命令的参数。
命令与参数之间必须用空格或制表符隔开。
•命令之间必须用换行符或分号隔开。
1.变量:•TCL中的变量以美元符号()开开开开开开开开开开开开开开myVariable表示一个名为“myVariable”的变量。
•变量可以在命令中直接使用,无需事先声明。
2置换:•TCL支持三种置换:变量置换、命令置换和反斜杠置换。
•变量置换:$[variable]•命令置换:$[command]•反斜杠置换:$[command]3字符串操作:•TCL支持字符串连接、子串提取、字符串替换等操作。
例如,expr substr($string, 1, 3)表示提取字符串“string”的前三个字符。
4控制结构:•TCL支持条件判断(if/then/else)和循环控制(for/while)。
例如,if { $x > $y } { puts "x is greater" }表示如果x大于y,则输出“x is greater”。
5函数:•TCL允许用户自定义函数,使用proc关键字定义函数。
例如,proc add {a b} {return [expr $a + $b]}定义了一个名为“add”的函数,用于计算两个数的和。
6注释:•TCL使用双引号和注释符号(#)来添加注释。
例如,“puts “Hello World””和“# This is a comment”都是合法的TCL语法。
7输出:•TCL使用“puts”关键字来输出字符串到标准输出设备(通常是屏幕)。
例如,“puts "Hello World"”将输出“Hello World”。
TCL语言
TCL(Tool Command Language)是一种通用的脚本语言,最初设计用于自动
化软件测试。
它具有简单易学的语法结构和强大的扩展能力,可以在多个操作系统上运行。
TCL语言主要用于编写脚本来控制和配置软件应用程序。
TCL的特点
TCL语言具有以下特点:
•易学易用:TCL语法简单清晰,入门门槛低,适合初学者快速上手。
•跨平台:TCL脚本可以在多个操作系统上运行,包括Windows、Linux、Unix等。
•模块化:TCL支持模块化开发,可以将功能分割成多个模块,提高代码可复用性。
•动态类型:TCL是一种动态类型语言,变量的类型在运行时确定,灵活性较高。
•强大的扩展能力:通过TCL的扩展包,可以方便地扩展功能,适应多样化的需求。
TCL的应用领域
TCL语言在以下领域有着广泛的应用:
•自动化测试:TCL最初设计用于自动化软件测试,可以通过编写TCL 脚本来进行自动化测试。
•网站开发:TCL可以用于构建Web应用程序,通过TCL的Web扩展包可以实现服务器端的动态网页生成。
•网络编程:TCL提供了丰富的网络编程库,可以用于开发网络应用程序。
•嵌入式开发:TCL语言可以作为嵌入式系统的脚本语言,用于控制和配置嵌入式设备。
•图形界面开发:TCL/TK是一个常用的图形用户界面开发工具包,可以用来创建GUI应用程序。
TCL语言示例
下面是一个简单的TCL脚本示例,展示了如何输出。
控制结构TCL中使用命令来实现程序控制结构,我们还可以自己编写扩展命令来扩充控制结构。
常见的控制结构包括如下几种:循环控制、条件判断、异常处理和执行脚本。
这些结构控制命令都比较简单,和C/C++中的程序控制比较类似。
但是在介绍控制结构之前,先有必要介绍一下Tcl中的布尔类型。
Boolean类型再次强调,TCL中一切都是字符串,没有类型。
这里所说的Boolean类型,指的是在条件判断的时候,什么东西被当作True,什么被当作False。
请记住如下规则:1.字符串:Yes,Y,True,T,On。
不管大小写,当作条件来判断时,会被认为是True;2.字符串:No,N,False,F,Off。
不管大小写,当作条件来判断时,会被认为是False;3.数字0(整数或者浮点)会被当作False,任何非0的整数或者浮点数都会被当作True;例如:% while 0.00e23 "puts ccc;break;" ;#False% while 0. "puts ccc;break;" ;#False% while 0.1 "puts ccc;break;" ;#Trueccc% while T "puts ccc;break;" ;#Trueccc% while 1023 "puts ccc;break;" ;#Trueccc% while T "puts ccc;break;" ;#Trueccc条件判断TCL中的条件判断主要是两个命令:if和switch。
if…elseif命令的格式如下:if expr1 ?then? body1elseif expr2 ?then? body2elseif ... ?else? ?bodyN?可以看见,if命令的参数then是可以省略的。
这给喜欢Pascal风格和C风格的不同的编程人员,都带来了怀旧的机会。
Pascal中then是必须的。
C中是没有then的。
if命令中的条件表达式expr可以写成多行,只要是一个字符串都可以。
如果写成多行,那么最好加上then,这样看起来就比较方便。
这个命令的具体执行我就不详细解释了。
要注意的是最后的else,如果没有else,那么就不能有bodyN,如果有了else,就必须有bodyN。
请看例子:if {$vbl == 1} {puts "vbl is one"} elseif {$vbl == 2} {puts "vbl is two"} else {puts "vbl is not one or two"}switch相比if…else,switch命令则要复杂很多。
它有两种语法形式:1.switch ?options? string pattern body ?pattern body ...?2.switch ?options? string {pattern body ?pattern body ...?}两种形式功能上完全等价,我们一般建议采用第二种,它和C语言的语法比较接近:所有的候选值和对应的代码全部都放在一个花括号中。
但是如果需要对pattern和body等进行替换,那么第一个形式就比较方便。
switch的选项参数可以为:1.-exact:这是默认情况,表示参数string和模式pattern的精确匹配;2.-glob:表示采用glob模式进行匹配。
匹配方法参考string match命令;3.-regexp:表示采用正则表达式进行匹配,string是字符串,而pattern是正则表达式;4.--:表示选项参数到此为止,后面的是参数string。
这是为了防止参数string的第一个字符就是“-”而引起非法选项的错误。
该命令的执行过程:根据选项指定的匹配模式,逐个将string和pattern进行匹配,如果匹配成功,那么就执行pattern后面对应的代码,并且返回该代码的结果。
如果最后的一个模式是default,安么它匹配任意字符串。
如果string没有一个匹配成功并且没有default,那么switch直接返回空。
如果某一个pattern对应的body为“-”,那么表示这个pattern和下一个pattern共享一个body。
这和C语言中的case 1:case2:{…}比较类似。
switch中的-regexp请看下面的几个例子:set r "abbbcc"switch -regexp $r {ab{2}c { puts "1" }ab{3}c { puts "2" }ab{3}c{2} { puts "3" }}上面采用正则表达式进行匹配,显然,第三个表达式才是和$r完全匹配的。
但是上面的代码执行输出是“2”。
这给我们一个重要的启示:switch中的-regexp匹配选项,实质上就是把pattern拿出来在string中进行正则表达式查找,也就是执行regexp命令,如果regexp返回1(也就是在string中找到了pattern),那么就算匹配成功,就开始执行后面的body。
而根本不管pattern是不是恰好匹配了整个string!上面这一点务必牢记。
对-glob选项,则没有这样的问题。
选项pattern和string只有完全匹配的时候才算匹配成功。
也就是说执行命令string match $pattern $string返回1,才算匹配成功。
注释的位置如果使用switch的第二种语法形式,那么就要注意switch中注释的正确位置。
注释只有放在各个body中才是正确的注释,如果放在其它地方,会出现语法错误。
例如:set r "abbbcc"switch -glob $r {a {#匹配失败,不可能执行到这里puts "1"#正确的注释}a*cc { puts "2" }#放到这里,是错误的注释ab??cc {puts "3"}}我使用的是8.4.9版本,出现的错误信息还非常的人性化:extra switch pattern with no body, this may be due to a comment incorrectly placedoutside of a switch body - see the "switch" documentationwhile executing会提醒你可能是注释放错了地方,以前的版本就没有这么好了。
错误信息会让你不知所云。
循环控制TCL中使用while、for、foreach命令来实现循环控制结构。
除了这三个命令之外,tcl 程序包control还提供了do循环。
别忘了,前面的章节中,我们还自己实现了一个简单的do…while循环。
while循环while循环命令的语法格式如下:while test body其中test被当作一个表达式来求值(和expr命令一样),结果必须是一个合法的布尔值。
当test的值为True的时候,循环体body会被执行;body执行完之后,test会被再次求值,直到test为False为止。
while命令总是返回一个空的字符串。
如果body中包含continue,那么当前这一次循环迭代会被中止,然后直接计算test,根据结果判断是否继续下一次循环;如果body中包含break,那么整个while循环立刻全部中止。
前面的章节中我们介绍TCL置换原理的时候强调了,while命令的test条件必须放在华括号中,这样每次循环结束后才对test进行真正的求值。
如果不放在花括号中,就可能会出现死循环。
有些初学者会写出如下的代码:set x 100while {[expr $x>=50 && $x<=100 ]} {……}这样的代码错了吗?没有错误,但是不好。
while循环中的判断条件,我们没有必要写在expr命令中来求值,因为while命令会自动的进行expr计算。
所以如下的代码更好:while {$x>=50 && $x<=100} {……}for循环Tcl中的for循环和C中的类似,其语法如下:for start test next body其中start,next和body都是可以执行的TCL脚本;test和while中的test类似被当作一个表达式来求值,其结果作为循环是否继续的判断标准。
for循环的执行过程如下:1.首先执行start;2.计算表达式test;3.如果test的值是True,那么就执行body,然后再执行next;然后跳到第2步;4.如果test的值是False,那么就停止循环;如果在body或者next中执行了break命令,那么for循环马上中止;如果在body中执行了continue命令,那么body中剩下的命令全部跳过而继续执行next,然后再计算next,根据结果判断是否继续循环;这两个命令在for循环中的表现和C语言中的breakl以及continue类似。
一般而言,test都必须放在花括号中,这一点和while循环类似。
下面是for循环的例子:for {set x 1} {$x<=1024} {set x [expr {$x * 2}]} {puts "x is $x"}上面的代码打印出从1开始到1024中所有的2的n次方。
foreach 循环foreach提供了一种简单的在一个或者多个列表上进行迭代的方法。
它有两种形式:foreach varname list bodyforeach varlist list1 ?varlist2 list2…? body第一种语法中,只利用一个变量对列表list进行迭代,每一次循环,都顺序取一个列表元素的值赋给varname,然后执行body。
第二种语法中,可以同时对多个列表进行迭代。
在迭代的时候,可以一次取出一个列表多个元素。
实际上,第一中形式只是第二种语法的一个特例而已。
看看下面的几个例子:set x {}foreach {i j} {a b c d e f} {lappend x $j $i}#执行后,x的值为"b a d c f e";总共完成了3次迭代。
#下面的迭代中,同时针对两个列表进行迭代:set x {}foreach i {a b c} j {d e f g} {lappend x $i $j}#执行后,x的值为"a d b e c f {} g";总共完成了4的迭代。