變數是大部份程式語言都會提供的功能,你可以把變數想像成是一塊儲存資料的空間,它可以讓你儲存程式執行時的資料。在這篇文章裡我們將介紹Tcl的變數相關命令及作用範圍的觀念。雖然說明的方法可能不是很正式,但觀念上是正確的。
2.1 設定變數
一般來說變數的操作不外乎就是「設定」、「取用」及「清除」這三種。其中設定是指把資料存入變數,取用是指由變數中取出資料,最後的清除是指釋放變數或是銷毀變數。接下來就讓我們要先來看設定變數的方法。在Tcl的世界裡你可以使用set命令來設定變數,例如,下面的程式設定了一個名稱叫birthday的變數,而且把字串「11/15」儲存進去。請先注意到set後面的第一個欄位,它的功能主要是用來指定變數的名稱。在這個例子中birthday就是一個變數的名稱,你可以想像變數名稱就像是一塊儲存空間的名牌,依據這個名牌,往後你才能夠正確的找出儲存在裡面的資料,或是釋放這塊空間。另外在Tcl裡變數的名稱是不能夠亂取的,而是需要遵守一些命名的規則,否則會導致語法上的錯誤。
關於變數命名的規則是這樣子的。首先我們需要了解Tcl會區分大小寫,所以說dai和Dai是指不一樣的兩個變數。然後,變數的名稱裡請不要出現奇怪的符號,要儘量使用英文字母、數字或底線來構成變數的名稱,而且要儘量讓字面上看起來是有意義的,最好是看到名稱就知道變數裡面儲存了什麼樣的資料。最後一點儘量不要用全部大寫的字母來組合變數名稱,因為全部大寫字母組成的變數名稱,通常具有特殊的意義,它可能被用來儲存系統的重要資料,或是不希望被隨便修改的資料。
§ 關於變數的命名
事實上Tcl對於變數的命名幾乎沒有什麼限制,你可以非常自由的使用任何的文字串、符號甚至是關鍵字來命名,而且Tcl真的允許你這麼做。但對於一個有經驗的程式設計師,他通常只會使用底線、數字及英文字母來組成變數的名稱,而且變數的名稱儘可能有意義,事實上大家也都建議這麼做。
正常的情況下,你可以使用set去設定非常多的變數,Tcl並沒有限制你變數的上限數量。例如:下面的程式設定了三個變數,分別是name、birthday及phoneNumber。
在上面的例子裡,每個打算儲存進變數裡的資料都用雙引號夾了起來。實際上如果它們的內容沒有包含「空白」字元,雙引號是可以省略的,例如,下面的寫法也是正確的。
但是,如果要存入的資料有包含「空白」字元,那麼就一定要加上雙引號。例如,下方是錯誤的寫法,因為set後面最多只能跟隨兩個參數,但下面的程式會被判斷為3個參數,所以是不正確的用法。
正確的寫法應該像下面一樣:
§ 關於變數的使用
雖然說正常的情況下你可以拚命的設定變數,但說真的還是省省用的好,除非你嫌記憶體太多或太便宜。另外一點,對於已經用set設定過的變數,同樣可以用set來重新設定變數的值。
2.2 取出變數的內容
一旦設定好變數後,接下來就可以任意次數的使用它。取用變數裡的資料是很容易的,只需要在變數名字的前方多加上一個「$」符號就可以了,例如,使用puts命令來輸出變數的內容:執行程式後應該會有如下的輸出:
11/15 dai 0938938938
Tcl有一個很方便的方法可以讓你在某一個文字串中插入已經設定好的變數。例如,下面的程式把name、birthday及phoneNumber三個變數夾在一串中英文組成的字串中輸出:
輸出的結果是:
Hi! 我是 dai 出生於 11/15 號,電話是 0938938938 有空call我哦!!
§ 為什麼要使用變數
剛開始使用變數的初學者時常會有一個疑問,「為什麼要使用變數?直接使用原來的文字串不好嗎?」。嗯~這是個好問題。其實有些資料不是在寫程式時就可以知道的。例如,程式執行到一半的時候請使用者輸入的資料,或是某些程式碼產生的運算結果。這些資料都是要等到程式執行時才可以決定的,所以我們沒辦法在寫程式的時候,就把這些資料直接寫在程式裡,唯一的方法就只有透過變數記下它們然後操作它們了。另外你也可以用另一個角度思考。如果你寫了一個10000行的程式,裡面總共出現了100次電話號碼,也就是說有100個0938938938散落在這10000行之中,假設有一天你換了電話號碼,那你就需要在這一堆程式碼中找出舊的電話號碼,然後一一修改,雖然你可以用文字編輯器的取代來處理,但難保不會有什麼意外。若改用變數的話,那就變成只需要修改儲存電話號碼的變數就好了,這樣有效率多了。所以就算是寫程式時就知道的資料,有時透過變數來操作資料也會有一定的好處。
2.3 清除變數
清除變數的功能可以讓你釋放變數佔用的記憶體,然後一併清掉變數裡的資料,如果你真的確定不需要用到某些變數了,可以使用unset命令來清除變數:上面的例子把之前設定的name、birthday、phoneNumber等3個變數給清除掉。清掉以後就不可以再取用它們了,除非你重新設定它們的值,才可以再度使用。
§ 關於清除變數
一般來說你不需要在程式結束前手動把變數清除掉,正常的情況下Tcl會在你的程式結束前自動的處理善後動作。
2.4 變數的作用範圍
為了讓變數的使用更有彈性,Tcl提供了一套機制讓程式設計者可以決定每一個變數的作用範圍,這麼做的目的主要是為了避免多人一起開發程式時,不小心用到相同的變數名字,而導致程式發生錯誤。其主要觀念是:「在不同的變數作用範圍裡,就算是一樣的變數名字,它們還是屬於不同的個體,彼此不會互相影響」。變數作用範圍的建立及使用方法以後會慢慢的出現,目前我們只需要記得兩個重點:- 凡是以兩個冒號開頭的變數名字(變數名字中間沒有出現其它的雙冒號),即表示是一個全域性的變數在任何地方都可以使用它。
- 沒有使用兩個冒號開頭的變數名字,即表示是區域性質的變數,它只可以用在特定的程式區塊,一但離開了所屬的區域就會被自動清除。
下面的例子說明建立全域變數的方法。var1以雙冒號開頭所以它是一個全域的變數,而var2則是一個區域性質的變數。
全域變數的取用和清除方法和普通變數是一樣的,所以你同樣可以冠上「$」字符號取出它的值,或用unset清除它。提醒一點。第3、4行「;#」後面的都是註解,不是程式。
2.5 全域變數的程式範例
接下來我們要來寫一個簡單的問安程式,這個程式可以讓你輸入姓名,然後按下按鈕後,它會跟你問好。2.5.1 問安程式
程式執行後會出現一個文字輸入方塊及一個按鈕,你可以在文字方塊上輸入你的姓名,然後按下"Say Hello"按鈕,然後這個程式就會向你問安。
圖 2-1 問安程式
2.5.2 程式說明
第1行的entry是Tcl/Tk製作單行輸入方塊的命令。其中.txtName是指定給文字方塊獨一無二的ID,緊接在後面的-textvariable可以用來指定一個變數,這個變數將用來儲存輸入在文字方塊上的內容,之後的::name即是指定的變數,它是一個叫name的全域變數。簡單的說使用者在文字方塊上輸入的內容,都會被儲存在::name變數裡。第2行的button是建立按鈕的命令。其中.btnHello是他獨一無二的ID,緊接著的-text可以用來指定要顯示在按鈕上的文字,這邊我把它指定為「Say Hello!!」。然後-command參數可以用來指定按下按鈕要執行的動作,大括號裡的內容即是要執行的動作。在這裡我用puts命令輸出了::name變數的內容再加上「您好」兩個字。由於之前設定了::name會反應文字方塊上輸入的內容,所以真實輸出的結果就是文字方塊上的文字加上「您好」這兩個字。
第3、4行,只是很單純的把文字方塊及按鈕排放在螢幕上顯示。
本章回顧
變數是一塊資料儲存的空間,建立變數的方法像這樣:set 變數名稱 變數的值
Tcl對於變數名稱的規定不是很嚴格,但是請儘量使用英文字母、數字及底線來組合變數名稱。另外,變數名稱有區分英文大小寫,所以dai和Dai是兩個不同的變數。
當變數建立後,使用set可以重新設定變數的值,使用unset可以釋放變數佔用的空間,例如,使用下面命令可以釋放變數:
unset 變數名稱
在變數的前面加上一個「$」號,就可以取出變數的值。例如,下面的puts會印出儲存在dai變數裡的內容:
凡是以兩個冒號開頭的變數名字(變數名字中間沒有出現其它的雙冒號),即表示是一個全域性的變數,這種變數可以在任何地方使用它,方法就和一般變數一樣。下面是一個簡單的例子:
按右上方的「#」號切換側邊欄