TCL学习资料Word格式文档下载.docx
《TCL学习资料Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《TCL学习资料Word格式文档下载.docx(26页珍藏版)》请在冰豆网上搜索。
一.Tcl/Tk简介
1.1背景
Tcl/Tk的发明人JohnOusterhout教授在八十年代初,是伯克利大学的教授。
在其教学过程中,他发现在集成电路CAD设计中,很多时间是花在编程建立测试环境上。
并且,环境一旦发生了变化,就要重新修改代码以适应。
这种费力而又低效的方法,迫使Ousterhout教授力图寻找一种新的编程语言,它即要有好的代码可重用性,又要简单易学,这样就促成了Tcl(ToolCommandLanguage)语言的产生。
Tcl最初的构想的是希望把编程按照基于组件的方法(componentapproach),即与其为单个的应用程序编写成百上千行的程序代码,不如寻找一个种方法将程序分割成一个个小的,具备一定“完整”功能的,可重复使用的组件。
这些小的组件小到可以基本满足一些独立的应用程序的需求,其它部分可由这些小的组件功能基础上生成。
不同的组件有不同的功能,用于不同的目的。
并可为其它的应用程序所利用。
当然,这种语言还要有良好的扩展性,以便用户为其增添新的功能模块。
最后,需要用一种强的,灵活的“胶水”把这些组件“粘”合在一起,使各个组件之间可互相“通信”,协同工作。
程序设计有如拼图游戏一样,这种设计思想与后来的Java不谋而合。
终于在1988年的春天,这种强大灵活的胶水-Tcl语言被发明出来了。
1.2定义
按照Ousterhout教授的定义,Tcl是一种可嵌入的命令脚本化语言(CommandScriptLanguage)。
“可嵌入”是指把很多应用有效,无缝地集成在一起。
“命令”是指每一条Tcl语句都可以理解成命令加参数的形式:
命令[参数1][参数2][参数3][参数4]......[参数N]
脚本化是指Tcl为特殊的,特定的任务所设计。
但从现在角度看,可以说Tcl是一种集C语言灵活强大的功能与BASIC语言易学高效的风格于一身的通用程序设计语言。
按照Ousterhout教授的定义,Tcl是一种可嵌入的命令脚本化语言(CommandScriptLanguage)。
tcl(读作“tickle”)脚本语言和tk工具箱是为XWindow系统创建图形用户界面的编程环境。
tcl和tk非常容易学习和使用,并且利用它们构造用户界面的速度要比利用传统的XWindow编程方法快得多。
它最初设计用来为交互式工具提供一种可复用的命令语言,但它的实际发展却远非如此,并且在众多的软件产品中被广泛应用。
tcl/tk的真正功能在于,利用tcl脚本语言几乎完全可以编写复杂的图形应用程序,因而避开了利用C语言编写界面时所遇到的界面编程的许多复杂性。
tcl/tk的正式Web站点是http:
//www.scriptics.com/。
在这里tcl平台是Scritpics公司的产品。
Scritpics公司要把tcl脚本语言推广到主流的团体中去。
Scritpics公司提供了开发工具,技术支持和在开发tcl和tk公开代码的软件包是对tcl实行商业支持服务。
该站点还具有下载和安装tcl/tk最新版本的连接。
目前,可得到的最新tcl/tk的版本是8.4a。
tcl中的可执行程序tcl,tclsh,wish和tclhelp被RedHat的rpm安装在目录/usr/bin中。
可以使用tclhelp调出关于tcl和tk的帮助信息。
系统中也提供了tclsh和wish的手册页。
二.Tcl/Tk基础
tcl是类似于UNIXshell的一种解释性的语言,这就是说,tcl命令首先被读取,接着就被执行。
也是一个用来设置查看的工具箱,它可以利用tcl语法来创建按钮、滚动杆、对话框以及窗口等GUI组件。
为了运行tcl。
tclsh和wish与sh或csh这样的标准UNIXshell类似,它们都允许命令被交互地执行或从某个文件中读入。
在实际情况中,人们很少交互地使用这些shell,因为它们的交互能力很有限。
tcl和wish之间的主要差别是:
tclsh只理解tcl命令,而wish理解tcl和tk两种命令。
2.1交互方式
本节将简单介绍tclshell的交互使用方式,从而来说明它的一个问题。
要想开始交互使用tcl,只须在UNIXshell的提示符下输入tclsh(或wish),这时将出现如下提示符:
%
在本章中,交互的命令以百分号(%)开始。
在这一提示符后,输入如下命令:
%echo“helloworld”
在输入这一命令之后,helloworld将会显示在新的提示符之后。
接下来执行如下命令:
%puts“helloworld”
此时,同样的输出结果将显示出来,不过这两个命令之间具有很大的差别。
为了显示字符串“helloworld”,第一个命令运行的是echo二进制文件,而第二个命令使用的是tcl命令puts(putstring)。
echo形式的”helloworld”,仅当交互运行tclsh时才起作用,这正是交互使用tclsh和wish的问题之一。
例如,如果把命令:
echo“helloworld”
放入文件helloworld.tcl,然后从tclsh中执行如下source命令:
%sourcehelloworld.tcl
那么将会得到如下的错误信息:
invalidcommandname“echo”
此行代码将在一个UNIXshell中执行这一具有变化的命令。
这只是在tclshell的交互方式中工作方式不同的事例之一。
2.2非交互方式
在通常情况下,tclsh和wish-般是以非交互的方式来使用的,这就是说,它们在UNIX的提示符($)下被调用并执行脚本,例如:
$tclshmyprog.tcl
$wishmyprog.tcl
或者从一个脚本内来调用它们,这个脚本的第一行通常与如下内容类似:
#!
/usr/bin/tclsh
在通常情况下,对脚本的每次安装都必须修改第一行,因为wish或tchsh可能位于不同的位置。
为了避免在每次安装时都必须对脚本进行编辑,tclsh的手册页推荐利用如下三行代码作为所有tcl/tk脚本的头三行:
/bin/sh
#thenextlinerestartsusingtclsh\
execwish“$0”“$@”
这意味着,用户只须在自己的路径中具有wish就可以使用脚本。
利用这种方法产生的各自的结果可能会根据系统上sh版本的不同而不同。
tcl非交互使用方式的实际优点是与UNIXshell的非交互使用方式的优点相同。
非交互使用方式允许把多个命令组合在一起,并且只要输入脚本的名字就可以执行脚本中的所有命令,同时这种方式可以加速对大型程序的开发和调试。
三.TCL总体结构图
四.与其它语言的比较
下面就Tcl与经典的的程序设计语言C++,及现在时髦的Java做一些比较:
C++,Tcl/Tk和Java的性能比较表
C++
Tcl/Tk
Java
运行程序速度
快
与C++可比
慢
调试难易程度
复杂
每次修改完代码需重新编译
简单
修改完代码可直接运行
比较简单
修改完代码需重新编译成ByteCode,而且编译速度很慢
程序代码复杂程度以上面的grep为例
50行程序代码
简明
10行程序代码
40行程序代码
系统资源占用情况
200MBHD
32MBMemory
3MBHD
4MBMemory
20MBHD
代码可维护性
可移植性
好
一般
较好
五.TCL语法
本节将介绍tcl的语法及其在脚本中的使用方式。
下面几小节中的代码既可以交互地运行,也可以从脚本运行。
在交互方式下,输出内容之间的间距会略有不同。
5.1tcl命令结构.
TCL命令的基本结构是:
commandnamearguments
这里的commandname是tcl所要执行的命令,arguments是提供给此命令的可选变元,整个行(commandname和arguments)称为一个命令。
命令之间通过换行(\n)或者由分号(;
)来分隔。
如果在一行上只有一个命令,那么分号可以省略。
作为说明,看下面两个命令:
setfoo0
setbar1
这两个命令可以写成两行,每行写一个;
另外,它们也可以写在同一行上,例如:
setfoo0;
setbar1;
有时需要在表达式中使用另一个表达式的值。
使用方括号来实现:
puts[expr1000/4];
输出将是250。
在需要时方括号也可以嵌套。
5.2TCL的注释
除命令外,tcl脚本中另一种类型的代码行是注释。
如同在UNIXshell和Perl中那样,注释行是以#号开头的行,例如:
#thisisacomment
但是与shell中不同的是,下面一行内容并不是注释
setfoo0#initializefoo
而且它将会产生一个错误,这是因为tcl解析器总是认为一条命令应该以换行或分号结束,因此如果想要在命令所在的同一行上包括注释内容,这个命令必须以分号结束,就像下面这样:
#initializefoo
因此,用分号结束所有的命令通常是一种很好的做法,尽管有时分号并不是必需的。
5.3数据类型
tcl不支持诸如int、float、double或char之类的变量类型。
这意味着,在同一程序中,一个变量可以在不同的时刻分别被设置为数值、字符或字符串。
但是在内部,tcl把所有的变量都当作字符串来看待。
当需要操作变量时,tcl允许以ANSIC所能识别的任何一种方式来提供数字(实数或整数),下面列出的是可以提供给变量的有效数字值的例子:
74整数
0112八进制,以0开头
Ox4a十六进制,以Ox开头
74.实数
74.0实数
7.4e1实数
7.4e+1实数
除此之外的其他值都被当作是字符串,如果把它们应用于数学表达式,则会产生错误。
5.4变量
tcl可以定义两种类型的变量:
标量和数组。
要创建标量变量并对它赋值,可利用set命令,例如:
setbanana1;
这一命令将创建变量banana并把它的值赋为1。
要想把变量banana设置为另一个值,只须再次利用set,例如:
setbanana"
FreshfromBrazil"
;
此时变量banana具有的值为“FreshfromBrazil”,命令中的双引号用来通知tcl变量的值由引号中包括空格在内的所有字符组成(在本章后续章节中将讨论引用和置换)。
要输出banana的值,可利用puts命令:
puts$banana;
这一命令将把变量banana的值显示到标准输出(也称为STDOUT)。
在变量名前放置$用来通知tcl访问的是这一变量的值,这个规定称为变量置换,它与UNIXshell中所使用的规定类似。
注意要使用变量内容时应使用$符,而在设置或改变变量时不必使用$.
要想创建一个一维数组,可以像下面这样进行:
setfruit(O)banana;
setfruit
(1)orange;
这两个命令将创建一个数组变量fruit,并把它的两个元素。
0和1分别赋值为banana和orange。
注意计算机记数是从0,而不是从1开始。
对数组的赋值不必按照索引的顺序,例如,下面命令在数组fruit中创建了三个元素。
setfruit{100}peach;
setfruit{2}kiwi;
setfruit{87}pear;
tcl中的数组非常类似于把“关键字”与值联系在一起的关联数组。
tcl中的数到把某一给定的字符串与另一个字符串联系起来,这使得这种数组可能具有非数字的数组下标,例如:
fruitto100:
setfruit{banana}100
这一命令把数组fruit中元素banana的值设置为100,被赋的值也可以不是数字,例如:
setfood(koala)eucalyptus;
setfood(chipmunk)acorn;
如果想访问存放在一维数组中的值,可利用$,例如:
puts$food(koala);
这一命令将显示出存放在数组food中下标为koala的值,数组的下标也可以是一个变量,例如:
setanimalchipmunk;
puts$food($animal);
如果在前面进行了赋值,这两个命令将输出acorn。
多维数组是一维数组的简单扩充,它们的设置方式如下:
setmyarray(1,1)0;
这一命令把数组myarray中位于1,1处的元素的值设置为0。
通过利用逗号分隔下标,你可以设置三维、四维或更多维的数组,例如:
setarray(1,1,1,1,1,1)“foo”
除了设置数组的值外,tcl还提供用来获取有关数组信息的命令array,以及用来输出有关数组信息的命令parray。
首先,我们来考察parray命令。
如果已经提供了如下命令:
setfood(panda)bamboo;
那么命令
parrayfood
将产生如下的输出结果:
food(chipmunk)=acorn
food(koala)=eucalyptus
food(panda)=bamboo
接下来我们来考察array命令及其变元,这个命令用来获取有关数组及其元素的信息。
array命令的基本语法如下:
arrayoptionarrayname
在本节后面将讨论它所支持的选项。
有关数组最常用的信息之一是数组的大小。
如果已经提供了如下说明:
setfruit(0)banana;
setfruit
(1)peach;
setfruit
(2)pear;
setfruit(3)apple;
arraysizefruit;
将返回4,这一数值通常在循环中非常有用。
由于数组可以具有非顺序的或非数字的下标,因此array命令提供一个用来从数组中获取元素的选项。
假设数组food已经像前面介绍的那样进行了定义,那么开始获取元素所须做的第一件事是利用startsearch遍历数组。
这是通过首先获取数组的一个搜索ID来完成的:
setfood_sid[arraystartsearchfood]
在方括号中的命令arraystartsearchfood返回一个字符串,这一字符串是搜索标志的名字
(请参看“引用和替换”)。
这个名字将在以后的引用中用到,因此需要把它赋给某个变量。
在本例中,这一变量为food_sid。
要获取food数组的第一个元素(以及其后的每个元素),可以利用如下命令:
arraynextelementfood$food_sid;
当完成对数组的搜索时,可利用如下命令终止搜索:
arraydonesearchfood$food_sid;
array命令的另一个选项是在遍历数组时经常用到的anymore。
当在搜索中还有元素时,它将返回true(也就是1),这一命令当与前面所说明的数组food一起使用时,在前两次将返回1。
arrayanymorefood$food_sid;
要清除变量(标量或数组),可以利用unset命令,例如:
unsetbanana;
这个命令将取消banana变量。
如果你利用unset$banana(假如banana已被设置为前面所显示
的值)来取代刚才的banana,那么你会得到如下一条错误信息:
can'
tunset"
0"
:
nosuchvariable
发生错误的原因是:
当把$放在变量名的前面时,在执行命令之前变量的值将被替换进去。
5.5字符串的操作
对字符串进行操作的最简单的形式是利用append命令把多个字符和变量连接在一起。
作为说明,考察如下几条命令
这些命令的输出结果为:
BeginaStringwithsometextandaddevenmoretexttoit.
你也可以利用如下命令来达到相同的结果:
但是这种做法与利用append相比,执行起来要慢一些,这是因为append不像set那样要执行字符拷贝。
为了能够执行更多高级的字符操作,tcl提供了string命令,这一命令能够识别许多选项。
sting命令的基本语法是:
stringoptionstring1string2
这里的string1和string2可以是文字串(例如,“thisisastring”),也可以是变量,option是下列选项之一:
compare按照词典的排序方式进行比较,根据string1小于、等于或大于string2,分别返回-1、0或
1(类似于C库函数strcmp)first返回在string2中第一次出现string1的位置如果string1没有出现在string2中,则返回-1
last返回在string2中最后一次出现string1的位置。
如果string1没有出现在string2中,则返回-1
string命令的如下选项将把string2解释为要从stringl中删除的一列字符:
trim从string1中删除开头和结尾的出现在string2中的字符
trimleft从string1中删除开头的出现在string2中的字符
trimright从string1中删除结尾的出现在string2中的字符
string命令的如下选项只利用string1作为变元:
length返回string1包含的字符数
tolower返回string1中的所有字符被转换为小写字符后的新字符串
toupper返回string1中的所有字符被转换为大写字符后的新字符串现在让我们来考察几个例子。
首先,创建一个字符串并获取其长度:
setstr"
HereIsATestString"
stringlength$str;
这一命令给出的长度为23(length选项对空格字符也计算在内)。
现在,让我们来获取在$str字符串中第一次和最后一次出现字符串“st”的位置:
stringfirst"
st"
$str;
stringlast"
$str
这两个命令给出第一次出现“t”的值为13(相应于在Test中出现的位置),最后一次出现“st”的值也为13(还是Test)。
在String中出现的“t”为什么不算数呢?
这是因为大多数字符串比较函数是区分大小写和空格的,下面的代码将首先把$str转换为小写字体,然后再执行查找:
[stringtolower$str];
此时,这一命令给出的值为16,它相应于String中的“st”。
最后,让我们来删除$str字符串前后的空格,然后获取这一字符串的长度:
stringlength[stringtrim$str"
"
],
该命令的返回值为21,这意味着已经删除了第一个和最后一个空格。
33.2