網頁標題: 03 變數與資料型態 #1: 簡介

Warning: fopen(/home/crazy/www/cmsb/bcj/has_read.php): failed to open stream: Permission denied in /home/crazy/www/compose/reading.php on line 2070

Warning: fputs() expects parameter 1 to be resource, bool given in /home/crazy/www/compose/reading.php on line 2072

Warning: fclose() expects parameter 1 to be resource, bool given in /home/crazy/www/compose/reading.php on line 2073
 
﹗﹗﹗觀看留言:此文章已經有18則留言 ﹗﹗﹗


 程式執行過程中有很多運算,經常要暫存中間的結果,上一步驟答案暫存後成為下一步驟輸入,用來暫存答案的東西稱為「變數」。一個變數有自己的生命週期、名字、以及存在裡面的值。變數一般而言會經過宣告、初始化、使用與消滅四個階段,以下首先介紹「宣告」,然後從「初始化」引入資料型態的概念,進而講解各種型態的使用方法。

 「宣告」就是跟 AutoIt 約定一個變數名稱,取得一塊記憶體空間能夠儲存資料。變數的命名必為 $ 開頭,之後是連續的英文大小寫、數字或底線。如 $var, $123, $iCount 跟 $tmp_result 都是合法的變數名稱,請留意 AutoIt 變數命名不區分大小寫。

 然而,AutoIt 裡變數的第一次出現也不一定要被宣告,可有兩種方式如下:

 (1) 就是變數的宣告,前面必須有一個 Local 關鍵字。AutoIt 跟其他許多程式語言一樣有自己的關鍵字,不同場合該使用對應的關鍵字,往後會逐一介紹。變數宣告的關鍵字也可以用 Global 和 Dim, 不過目前的使用場合無法區別三個字用來宣告的差異,下面就都習慣以 Local 宣告。另外,可一次同時宣告多個變數如 Local $i, $k 用逗點隔開,一次宣告 $i 和 $k 二個變數。

 (2) 的變數,未經宣告直接出現,但這種狀況就必須立刻等於某個東西,這邊讓它內存整數 1. 變數第一次被賦予某個值,就是「初始化」,在變數倍讀取內容之前一定要初始化。宣告變數時也可以利用 Local $i = 0 這樣的寫法,同時宣告與初始化。注意像 $j 這種直接初始化的變數出現方式,一行只能新增一個變數,不像宣告可一次新增多個變數。

 (3) 例子裡的 $K 宣告比 $i 多出 Const, 隨後無法改變 $k 的內容,「常數」必須在宣告時立刻初始化。之前用過的 $MB_OK 也是「常數」,常數通常用來定義有特殊用途的數值或字串,主要目的是給它一個好讀的別名以提升程式碼可讀性,習慣上我們會把常數的命名都用大寫字母以與一般變數區別。

 剛才的範例中,變數 $j 裡面存的值(資料)是整數的 1. 「整數」是資料的型態 (type), 1 是資料的值 (value). AutoIt 的變數本身不限定儲存何種型態的資料,但每個資料都有自己的型態。AutoIt 裡的基本資料型態有 Number, String, Boolean, Binary, Pointer 等五種。此外,有二個特殊的值被列入關鍵字,成為 Keyword 型態,以及進階資料型態如陣列 (Array), 結構 (DllStruct), COM 物件 (Object) 等。本文將涵蓋五個基本型態、關鍵字型態和最初步的陣列操作。


 Number 內又涵蓋整數 (integer), 浮點數 (floating-point number) 兩種,差別在於後者可用來儲存 1.23 這種有小數內容的數值資料。當要表示一個 Number 時,整數就寫成如鋼材的 1 那樣,浮點數則可寫成 $j = 1.23

 「整數」又能分成 32 位元與 64 位元兩種,差別在於花費的儲存空間,誠如其名。一般未特別指定,AutoIt 會看資料的值本身需要多少空間才足以避免遺失內容,剛才的 1 只要 32 位元即可,但若要存 10000000000 就需要 64 位元整數才行, AutoIt 內部會自行判斷,儘可能避免資料遺失。

 有時浮點數的值會很大或很小,需要用科學記號表示,這時候 AutoIt 允許用科學記號的寫法來表達浮點數的值,如 1500.0 可寫做 1.5e3, 用 e 分開大小和指數的部份,且 e 後面的次方也可插入多餘的 0 比如 1.5e03

 有時我們也用十六進位來表達整數,平常聽到字元的內碼就是十六進位的整數,十六進位的 1234(16) 可寫成 0x1234, 相當於十進位 1*16^3+2*16^2+3*16+4 = 4660, 十六進位與十進位間的轉換過程請參閱計算機概論一類的書籍。通常用十六進未,表示重點在資料本身組成的 0/1 位元的排列,不是人類好看好懂的「語意」上的形式。

 以下針對整數的表示法舉例:

 VarGetType 是一個 AutoIt 的內建函式,協助我們檢視變數目前容納的資料型態。$c, $d 的型態 Double 就是指「雙精度」浮點數,由於儲存空間的不同 (32 v.s. 64 bits), 浮點數又分成「單精度」與「雙精度」等,但是 AutoIt 的浮點數一律採用「雙精度」的規格。

 接下來是如何使用 Number 形態的資料。它支援加減乘除等四則運算,以及「次方」的運算。比如剛才舉例中若印出 $a + $b 將得結果 10000000123, $b * $d 將得 6.626e-024. 需注意除法的除數不能為 0, 如果故意除以 0, 可能會得到 1.#INF 或 -1.#IND 這種奇怪的答案。另外,四則運算除了除法外,雙方型態相同時,無論答案為何仍以該型態存之;雙方型態不同時,答案的型態將是容忍範圍較大者,Number 的三種型態範圍大小依序為 Double 大於 Int64 大於 Int32. 以下舉例加減乘除和次方運算的使用方式:

 從結果可以看出,其他運算答案都跟預期一樣,數字正確且型態也是 Int64 才能容納這麼大的數字,只有除法雖然答案與手算完全一樣,但型態變成浮點數,因為只有浮點數才能記下 1.23 乘以 10 的 -8 次方這種非整數的值。

 到鋼材為止的運算過程,答案都必須放在第三個變數,可是許多時候,我們清楚明白,$a 原本的值不重要了,重要的是 $b 與 $a + $b, 站在節省資源的角度,可以寫下 $a = $a + $b 這樣的敘述,這個「等於」不是數學上的等於,而是把右邊 $a + $b 的計算結果「賦予」左邊的 $a. 這種敘述可以寫得比較簡單,以下示範「累加」、「累減」、「累乘」、「累除」等四種運算:

 比較令人驚訝的是,累除過後雖然印出的是整數樣子的 123, $a 的型態卻轉變為浮點數了。可見得,雖然 $a 的值都跟我們猜想一樣,但是型態卻不一定。不過,總而言之,AutoIt 內部對型態的處理大多可以信任,人可以憑著自己的直覺來寫程式。


 String 即「字串」,已經在「第一個程式」裡稍微提起,不過 AutoIt 允許使用單引號或雙引號夾住字串。如果字串中必須有跟夾住的引號同類的引號字元,如雙引號夾住的字串中包含雙引號,則要連打二個雙引號,寫成 "這是雙引號 ("") 字元" 印出來則是「這是雙引號 (") 字元」。AutoIt 的字串,內部儲存採用 UTF-16 (UCS-2) 編碼,可表示字元編號在 0000(16) 到 FFFF(16) 的 Unicode.

 當二個字串需要連接時,或者字串中某些內容要來自別的變數,可使用 & 來黏貼。「連接」的運算加上等於,成為「續接」,就是把別人的字串內容追加到自己最後。使用方法舉例如下:

 其實「字串」的使用不只這樣,AutoIt 提供很多內建函式來實現求取自串長度、字串切割、字串搜尋特定內容等功能,不過這些運算已經屬於「字串處理」的議題,不在本文範圍。


 Boolean 表示「邏輯」的值,只有「真」跟「假」。AutoIt 安排了 True 和 False 二個關鍵字來代表邏輯的真和假,並設置 Not, And, Or 三個關鍵字表示邏輯的三個最基本運算。使用舉例如下:

 Not 就是把邏輯的真假交換,因為 $b1 是假,$b3 反過來為真,值得一提的是,Not 是本文唯一只有一個變數參與的運算,其他運算都要二個變數的參與。And 參與雙方必須同為真才讓結果為真,此刻由於 $b1 是假,使得它跟 $b2 的 And 答案為假。Or 只要雙方有一個真即讓答案為真,因為 $b2 是真所以雙方 Or 結果也是真。

 不過,邏輯運算倒是很少像剛才的範例這樣使用,而多用於程式執行流程的控制,藉由判斷條件成立與否決定某些敘述是否要執行,或再執行一賜等等。下面介紹一行就能辦到的最簡單流程控制,其他較複雜的流程控制,不在本文之內。

 最簡單的流程控制由問號和冒號組成,填入三個表達式 (expression). 「表達式」就是由變數或常數經過一連串四則、連接、邏輯運算、比較及函式呼叫等操作,所寫成的一個算式,表達式可以跟另一個表達式用運算符號連接起來併成更長的表達式,也能代入函式當做參數。到本文結束為止,範例中都除 #include 外只有表達式構成的程式碼敘述。

 它的基本結構是 (exp1) ? (exp2) : (exp3), 其中 exp1, exp2 和 exp3 表示三個「表達式」,整句 (exp1) ? (exp2) : (exp3) 也被併成一個「表達式」。套入 ?: 的表達式不一定有小括號圍住,不過 AutoIt 建議大家盡量寫出來。

 exp1 的計算結果會被轉成 Boolean, 當它不是如上的 Boolean 值或某個比較的結果,是整數則 0 當做 False 其他值當 True, 字串的話 "" 是 False 其他非空字串都是 True. 如果 exp1 算完是 True 則接著只執行 exp2, False 就執行 exp3, 執行結果成為這整句表達式的最後答案。

 上例完全由範例 3-6 修改而來,前三個 MsgBox 的真假都和範例 3-6 一樣。第四個 MsgBox 裡有兩層問號冒號,(Not $b2) 是 False 因而執行第一個冒號之後,又是判斷而 Not ($b1 And $b2) 是真故印出第二個問號後的 B. 換言之,第二組問號冒號的角色是第一組的 exp3.

 這種根據條件來二選一答案的情形,用問號冒號將比一般流程控制寫法輕便許多。


 Binary 型態表示一段位元組的資料,它的內容沒有經過任何解釋,赤裸呈現在我們眼前。直接舉例使用如下:

 在此 Binary 也是一個內建函式,會把參數引號內的東西的位元組內容呈現出來。三個字母 abc 用了三個位元組記錄,印出的 0x616263 就是三個位元組湊起來的結果,它們三個分別是 0x61, 0x62 和 0x63.

 一般狀況下程式中對資料的處理不需要用 Binary 層級的眼光去看待,這也是 AutoIt 此類高階語言的目的,可是畢竟有時候內部處理資料的方式不是我們預期的,從 Binary 的資料來處理就可以讓我們擁有較完全的控制能力,比如自己決定檔案裡的位元組該做何解釋。

 上面提到字串的「編碼」,就是這類需求會發生的情況。世界上每個「字」都由人類指定一個對應的編號,但這編號是邏輯上的,在電腦裡「字」被編碼成位元組之後才存檔。相同「字」會因為編碼不同而用不同位元組表示,比如台灣、大陸、日本三地寫相同一個漢字後存檔,在對方電腦打開就變亂碼,因為開檔後解碼時所用的不是存檔當下用的編碼。

 台灣的電腦上遇到文字檔就預設用 BIG-5 編碼來處理,另外也設有 UTF-8 和 UCS-2, 但除此之外別種編碼出現的機會就都一樣,所以這之外的文字檔就必須由程式負責依據自己執行的前後狀況指定哪種編碼來解釋,而不是由 AutoIt 不厭其煩列舉所有可能,但是這樣就不能讓 AutoIt 執行它預設的文字檔解析方式,要繞過這個機制的辦法就是使用 Binary 角度抽出檔案內容後自己指定編碼了。

 Binary 也可以像字串一樣執行「連接」動作,一樣使用 & 連接,&= 續接,其實說穿了它與字串就只差一個編碼關係,其他特徵雙方都擁有。


 Pointer 儲存一段連續記憶體的第一個位址,我們說這個指標「指向」那段記憶體,其大小隨著運行的是 32 或 64 位元的 AutoIt 而不一樣。多數 AutoIt 內的運算不會用到指標,然而指標在 AutoIt 跟其他 dll 之間溝通等情境時扮演重要角色,詳細描述不在本文範圍。


 AutoIt 另外安排一種特別的型態——關鍵字,只有兩個值被歸類為這種型態,Default 與 Null, 而它們也是 AutoIt 裡的關鍵字。

 Default 語意為「默認」,就代表系統裡一個內定的值,沒有任何數學運算意義,可以用 $var = Default 指定 $var 的值是 Default, VarGetType($var) 印出將是 Keyword. Default 也不常用於一般場合,多用在函式的參數傳遞,函式內對 Default 的處置詳細過程未列入本文,但無論屬故意或過失,Default 被拿來運算時,AutoIt 不會特地檢查並展示錯誤而終止,只會讓大家看到一個沒有明確定義行為的結果,因此只能小心留意。

 Null 語意為「空」,可以這樣比喻。「變數」是一個盒子,當讀到 Local $var 時 AutoIt 給你這個盒子,標籤寫著 var, 盒蓋緊閉。當 $var = Null 時,蓋子打開但裡面空無一物,也不能拿來運算,然而它的狀態由蓋子緊閉的未初始化變成概子打開空無一物的 Null. 當指定別的值給 $var, 盒子內就是有東西也能參與運算了。「空」常用於想初始化又暫無須指定資料的變數,它在型態與意義上都跟數字 0 和空字串 ("" 或寫成 '') 都不相同。


 「陣列」是一種進階資料型態,但是許多場合需要它來簡化程式碼跟執行有效率的演算法。宣告陣列好像一次宣告多個變數,用相同的名字,只是不同下標代表不同位置的變數。下例展示陣列的用法:

 上例比之前多引入了 Array.au3, 這個函式庫提供許多與陣列相關的函式,善用它們將迅速又正確的處理陣列。這裡 $data 之後多了一對中括號,表示 $data 是陣列而非一般變數,初始化方式如上,中括號內列出所有陣列裡的變數值,列幾個陣列就有多長,之後就用 UBound 取得陣列長度。

 上例中的陣列,初始化含有三個值,因此陣列裡就有三個「元素」,陣列長度是 3, 元素被編號 0 到 2, 這編號稱為「索引」。想存取特定位置的元素必須透過索引,如例中 $data[2] 中括號內的數字可以是 0 到 2 以區別三個元素。宣告完後 $data[0]$data[2] 就能當一般變數使用。陣列宣告也可以不初始化,但此時必須寫 Local $data[3] 如此語法,明確指定它有三個元素。

 _ArrayDisplay 來自 Array.au3, 就像 MsgBox, 只是它針對陣列設計,把陣列所有元素的內容印出來,方便我們檢查。第一個參數是陣列本身,因為用 $data 代表這整個陣列,就不用寫索引,第二個參數是跳出來的視窗要顯示的標題。

 之後將針對陣列的操作另外撰文,本篇只提到一維陣列的取長度、取值、展示,之後將介紹其他運算以及二維以上的陣列。


 最後將本文提到過的運算符號列表在此:

06. 運算符號列表 (1).txt
符號說明
=指定
+
-減、負號
*
/
^次方
+=累加
-=累減
*=累乘
/=累除
&文字、二進位資料連接
&=文字、二進位資料續接
And
Or
Not
?:按條件選擇表達式

註:這個表格是高生旺老師教材的 06. 運算符號列表.txt 的一部分。


回 · 我的 AutoIt 學習筆記 這一篇文章封面
回 · 我的 AutoIt 學習筆記 這一篇文章封面
回 · 我的 AutoIt 學習筆記 這一篇文章封面


本文張貼者:Bo-Cheng Jhan〔張貼時間:民國105年4月17日(星期天)17點46分 | 更新次數 #7 | 最後更新:民國105年6月11日(星期六)0點26分〕

部落格首頁


學習的故鄉首頁
本站公告:〔您越需要我們,我們就越有創意〕 本站說明書:〔發現故鄉還有改進的地方,請來信告訴原丁們〕
觀察應用學習點數 :〔咱的故鄉有您的參與,會使我們有更大的發揮空間,展現更豐富精彩的學習畫面〕 〔期待藉由無障礙網頁設計,能讓視障小朋友更愛看書、更愛寫作且更愛學習〕:盲用電腦「心得分享」
〔為了讓我們有乾淨的學習環境,請勿任意在本站散播商業廣告與不合法文件或聯結〕:本站宣示