一、腳本、命令和單詞符號
一個TCL腳本可以包含一個或多個命令。命令之間必須用換行符或分號隔開。
1、關鍵字/變量
變量是程序的基礎
變量組成:變量名、變量值
變量名要求:任何字符串都可以作為變量名,區分大小寫
變量值要求:任何字符串都可以作為變量值
⦁ 變量賦值基本語法:
set varname value;
e.g:
set x 10;
set text “Hello,World”
2、置換
TCL解釋器在分析命令時,把所有的命令參數都當作字符串看待,例如
set x 10; #定義變量x,並把x的值賦為10
set y x+100;#定義變量y,y的值是x+100,而不是我們期望的110
上例中的第二個命令中,x被看作字符串x+100的一部分,如果我們想使用x的值'10',就必須告訴TCL解釋器:我們在這里期望的是變量x的值,而非字符'x'。怎么告訴TCL解釋器呢,這就要用到TCL語言中提供的置換功能。
TCL提供三種形式的置換:變量置換、命令置換和反斜杠置換。每種置換都會導致一個或多個單次本身被其他的值所代替。置換可以發生在包括命令名在內的每一個單詞中,而且置換可以嵌套
set x 10
⦁ 變量置換
變量置換由一個$符號標記
set y $x+100; #y的值為10+100,這里x被置換成它的值10;
⦁ 命令置換
命令置換是由[]括起來的TCL命令及其參數
set y [expr $x+100]; #y的值為110;
y的值是110,這里當TCL解釋器遇到字符'['時,它就會把隨后的expr作為一個命令名,從而激活與expr對應的C/C++過程,並把'expr'和變量置換后得到的'10+100'傳遞給該命令過程進行處理。
注意:[]中必須是一個合法的TCL腳本,長度不限。[]中腳本的值為最后一個命令的返回值,例如:
set y [expr $x+100;set b 300]; # y的值為300,因為set b 300的返回值為300
⦁ 反斜杠置換
set y \$x+100;#y的值為$x+100;
⦁ 釋放變量:
unset x;
3.雙引號和花括號
TCL提供另外兩種方法來使得解釋器把分隔符和置換符等特殊字符當作普通字符,而不作特殊處理,這就要使用雙引號和花括號({}).
TCL解釋器對雙引號中的各種分割符將不作處理,但是對於換行符以及$和[]兩種置換符會照常處理。例如
set x 100
set y "$x ddd"; # y的值為100 ddd
而在花括號中,所有特殊字符都將成為普通字符,失去其特殊意義,TCL解釋器不會對其作特殊處理。
set y {/n$x [expr 10 +100]}; #y的值為/n$x [expr 10 +100]
4.注釋和輸出
TCL中的注釋符是‘#’,‘#’和直到所在行尾的所有字符都被TCL看作注釋,TCL解釋器對注釋將不作任何處理。
不過,需要注意的是,“#”必須出現在TCL解釋器期望命令的第一個字符出現的地方,才被當作注釋。例如:
set a 100 # Not a commnet
上述命令不是一個注釋,會報錯
set a 100; # this is a comment
上述才是一個有效的注釋
第一個命令中“#”不被當作注釋符,因為它出現在命令行的中間,TCL解釋器把它和后面的字符當作命令參數處理,從而導致錯誤。而第二個命令中“#”就被當作注釋,因為前一個命令已經使用了一個分號結束,TCL解釋器期望下一個命令接着出現,現在這個位置出現“#”,隨后的字符就被當作注釋了。
puts :輸出文本,多個單詞如被空格或TAB分隔需要使用“”或{} 括起來;多個命令寫在一行使用 ; 間隔。
puts Hello # 正確
puts Hello,World ; # 正確,多個單詞之間不是被空格或者TAB分隔開
puts Hello World; # 這行命令運行出錯,被空格分隔
puts "Hello, World - In quotes" ; # 注釋
puts {Hello, World - In Braces}
puts "This is line 1"; puts "this is line 2"; # 正確,用分號分隔兩個命令
puts "Hello, World; - With a semicolon inside the quotes" ; #正確,分號在雙引號內,作為字符串一部分
二、數據類型
tcl的數據類型實際上只有一種:字符串
在tcl中變量沒有類型轉換或者類型匹配的問題,所有的“數據”都是以字符串的形式存在,那么tcl如何進行數值計算?如何輸出一個小數?
數值計算:
tcl支持各種數學函數的數值計算,但是僅能在expr命令中使用
e.g:
set angle 30;
set radian [expr $angle*3.1415926/180.0];
set value [expr sin($radian)];
value值為0.499999992265;
數據類型輸出
在輸出數據到文件或者屏幕時,format命令可以用於控制顯示的格式確保它按要求輸出。
e.g:
set vlaue1 [format %.1f $value];
value1的值為0.5;
三、數據結構-List
List是tcl語言里功能給常強大非常靈活的應用最多一種數據結構之一,一個列表可以有任意多個元素,每一個元素都可以是任意的字符串,最簡單的列表就是包含由任意個空格、制表符、換行符分隔開的任意多個元素的字符串。
e.g:
john anne mary jim;
創建一個列表
set x [list 1 2 3 4];
按指定分隔符將一個字符串拆分為列表
set string “1,2,3,4”;
set x [split $string “,”];
從列表中取出一個元素
set value1 [lindex $x 0];
set value2 [lindex $x 1];
set value3 [lindex $x 2];
set value4 [lindex $x 3];
四、數據結構-Array
在Tcl中,除了簡單變量,還提供了數組,數組是元素的幾何,每一個元素都有自己的名稱和值。數組由兩部分組成,即數組名和數組中的元素名,數組名和元素名都可以是任意字符串,因此在使用過程中一定要注意區分空格、雙引號等字符。
創建數組
set student(name) “張三”;
set student(age) 15;
set student(gender) “男”;
查詢數組
array size student;查詢數組student中的元素個數
array names student;查詢數組student的元素名稱
多維數組
set grade(jim,chinese,english) [list 98 99];
set grade(peter,chinese,english) [list 96 100];
五、控制結構
控制結構有很多種類,包括條件、循環、異常處理、底層的條件處理等。
常見控制語句 |
解釋 |
if {expression} {body1} else {body2}; if {expression1} {body1} elseif {expression2} {body2} |
條件執行語句,其中的else 或者else if並不是必須存在的 |
foreach value valuelist {body} |
valuelist是一個鏈表數據,該命令將遍歷valuelist中的每一個值,每遍歷一次執行一邊body |
switch $var {a {body1};b {body2};c {body3}} |
用一個值與很多模式比較,執行能匹配的那個模式所對應的body |
for {init} {test} {reinit} {body} |
將init作為初始量,將test作為表達式,如果為真則執行body,然后再講reinit作為初始量重復執行該過程。 |
while {test} {body} |
將test作為表達式處理,如果其值為真,則執行body,然后再處理test重復這個過程 |
return |
結束一個函數返回value值 |
break |
用於終止最內層的循環 |
continue |
用於終止最內層循環的當前迭代步,進行該命令的下一個迭代步 |
catch {body} |
命令異常處理,當沒有異常是返回值為0,否則返回非0值 |
六、程序結構
source :可以把一個外部的tcl文件在此處展開執行
global :指定某些變量是全局可用的。在tcl中,主程序里的變量並不是全局可用的,必須在出程序或過程里用global聲明后,才能在過程里引用。
proc :說明一個子過程,后面接過程名、參數列表、執行體。需要注意的是,過程的參數列表應該和調用處的參數一致。但例外的是,如果過程的參數只寫一個,它就可以以list的形式接收多個入口參數。
proc講解:
1. 格式:proc name args body
2. 調用方法中參數可以用花括號或者雙引號包含,也可以不包含
3. 在puts等命令中需要置換的話,需要使用方括號
例子:012_proc.tcl
proc sum {arg1 arg2} {
set x [expr $arg1+$arg2];
return $x ;#過程返回值
}
puts " The sum of 2 + 3 is: [sum 2 3]\n\n" ;#調用過程
#puts " The sum of 2 + 3 is: [sum {2 3}]\n\n" ;#出錯,提示找不到第二個參數,置換過程中第一個參數是{2 3},所以找不到第二個參數
puts " The sum of 2 + 3 is: sum(2 3)\n\n" ;#輸出sum(2 3),因為沒有方括號,根本沒有進行置換
puts " The sum of 2 + 3 is: sum{2 3}\n\n" ;#輸出sum{2 3},因為沒有方括號,根本沒有進行置換
sum 2 3 ;#正確
sum {2} {3} ;#正確
sum "2" "3" ;#正確
過程PROC的參數定義
講解:
1. 過程的參數賦缺省值:proc name {arg1 {arg2 value}}
2. 過程的不確定個數的參數定義:proc name {arg1 args}
proc example {first {second ""} args} { ;#參數定義:賦缺省值和不確定個數參數定義
if {$second == ""} {
puts "There is only one argument and it is: $first";
return 1;
} else {
if {$args == ""} {
puts "There are two arguments - $first and $second";
return 2;
} else {
puts "There are many arguments - $first and $second and $args";
return "many";
}
}
}
set count1 [example ONE]
set count2 [example ONE TWO]
set count3 [example ONE TWO THREE ]
set count4 [example ONE TWO THREE FOUR]
puts "The example was called with $count1, $count2, $count3, and $count4 Arguments"