03-EDA工具课程之TCL市公开课获奖课件省名师优质课赛课一等奖课件_第1页
03-EDA工具课程之TCL市公开课获奖课件省名师优质课赛课一等奖课件_第2页
03-EDA工具课程之TCL市公开课获奖课件省名师优质课赛课一等奖课件_第3页
03-EDA工具课程之TCL市公开课获奖课件省名师优质课赛课一等奖课件_第4页
03-EDA工具课程之TCL市公开课获奖课件省名师优质课赛课一等奖课件_第5页
已阅读5页,还剩85页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

EDA技术试验工具命令语言(TCL)

ToolCommandLanguage1/90主要内容TCL介绍TCL语法TCL数据形态TCL结构TCL过程2/90CompanyLogo一、TCL介绍概述

Tcl(称为“工具命令语言”“ToolCommandLanguage”)是一个脚本语言。由JohnOusterhout创建。TCL很好学,功效很强大。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。TCL念作"tickle".特征

*全部数据类型都能够看作字符串,含有强大字符处理能力。

*语法规则相当简单。

*很轻易用C,C++,或者Java扩展。

*解释语言,代码能够动态改变。

*平台无关。Win32,UNIX,Mac

上都能够跑。

*代码紧凑,易于维护。TCL是当今EDA软件系统中普遍采取一个脚本语言,如SynopsysDC中dc_shell-t>和SynopsysPrimeTime中pt_shell>就是基于这种脚本,实际上TCL已经成为了一个工业标准。

3/90CompanyLogo二、TCL语法

语法

简单来说,TCL语法就是TCL解释器对TCL命令进行分析规则集合。TCL脚本可视为一个包含许多TCL指令(TCLcommand)程序。一个TCL指令基本语法为:commandarg1arg2arg3….在TCL语言中,每行指令第一个单字为指令名称空格符用来分隔指令名称与各个个别参数,个别指令分隔是以分号与换行符号作为分隔符。一个参数假如超出一个英文单字(字符串中间穿插空白或TAB键),可用双引号与大括号将这些元素组成(grouping)单一一个参数。使用双引号与大括号差异,在于TCL针对双引号中字符串会做置换处理(substitution),比如变量值代换或是执行包含于字符串中TCL指令(使用中括号来表示),而对于大括号所括住内容TCL则不会有这些置换处理。

4/90CompanyLogo二、TCL语法举例说明:setx4sety6putsx显示结果xputs$x显示结果4puts"$x+$y=[expr$x+$y]“显示结果4+6=10puts{$x+$y=[expr$x+$y]}显示结果$x+$y=[expr$x+$y]

5/90CompanyLogo二、TCL语法下表所列符号在TCL语言里有特殊意义:置换符号(substitutionsymbols)$:变量值置换符号。$符号用来取出指定变量值。底下利用set指令设定x变量值,并用puts指令输出x内容:setx5puts$x如上列最终一行程序代码,取出变数值时需在变量名称前加上$符号。[]:命令置换符号。TCL将中括号中内容视为一个指令,会执行其中指令并将结果传回。puts"$x+$y=[expr$x+$y]"在做完x与y两个变数置换后,TCL解译器碰到中括号认为其中为另一个可执行指令,指令名称为expr。在执行expr指令前,TCL先将x与y值置换后,传递给expr指令并呼叫执行之。expr指令用来做数学式子运算,会负责剖析参数并做数学运算。6/90CompanyLogo二、TCL语法群组(groupingsymbols)“”:双引号可将多个元素组成单一一个参数,引号内内容会被TCL进行置换处理,包含变量置换与命令置换。{}:大括号功效与双引号相同,但TCL不会对括号中内容做任何解释或处理,会照将括号中内容视为一个参数,照本宣科原原本当地传递给指令去处理。比如Demo1.tclL6:puts{$x+$y=[expr$x+$y]}因为TCL对大括号中内容不做任何处理,所以它输出为$x+$y=[expr$x+$y]。另外,TCL不会将大括号中换行符号视为一个指令结束,假如一个指令参数很长时,我们就能够利用大括号这么写,把换行符号当成是参数一部份:puts{$x+$y=[expr$x+$y]}7/90CompanyLogo二、TCL语法其它\:和Cbase语言一样,反斜线可将特殊字符做跳脱处理。比如\n代表换行符号。在TCL语言里,假如一个指令超出一行,亦可在行尾使用反斜线做为续行符号(VB指令假如超出一行,则是在行尾用底线符号代表续行)。;或者TAB键:代表一个TCL指令结束符号。#:批注符号。通常我们会在一行程序代码第一个字符打上#符号,以代表本行程序为批注。注意!假如在#符号前有TCL指令,必须像这么做:putshello;#hereiscomment在#符号前加上一个分号代表前面指令结束。假如不这么做,那TCL便会把#视为一个参数丢给puts指令去做处理。8/90CompanyLogo二、TCL语法变量TCL变量能够随时建立不用事先宣告,变量名称取法也没有任何限制,所以能够使用任何字符来为变量命名,甚至变量名跟指令名称相同也没问题。使用时只有一点要注意,就是TCL是大小写有别语言。通常,我们以set指令来设定变量值:setx5sety6setPI3.14setPI*26.28;#注意!变量名称是PI*2puts$PI*2setPITCL

set指令除了设定变量值用途外,也能够用来取出变量内容,如上列程序最终一行使用set指令取出PI值(注意!这边不用在变量名称前加上$符号)。unset指令用来删除一个或多个变量,来释放内存空间:unsetxyPI9/90CompanyLogo二、TCL语法置换与群组处理(SubstitutionandGrouping)底下是TCL置换处理与群组几点规则整理:1、TCL指令参数是以空格符分隔,能够使用双引号或大括号将多个元素组成一个参数。假如是以大括号组出一个参数,TCL不会对括住内容进行任何置换,在对应结束大括号出现前,任何字符都将视为参数一部份,包含换行符号、分号或是内部巢状大括号。2、假如是以双引号组出一个参数,则在对应结束双引号出现前,双引号中内容会被TCL进行置换动作。3、假如参数或是双引号内单字是以变量符号$为开头,则TCL为会进行变量置换。4、假如参数或是双引号中有中括号,则在对应中括号出现前,TCL会对中括号中内容进行指令置换。5、因为TCL是以空格符作为参数分隔符,所以要防止以下错误:if{$x>1}{puts$x}需要在此加上一个空格符,隔开if指令第二及第三个参数。

10/90CompanyLogo二、TCL语法TCL数学运算符

-~!「减号(Unaryminus)」/「NOT位运算(Bit-wisenot)」/「NOT布尔逻辑运算(Logicalnot)」。这些运算不能够用来操作字符串(string)操作数,而且「NOT位运算」只限于整数操作。*/%「乘(Multiply)」/「除(divide)」/「余数(remainder)」。这些运算不能够用来操作字符串(string)操作数,而且「余数」运算只限于整数操作。+-「加(Add)」与「减(subtract)」。限用于数值操作数。<<>>「左右移位运算(ShiftLeft/Right)」。运算只限于整数操作。<><=>=布尔运算「小于(less)」/「大于(greater)」/「小于等于(lessthanorequal)」/「大于等于(greaterthanorequal)」。假如条件成立这些运算子会产生「1」结果,不然产生「0」。11/90CompanyLogo二、TCL语法TCL数学运算符

==!=布尔运算「等于(equal)」/「不等于(notequal)」。每个运算会产生0/1结果。可适适用于任何操作数。&「AND位运算(Bit-wiseand)」。限于整数操作。^「XOR位运算(Bit-wiseexclusiveor)。限于整数操作。&&「AND布尔逻辑运算(Logicaland)」。假如参加两个操作数都非零话会得到1结果,不然话会得到0。限用于数值操作数(不限整数或小数)。||「OR布尔逻辑运算(Logicalor)」。假如参加两个操作数都是零话会得到0结果,不然话会得到1。限用于数值操作数(不限整数或小数)。x?y:z假如x为真时传回y不然传回z12/90CompanyLogo三、数据形态

TCL语言基本数据型态有:stringlistarrayhandle13/90CompanyLogo三、数据形态

String字符串数据型态字符串是TCL语言最基本数据型态,常见字符串处理指令有:string、append、format、scan以及binary。比如使用string指令来计算指定字符串长度:%setname“ZhangBin”%stringlength$name=>11其中string指令第一个参数代表对字符串操作方式。14/90CompanyLogo三、数据形态

string指令使用方法stringbytelengthstr传回字符串字节数(以UTF-8encoding计算),传回值可能会跟计算字符数stringlength有所不一样stringcompare?-nocase??-lengthlen?str1str2比较两字符串内容,若相同传回『0』、其它传回『1』。-nocase:表示不分大小写例:%stringcompare–nocaseRickrick=>0-length:能够指定要比较字符串长度例:stringcompare–length3rickricp=>015/90CompanyLogo三、数据形态

string指令使用方法stringequal?-nocase?str1str2比较str1和str2内容,若相同传回『1』、不然传回『0』stringfirstsubStringstringstartIndex传回string中相符子字符串第一个出现位置,若无则传回『-1』。startIndex代表从字符串指定位置开始搜寻子字符串。例:%stringfirstrickilovericktoo=>516/90CompanyLogo三、数据形态

string指令使用方法stringindexstringcharIndex传回index位置所在字符,index计算从『0』开始,使用『end』代表最终一个字符或使用『end-N』代表相对于最终一个字符位置。例:%stringindexrick2=>c%stringindexrickend=>k%stringindexrickend-2=>i17/90CompanyLogo三、数据形态

string指令使用方法stringlaststring传回string中最终一个与子字符串相符位置,若无则传回『-1』。startIndex代表从字符串指定位置开始搜寻子字符串。例:%stringfristrickrickANDrick=>0%stringlastrickrickANDrick=>7stringlengthstring传回字符串字符数18/90CompanyLogo三、数据形态

string指令使用方法stringmap?-nocase?charMapstring依据charMap中字符串对应表,更换字符串中内容。例:%stringmap{ic}rick=>rcck%stringmap{rija}rick=>jack%stringmap{rjia}rick=>jack19/90CompanyLogo三、数据形态

string指令使用方法stringmatch?-nocase?patternstr将字符串拿来与pattern比对,若是相同则传回『1』,若不一样则传回『0』。字符串比正确方式为globstylepatternmatch:?:表示一个任意字符*:表示随意数量任意字符。[]:表示中括号中集合一个任意字符,[abc]定义符合abc任意一个字符,[a-z]定义符合全部小写英文字母任意一个字符。\?:表示一个问号字符。例:%stringmatchtcl*tcltk=>1%stringmatchtcl*rick=>020/90CompanyLogo三、数据形态

string指令使用方法『?』表示一个任意字符。例:%stringmatchric?rick=>1%stringmatchri??rick=>1%stringmatchric?rickpeng=>0『[]』表示在中括号集合中任意一个字符。例:%stringmatch{[a-z]}rick=>0%stringmatch{[a-z][a-z][a-z][a-z]}rick=>121/90CompanyLogo三、数据形态

string指令使用方法stringrangestrij取出str字符串中从i到j位置字符。可用end字符代表最终一个字符。例:%setx[stringrangeiloverick25]=>overstringrepeatstrcount将str字符串重复印出count所表示次数。例:%stringrepeatrick3=>rickrickrick22/90CompanyLogo三、数据形态

string指令使用方法stringreplacestrfirstlast?newstr?以空字符串或newstr取代指定范围字符串。First与last分别为所要取代字符串其头、尾位置,newstr则为所欲代换成字符串,newstr预设为空字符串代表要截断指定范围字符串。例:%stringreplaceiloverick14hateihaterickstringtolowerstring?first??last?将所定义字符串范围中之字符转换为小写字符。例:%stringtolowerILOVERICK14=>IloveRICK23/90CompanyLogo三、数据形态

string指令使用方法stringtotitlestring?first??last?将所定义字符串范围中第一个字母转换成大写。例:%stringtotitleiloverick14=>iLoverickstringtoupperstring?first??last?将所定义字符串范围中之字符转换为大写字符。例:%stringtoupperiloverick14iLOVErick24/90CompanyLogo三、数据形态

string指令使用方法stringtrimstring?chars?去除指定字符串头、尾中包含在chars中定义任何字符。chars系统预设为空格符。例:%stringtrimililoverickricklilove%stringtrimkkkloverickkkkkrick=>lovestringtrimleftstring?chars?去除在string左侧包含在chars中定义任何字符,chars系统预设为空格符。例:%stringtrimleftilovericki=>loverick%stringtrimleftkkkloverickkkklk=>overickkkk25/90CompanyLogo三、数据形态

string指令使用方法stringtrimrightstring?chars?去除在string右侧包含在chars中定义任何字符,chars系统预设为空格符。例:%stringtrimrightiloverickrick=>ilovestringwordendstrindex传回指定str字符串中指定位置上单字下一个位置。例:%stringwordend{Iloverick}5=>626/90CompanyLogo三、数据形态

string指令使用方法stringwordstartstrindex传回str字符串中指定位置上单字起始位置。例:%stringwordstartiloverick9=>027/90CompanyLogo三、数据形态

string指令注意事项字符串比较尽可能使用stringcompare或stringequal,比如:if{[stringcompare$s1$s2]==0}{#s1ands2areequal}if{[stringequal$s1$s2]}{#s1ands2areequal}防止使用==来比较字符串,即使以下程序代码中,比较两个字符串有不一样内容,仍会输出ack讯息,这是因为TCL会试图将字符串转换为数字再进行比较,于是16进位0xa会等于十进制10,这可不是我们所期望结果,所以提议尽可能使用stringcompare或stringequal来取代这种写法:if{“0xa”==“10”}{puts“ack”}28/90CompanyLogo三、数据形态

append指令append指令用来将新项目附加到指定变量内容后。例:%setxii%appendxloveyouIloveyou29/90CompanyLogo三、数据形态

format指令与C语言中printf十分相同指令,format指令依据指定格式将字符串格式化。

formatspecvalue1value2其中spec参数包含了文字或是任何字符。而普通定义关键词包含了六大部份:位置指示(positionspecifier)旗标(flags)栏宽(fieldwidth)准确度(precision)字符长度(wordlength)转换字符(conversioncharacter)因为在格式定义时候常会有空白夹杂其中,切记要使用双引号或大括号将定义内容群组(Grouping)起来。30/90CompanyLogo三、数据形态

d:带正负号整数(Signedinteger)u:无正负号整数(Unsignedinterger)i:带正负号整数。表示成为hex(0x)或octal(0)o:无正负号八进制数值。(Unsignedoctal)xorX:无正负号十六进制数值。(Unsignedhexadecimal),x表示为输出小写结果。c:把数字对映成为ASCII字符s:字符串f:浮点数,格式为a.beorE:浮点数,格式为科学符号,a.bE+-cgorG:浮点数,格式为%f或%e,依实际长度取短表示31/90CompanyLogo三、数据形态

位置指示表示方法为i$,意思是直接取得第i个参数值。参数计数是从1开始。底下范例透过位置指示直接取用format第二个参数内容:

%format{%2$s}onetwothree=>two因为在TCL中,$符号有特殊意义,上列指令以大括号抑制了格式化字符串中$符号变量置换作用,所以i$功效得以正常演出。但假如格式化字符串是以双引号来做群组(grouping),我们必须利用反斜线仰制$符号变量置换:

%format“%2\$s”onetwothere=>two32/90CompanyLogo三、数据形态

scan指令与C语言中scanf十分相同指令,scan指令依据指定格式化条件剖析字符串并将结果放入变量中。

scanstringformat?varName??varName?…例:

%scan“a123Rick”charnumstr%puts“char=$charnum=$numstr=$str”=>char=97num=123str=rickscan指令与format指令非常相像,%c会将某个字符ASCII数值读入变数中。33/90CompanyLogo三、数据形态

Binary指令

binaryformattemplatevalue?value….?binaryscanvaluetemplatevariable?variable…?这边我们看看几个binary指令惯用使用方法。使用c为模板(template),将数值97格式化为ASCII字符:%binaryformatc97=>a使用c为模板(template),将字符6

ASCII值读进var1变数中:%setinput6%binaryscan$inputcvar1%setvar15434/90CompanyLogo三、数据形态

一次scan多个字符码到list中:

%binaryscanabcde“c3”list%setlist=>979899%lindexlist1;#取出list中第1个元素

=>98换个方式,scan到多个个别变量中:

%binaryscanabcde“ccc”xyz%puts“x=$xy=$yz=$z”%x=97y=98z=9935/90CompanyLogo三、数据形态

List串行数据型态TCL

list指令有list,lindex,llength,lrange,lappend,linsert,lreplace,lsearch,lset,lsort,concat,join,andsplit等,提供您将数据放入list、取出list中元素、计算list元素数量、取代list中指定元素等等功效。通常我们会搭配foreach使用,将list中元素一一取出做运算。然而,在表现比较复杂数据结构时,list并不是最好选择方案,在这些场所里使用TCL

array型态会比list愈加适合。36/90CompanyLogo三、数据形态

listarg1arg2…..将list指令参数将建组成一个list。例:%listricktest=>ricktest用set指令建构一个list:%setmylist{ricktest}=>ricktest37/90CompanyLogo三、数据形态

lindexlisti传回在list之中第i个项目标内容。能够指定多个index,以取出巢状list中项目。例:%setx{rick}=>rick%lindex$x2=>c38/90CompanyLogo三、数据形态

llengthlist传回在list之中项目数。例:%setx{rick}=>rick%llength$x=>439/90CompanyLogo三、数据形态

lrangelistij传回list之中从i至j项目。例:%setlist{tpts1}=>tpts1%sety[lrange$list12]=>pt40/90CompanyLogo三、数据形态

lappendlistVarargarg…..附加项目到listVar之后例:%setlistrick=>rick%lappendlistiloveyou=>rickiloveyou41/90CompanyLogo三、数据形态

Linsertlistindexargarg..将数据插入在第i个项目之前。例:%setlist{iloverick}=>iloverick%linsert$list1really=>ireallyloverick42/90CompanyLogo三、数据形态

lreplacelistijargarg…将list中从i到j个项目取代为指定参数。lreplace传回取代后新list。例:%setlist{iloverick}=>iloverick%setlist2[lreplace$list11hate]=>ihaterick43/90CompanyLogo三、数据形态

lsearch?options?listpattern传回与pattern比对相符合第一个元素位置,传回-1假如没有相符元素。预设比对方式为Glob。例:%setlist{iloverick}=>iloverick%lsearch$listlove=>144/90CompanyLogo三、数据形态

lsetlistVarindex?index…?value使用value设定list第i个元素值。例:%setlist{iloverick}=>iloverick%lsetlist1hate=>ihaterick45/90CompanyLogo三、数据形态

lsort?switches?list依据switch所指定选项为list排序。可用选项有-ascii,-dictionary,-integer,-real,-increasing,-decreasing,-indexix,-unique,-commandcommand.。例:%setlist[listmaacxlinognoc]%lsort$list=>cxlinmaaognoc46/90CompanyLogo三、数据形态

concatlistlist…将多个list串成一个。例:%setlist1[list1maa]%setlist2[list2cxlin]%setlist3[list3ognoc]%setlistAll[concatlist1list2list3]%llength$listAll=>647/90CompanyLogo三、数据形态

joinlist?joinString?将list中项目合并成一个字符串。能够指定joinString作为每个项目间分隔,预设分隔字符为空白。例:%setlist[listiloverick]%join$list=>iloverick%join$list###=>i###love###rick48/90CompanyLogo三、数据形态

splitstring?splitchars?将字符串分割成一个list。可以指定splitChars作为字符串中每个项目分隔识别符号。例:%setlist[split”abc”]%length$list=>3%setlist[split“a#b#c”“#”]=>abc%lrange$list0end=>abc49/90CompanyLogo三、数据形态

Array数组数据型态TCLarray和Perl

associativearray类似,数组是以字符串作为索引。数组在TCL语言中举足轻重,许多数据结构都是以数组为基础设计而成。数组元素内容设定一样是使用set指令:%setprice(apple)10%setprice(orange)12%setquantity(apple)5%setdiscount(apple)0.8puts$price(apple)=>1050/90CompanyLogo三、数据形态

arrayexistsarr

判断arr是否为一个数组。传回1代表是数组。例:%setprice(apple)10%arrayexistsprice=>151/90CompanyLogo三、数据形态

arraygetarr?pattern?将arr索引及元素值交织建立成一个list后传回。能够使用样式(Pattern)来做比对。例:%setprice(apple)10%setprice(orange)12%arraygetprice=>orange12apple1052/90CompanyLogo三、数据形态

arraynamesarr?mode??pattern?传回arr索引list。能够使用mode指定样式比对方式(可为–exact、-glob(default)或–regexp)。例:%arraynamesprice=>orangeapple53/90CompanyLogo三、数据形态

arraysetarrlist依据list内容建构一个数组。例:%arraysetprice[listapple10orange12]%arraygetprice=>orange12apple1054/90CompanyLogo三、数据形态

arraysizearr传回arr大小。例:%arraysizeprice=>255/90CompanyLogo三、数据形态

arrayunsetarr?pattern?判断arr是否为一个数组。传回1代表是数组。释放符合样式数组元素。假如没有指定样式,则会释放整个数组。例:%arraysetprice[listapple10orange12]%arraygetprice=>orange12apple10%arrayunsetpriceapp*%arraygetprice=>orange12%setprice(apple)10%arraygetprice=>orange12apple10%arrayunsetprice%setprice=>can'tread"price":nosuchvariable56/90CompanyLogo三、数据形态

数组也常拿来与foreach循环搭配使用,比如:%setprice(apple)10%setprice(orange)12%arraygetprice=>orange12apple10%foreach{keyvalue}[arraygetprice]{“price($key)=$value”}=>price(orange)=12=>price(apple)=10或者这么写,程序结果也会一样:%foreachkey[arraynamesprice]{“price($key)=$price($key)”}57/90CompanyLogo三、数据形态

因为使用arrayget或foreach时,TCL作法是先产生一个暂时性list,这么会浪费一些内存空间与执行速度。改用array搜寻功能够加紧数组元素巡访(iterate)速度:%setsearchToken[arraystartsearchprice]%while{[arrayanymoreprice$searchToken]}{setkey[arraynextelementprice$searchToken]setvalue$price($key)puts“$key=$value”}arraydonesearchprice$searchToken=>orange=12=>apple=1058/90CompanyLogo四、控制结构如同先前TCL语法一节所介绍,对TCL来说每条叙述(Statement)都只是一个指令与传递给指令参数,其中每个指令第一个英文单字为指令名称。本节所要介绍控制结构,包含循环指令:while、for、foreach;条件判断用指令:if及switch;错误处理用指令:catch;以及饰演配角一职用来调整控制结构用指令:break、continue、return与error等等,实际上在TCL语言中,这些控制结构也都是指令。这些控制结构通常在一些条件成立时,会执行其指令主体程序代码(commandbody),比如:setx2sety3if{$x<$y}{puts“xislessthany!”}。59/90CompanyLogo四、控制结构我们知道在TCL语言中,大括号能够把多个元素(也就是很长字符串)群组起来变成一个参数。所以,以指令观点来看上列if指令可知,if指令接收两个参数,其中第一个参数是一个条件叙述,只有在此条件成立情况下,指令主体(commandbody),也就是if指令第三个参数,才会被if指令当成是一段TCLScript把它触动执行之。我们也知道换行符号与分号是代表一个指令结束,假如一个指令参数太长时,能够利用大括号括住参数,把换行符号也看成是参数一部份。在控制结构中,指令主体写法通常都会和上列if指令一样,使用大括号括住。这么做有两个好处,第一是我们能够在指令主体中写很多行叙述,而这些叙述会被大括号群组起来变成一个参数传给if指令,第二则是使用大括号能够防止TCL解译器在执行if指令前,就先进行置换处理,产生非预期结果。60/90CompanyLogo四、控制结构IfThenElseIf指令是最基本控制结构,它语法是:ifexpression?then?body1?else??body2?if指令在条件测试(expression)结果为真是执行指令主体(body1),不然执行另一个指令主体(body2)。比如:if{$x>0}{puts“xisgreaterthanzero!”}else{puts“xislessthanzero!”}你能够省略then跟else两个关键词,但像上面写法一样我们通常只省略then。另外在条件测试和指令主体两参数,提议养成习惯用大括号将它他们括住。61/90CompanyLogo四、控制结构当你需要判断一连串条件时,能够使用if搭配elseif指令:if{$temperature<24}{puts“It’scool!”}elseif{$temperature<30}{puts“It’salittlehot!”}else{puts“It’squitehot!”}然而,假如要判断条件式很多,能够选择使用底下要介绍switch指令62/90CompanyLogo四、控制结构Switchswitch指令可用来比对许多样式(patternmatching),并执行符合样式字符串指令主体。switch语法为:switchflagsvaluepattern1body1pattern2body2…?defaultdefaultBody?只有第一个样式比对符合指令主体会被执行,其它则会被忽略。能够在switch指令最终加上一个default样式,代表假如没有任何一个样式比对符合话,就执行default指令主体。你能够设定switch指令flags,指定字符串样式比对方法:-exact:使用完全相符样式比对方法。即要比正确value与比正确样式字符串完全相同才算比对成功。-glob:使用globstyle样式比对方法。请参考数据型态一节相关stringmatch说明。globstyle样式比对是switch指令预设比对方法。-regexp:使用『常规表示式(RegularExpression)』样式比对方法。相关常规表示式请见后述。--:代表switch指令flag设定已结束,接着下一个字符串是要被比正确字符串(value)。使用--允许value是以-符号开头字符串。通常我们会在value字符串前加上这个flag。63/90CompanyLogo四、控制结构值得注意一点是,switch样式比对有没有使用大括号括住影响,我们直接从底下范例程序及执行结果来看:setx5sety5switch-glob--$x\$y{puts“x=y”}\{[0-9]}{puts“x=5”}\default{puts“x>10”}switch-glob--$x{$y{puts“x=y”}[0-9]{puts“x=5”}default{puts“x>10”}}执行结果为:x=yx=564/90CompanyLogo四、控制结构While指令语法:whilebooleanExprbodywhile指令有两个参数,一是条件测试,一是指令主体。while指令会不停判断条件叙述,并在条件测试结果为真时,执行指令主体。以下程序会开启autoexec.bat档,读取档案中内容并输出到Console中,程序中gets指令会从指定档案读取一行数据,并传回读取到字符数,读到档案尾时传回-1:setfileId[openc:/autoexec.batr]while{[gets$fileIdline]>=0}{putsstdout$line}close$fileId65/90CompanyLogo四、控制结构在使用while指令时要注意TCL置换处理,比如底下程序会是一个无穷循环,因为TCL在执行while指令前,已将$i代换为0才传递给while指令作为参数,所以while指令条件测试结果永远为真:seti0;while$i<10{incrI}要防止请保持良好写码习惯(codingstyle),使用大括号来防止TCL置换,防止非预期错误:seti0;while{$i<10}{incrI}66/90CompanyLogo四、控制结构For指令语法:forinitialtestfinalbodyTCLfor指令和C语言相类似,for指令需要四个参数。第一个参数用来设定循环起始状态,比如计数值起始设定,第二个参数用来做条件测试,第三个参数是循环指令主体(body)每执行一次后要做事,通常我们会在这边增减计数值。底下范例使用循环印出三次当前时间:for{setx1}{$x<=3}{incrx}{puts[clockformat[clockseconds]-format{%D%T}]}=>06/22/0422:04:10=>06/22/0422:04:11=>06/22/0422:04:1267/90CompanyLogo四、控制结构其中clockseconds会以秒数为单位传回当前时间,clockformat则用来将指定时间进行格式化,本例格式化字符串为{%D%T}代表输出时间格式为%m/%d/%y%H:%M:%S。另外after指令会让程序停留一段时间后继续进行,停留时间单位为千分之一秒(millisecond)。之前while指令读取档案内容范例,能够用for指令改写成(能够看到此处于for指令initial与final两个参数都是空):setfileId[openc:/autoexec.batr]for{}{[gets$fileIdline]>=0}{}{putsstdout$line}close$fileId使用for指令来巡访(iterate)一个list,印出list中内容:for{seti0}{$i<[llength$list]}{incri}{puts[lindex$list$i]}68/90CompanyLogo四、控制结构但使用for指令巡访list并不是好写法,它效率不是很好,因为for指令需要不停呼叫llength及lindex去取得list状态。比很好方案,是选择使用foreach指令。Foreach指令语法:foreachlistVarlistbodyforeach指令主要用于list巡访(iterate),来看一个数列加总写法:settotal0setnumList[list12345678910]foreachnum$numList{settotal[expr$total+$num]}putsstdout“total=$total”=>total=5569/90CompanyLogo四、控制结构foreach指令也可针对一个list,设定多个循环变量来处理之,比如:foreach{keyvalue}{apple10orange12}{puts“$key=$value”}=>apple=10=>orange=12对于数组,可先让arrayget指令将数组索引与值变成一个list后传回,再拿给foreach指令利用:setprice(apple)10setprice(orange)12foreach{keyvalue}[arraygetprice]{puts“$key=$value”}=>orange=12=>apple=1070/90CompanyLogo四、控制结构break与continuebreak指令和continue指令用于循环结构中,break用来中止循环,而continue则用来让循环进行下一个重复(iteration)。71/90CompanyLogo四、控制结构Catch指令语法:catchcommand?resultVar?当TCL指令发生错误时,比如使用open开启档案失败,TCL会中止当前执行TCLScript。我们能够使用catch指令来补捉这些错误,catch指令会执行指定指令,假如指令没有发生错误,则catch指令会将指令传回值放入第二个参数,或是在指令发生错误时将错误讯息放入第二个参数。假如没有捕捉到任何错误,catch指令本身传回值会是0,不然会传回非0数值。我们将前面读取档案内容加上catch指令,让程序更严谨一些防止执行到二分之一便被TCL中止执行:if{[catch{openc:/autoexec.batr}fileId]}{puts“openingfileerror:$fildId”}else{while{[gets$fileIdline]}{puts$line}close$fileId}72/90CompanyLogo五、TCL过程

TCL程序跟普通程序语言程序一样,是程序模块化工具,当你定义好一个procedure时,它就会变成一个TCL指令。TCL使用proc指令来定义一个procedure:procprocNameargListbodyproc指令第一个参数是procedure名称,第二个参数是procedure参数列,第三个参数则是procedure指令主体,会在procedure被呼叫时执行起来。关于程序传回值,除非你用return指令明示程序传回值,不然TCL会将程序最终一行指令执行结果当做是程序传回值。比如定义圆面积procedure:setPI[expr2*asin(1.0)]procc_area{rad}{globalPIreturn[expr$PI*$rad*$rad]}%c_area3=>28.2743338823

73/90CompanyLogo五、TCL过程过程定义和返回值比如:%procadd{xy}{expr$x+$y}proc命令第一个参数是你要定义过程名字,第二个参数是过程参数列表,参数之间用空格隔开,第三个参数是一个TCL脚本,代表过程体。proc生成一个新命令,能够象固有命令一样调用:%add123

在定义过程时,你能够利用return命令在任何地方返回你想要值。return命令快速中止过程,并把它参数作为过程结果。比如:%procabs{x}{if{$x>=0}{return$x}return[expr-$x]puts“procabsfinished”}过程返回值是过程体中最终执行那条命令返回值。

74/90CompanyLogo五、TCL过程局部变量和全局变量对于在过程中定义变量,因为它们只能在过程中被访问,而且当过程退出时会被自动删除,所以称为局部变量;在全部过程之外定义变量我们称之为全局变量。TCL中,局部变量和全局变量能够同名,二者作用域交集为空:局部变量作用域是它所在过程内部;全局变量作用域则不包含全部过程内部。这一点和C语言有很大不一样.

假如我们想在过程内部引用一个全局变量值,能够使用global命令。比如:%seta44%procsample{x}{ globala incra return[expr$a+$x]}%sample3875/90CompanyLogo五、TCL过程%seta5

全局变量a在过程中被访问。在过程中对a改变会直接反应到全局上。假如去掉语句globala,TCL会犯错,因为它不认识变量a.

76/90CompanyLogo五、TCL过程缺省参数和可变个数参数TCL还提供三种特殊参数形式:首先,你可以定义一个没有参数过程,例如:procadd{}{expr2+3}其次,可以定义具有缺省参数值过程,我们可认为过程部分或全部参数提供缺省值,如果调用过程时未提供那些参数值,那么过程会自动使用缺省值赋给对应参数。和C\C++中具有缺省参数值函数一样,有缺省值参数只能位于参数列表后部,即在第一个具有缺省值参数后面全部参数,都只能是具有缺省值参数。例如:procadd{val1{val22}{val33}}{ expr$val1+$val2+$val3 }则:add1//值为6add220//值为25add456//值为1577/90CompanyLogo五、TCL过程另外,TCL过程定义还支持可变个数参数,假如过程最终一个参数是args,那么就表示这个过程支持可变个数参数调用。调用时,位于args以前参数象普通参数一样处理,但任何附加参数都需要在过程体中作特殊处理,过程局部变量args将会被设置为一个列表,其元素就是全部附加变量。假如没有附加变量,args就设置成一个空串,下面是一个例子:

procadd{val1args}{setsum$val1 foreachi$args{ incrsum$i }return$sum }则:

add2//值为2 add23456//值为20

78/90CompanyLogo五、TCL过程其中我们也定义了一个全域变量PI,接收一个参数rad作为半径。程序在procedure外使用expr及TCL内建数学函式asin计算圆周率PI,并在c_area程序中使用这个全域变量来计算圆面积。值得注意一点时,在程序变量空间(Scope)预设是看不到全域变量,假如要在程序中存取全域变量,则必须先使用global来宣告才行。我们也能够指定程序参数默认值(defaultvalue),比如底下修改后c_area程序在没有参数情况下,会将rad参数默认值设成1:setPI[expr2*asin(1.0)]procc_area{{rad1}}{globalPIreturn[expr$PI*$rad$rad]}%c_area3=>28.2743338823%c_area=>3.1415926535979/90CompanyLogo五、TCL过程我们也能够定义可接收不定参数程序,透过args这个关键词(TCL会将接收到参数变成一个list放入args变数中):procprintArgs{args}{puts“Totalarguments:[llength$args]”puts“Theargumentlist=[lrange$args0end]”}%printArgs=>Totalarguments:0=>Theargumentslistare:%printArgsonetwothree=>Totalarguments:3=>Theargumentslistare:onetwothree80/90CompanyLogo五、TCL过程在TCL语言里,我们甚至能够使用rename指令将一个指令重新命名,比如将TCLunknown指令更名为originalUnknown:renameunknownoriginalUnknown接着我们能够自行定义unknown,替unknown订定新行为,有需要时再呼叫originalUnknown,这么对原本呼叫unknown使用者来说,会完全转移到新定义unknown。另外,你也能够使用rename指令将现有指令定义成空字符串,如此一来,指令就会不存在。比如,我们将exec指令定义成空字符串,这么使用者便不能用exec执行其它程序:renameexec{}81/90CompanyLogo五、TCL过程任何一个Tcl命令都能够被重命名或者删除,包含内建命令以及应用中定义过程和命令。重命名一个内建命令可能会很有用,比如,exit命令在Tcl中被定义为马上退出过程。假如某个应用希望在退出前取得去除它内部状态机会,那么能够这么作:

renameexitexit.oldprocexitstatus{application-specificcleanup...exit.old$status}82/90CompanyLogo六、TCL内建指令after等后一段时间后执行指定指令append附加参数内容到指定变量之后array用来查询数组状态及搜寻数组元素binary用来做字符串与二进制数据转换break用来中止循环catch补捉错误cd变更工作目录clock用来取得时间及设定时间输出字符串格式close用来关闭I/O串流(stream)concat用来将多个参数串成一个list,或是将多个list合成一个。console用来控制输入命令用主控台(Console)continue让循环进行下一个重复(iteration)error引发一个错误eof用来检验档案是否

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论