expr(3tcl)

NAME
expr - 求一個表達式的值

總覽 SYNOPSIS
expr arg ?arg arg ...?

描述 DESCRIPTION

連接(concatenate)所有 arg (在它們中間添加分隔符空格)，把結果作為一個Tcl 表示式來求值(evaluate)並返回結果。在 Tcl 表達式中允許的操作符式在 C 表達式中允許的操作符的一個子集，並且它們與相應的 C 操作符有相同意義和優先級。表達式幾乎總是產生一個數值結果(整數或浮點數的值)。例如，表達式 expr 8.2 + 6 求值出 14.2. Tcl 表達式與 C 表達式在操作數指定的方式上有區別。還有，Tcl 表達式支持非數值操作符和字符串比較。

操作數 OPERANDS

一個 Tcl 表達式由操作符、操作數和括號的組合構成。在操作符、操作數和括號之間可使用白空格；它被表達式的指令所忽略。指定整數值可以使用十進制(通常的情況)、八進制(如果操作數的第一個字符是 0)、或十六進制(如果操作數的前兩個字符是 0x)。如果一個操作數沒有上述的整數格式，則如果可能的話把它作為浮點數對待。指定浮點數可以使用任何遵從 ANSI 的 C 編譯器可接受方式(除了在多數安裝(installation)中不允許 f、F、l 和 L 延伸檔名)。例如，下列的數都是有效的浮點數: 2.1、3.、6e4、7.91e+16。如果沒有可能的數值解釋，則一個操作數被作為字符串來保留(並且對它只提供一組有限的操作符)。

可以用下列方式指定操作數:

[1] 為一個數值值，要麼是整數要麼是浮點數。

[2] 作為一個 Tcl 變量，使用標準的 $ 記號。變量的值將被用作操作數。

[3] 作為用雙引號包圍起來的一個字符串。表達式分析器將在引號之間的信息上完成反斜槓、變量和命令替換，並把結果值用作操作數。

[4] 作為用花括號包圍起來的一個字符串。在左花括號和相匹配的右花括號之間的字符將被用作操作數而不做任何替換。

[5] 作為一個用方括號包圍起來的 Tcl 命令。命令將被執行並且它的結果將被用作操作數。

[6] 作為一個數學函數，它的參數可以是操作數的任何上述形式，比如 sin($x)。參見下面的已定義的函數的一個列表。

在上述替換發生的地方(例如在被引用起來的字符串當中)，他們由表達式的指令來完成。但是，在調用表達式處理器之前命令分析器可能已經完成了一個額外的替換層。如下面討論的那樣，通常最好把表達式包圍在花括號中來防止命令分析器在這些內容上進行替換。

舉一些簡單的表達式的例子，假設變量a 的值是 3 並且變量 b 的值是 6。則下面的每行左邊的命令將生成右邊的值。
expr 3.1 + $a    6.1
expr 2 + "$a.$b"    5.6
expr 4*[llength "6 2"]    8
expr {{word one} < "word $a"}    0

操作符 OPERATORS

下面列出了有效的操作符，用優先級的降序分組:

-  +  ~  !
    一元(Unary，也譯為單目)減，一元加，位(bit-wise) NOT，邏輯 NOT。這些操作符不能提供給字符串操作數，並且位 NOT 只能提供給整數。

*  /  %
    乘，除，求餘。這些操作符不能提供給字符串操作數，並且求餘只能提供給整數。餘數將總是與除數有相同的符號並且絕對值小於除數。

+  -
    加和減。對任何數值操作數均有效。

<<  >>
    左移和右移。只對整數操作數有效。一右移總是傳播(propagate)符號位。

<  >  <=  >=
    Boolean 小於，大於，小於等於，大於等於。如果條件是真則每個操作符產生 1，否則 0。這些操作符可以像提供給數值操作數一樣提供給字符串，在這種情況下使用字符串比較。

==  !=
    Boolean 等於和不等於。每個操作符產生一個零/一結果。對所有操作數類型有效。

&   位與。只對整數操作數有效。

^   位異或。只對整數操作數有效。

|   位或。只對整數操作數有效。

&&  邏輯與。如果兩個操作數都是非零則生成一個 1，否則生成 0。只對 boolean 和數值(整數或浮點數)操作數有效。

||  邏輯或。如果兩個操作數都是零則生成一個 0，否則生成 1。只對 boolean 和數值(整數或浮點數)操作數有效。

x?y:z
    If-then-else，如同 C 語言那樣。如果 x 求值為非零，則結果是 y 的值。否則結果是 z 的值。x操作數必須是一個數值值。

參見 C 手冊來得到對每個操作符的生成結果的更詳細的描述。所有相同的優先級的二元操作符從左至右的組合(group)。例如，命令 expr 4*2 < 7 返回 0.

&&, ||, 和 ?: 操作符「惰性求值」，如同 C 語言那樣，這意味著如果操作數對確定結果不是必須的則不被求值。例如，命令 expr {$v ? [a] : [b]} 中實際上只有 [a] 或 [b]中的一個將被求值，依賴於 $v 的值。注意，這只在整個表達式被包圍在花括號中時是真的；否則 Tcl 分析器將在調用 expr 命令之前求值 [a] 和 [b] 二者。

數學函數 MATH FUNCTIONS

Tcl 支持在表達式中的下列數學函數:
abs    cosh    log    sqrt
acos    double    log10    srand
asin    exp    pow    tan
atan    floor    rand    tanh
atan2    fmod    round
ceil    hypot    sin
cos    int    sinh

abs(arg)
    返回 arg 的絕對值。Arg可以要麼式整數要麼是浮點數，並且結果以同樣的形式返回。

acos(arg)
    返回 arg 的反餘弦，值域是 [0,pi] 弧度。Arg的定義域是 [-1,1]。 .TP asin(arg) 返回 arg 的反正弦，值域是 [-pi/2,pi/2] 弧度。Arg 的定義域是 [-1,1]。

atan(arg)
    返回 arg 的反正切，值域是 [-pi/2,pi/2] 弧度。

atan2(x, y)
    返回 y/x 的反正切，值域是 [-pi,pi] 和，x 和 y 不能都是 0。

ceil(arg)
    返回不小於 arg 的最小的整數值。

cos(arg)
    返回 arg 的餘弦，單位是弧度。

cosh(arg)
    返回 arg 的雙曲餘弦，如果結果導致溢出，返回一個錯誤。

double(arg)
    如果 arg 是一個浮點值，返回 arg；否則把 arg 轉換成浮點數並返回轉換後的值。

exp(arg)
    返回 arg 的指數，定義為 e**arg。如果結果導致溢出，返回一個錯誤。

floor(arg)
    返回不大於 arg 的最大整數值。

fmod(x, y)
    返回 x 除以 y 得到的浮點餘數。如果 y 是 0，返回一個錯誤。

hypot(x, y)
    計算一個直角三角形的斜邊的長度(x*x+y*y)。

int(arg)
    如果 arg 是一個整數值，返回 arg，否則通過截取arg (的整數部分)來把它轉換成整數並返回轉換後的值。

log(arg)
    返回 arg 的自然對數。Arg 必須是正數值。

log10(arg)
    返回 arg 的以10 為底的對數(常用對數)。Arg必須是正數值。

pow(x, y)
    計算 x 的 y 次冪。如果 x 是負數，y 必須是一個整數值。

rand()
    返回一個大於等於零且小於 1 的一個(隨機)浮點數，這個范圍用數學術語是區間[0,1)。種子來自機器的內部時鐘或用 srand 函數人為設定。

round(arg)
    如果 arg 是一個整數，返回 arg，否則通過四舍五入把 arg 轉換成整數並返回轉換後的值。

sin(arg)
    返回 arg 的正弦，單位是弧度。

sinh(arg)
    返回 arg 的雙曲正弦。如果結果導致溢出，返回一個錯誤。

sqrt(arg)
    返回 arg 的開方。Arg 必須是非負數。

srand(arg)
     arg 必須是一個整數，它被用於重置隨機數生成器的種子。返回用這個種子生成的第一個隨機數。每個解釋器都有它自己的種子。

tan(arg)
    返回 arg 的正切。單位是弧度。

tanh(arg)
    返回 arg 的雙曲正切。

除了這些預定義的函數之外，應用可以使用 Tcl_CreateMathFunc () 定義增補的函數。

類型 TYPES, 溢出 OVERFLOW, 和 精度 PRECISION

所有涉及整數的內部運算用 C 類型 long 處置。並且所有涉及浮點數的內部運算用 C 類型 double 處置。當把一個字符串轉換成一個浮點數的時候，若檢測到指數溢出則導致一個 Tcl 錯誤。對於從字符串轉換成整數，溢出檢測依賴於在本地 C 庫中的一些例程的行為，所以它應被作為不可靠的來看待。在任何情況下，對中間結果通常不能可靠的檢測整數的上溢和下溢。浮點數上溢和下溢的檢測通常達到由硬體支持的程度，普遍非常可靠。

整數，浮點數、和字符串的內部表示之間的轉換按需要自動完成。對於算術計算，在浮點數介入之前使用整數，此後使用浮點數。例如， expr 5 / 4 返回 1，而 expr 5 / 4.0 expr 5 / ( [string length "abcd"] + 0.0 ) 都返回 1.25。 返回的浮點值總是帶著一個「.」或一個 e 所以它們看起來不像整數值。例如， expr 20.0/5.0 返回 4.0, 而不是 4.

字符串操作 STRING OPERATIONS

字符串可被用做比較操作符的操作數，儘管表達式求值器盡可能的嘗試著作為整數或浮點數來做比較。如果一個比較的操作數中的一個是字符串而其他是數值值，數值操作數被轉換回字符串，對整數值使用 C sprintf 格式指定符 %d ，對浮點數值使用 %g。例如，命令 expr {"0x03" > "2"} expr {"0y" < "0x12"} 都返回 1。做第一個比較使用了整數比較，而做第二個比較在把第二個操作數轉換成字符串 18之後使用了字符串比較。因為 Tcl 趨向於盡可能的把值作為數值對待，在你事實上想進行字符串比較並且操作符的值可以是任意的的時候使用像 == 這樣的操作符通常不是個好主意；在這種情況下最好使用 string命令。

性能的考慮 PERFORMANCE CONSIDERATIONS

要得到最快的速度和最小的存儲需求，就要把表達式包圍在花括號中。這允許 Tcl 字節碼編譯器生成最好的代碼。

像上面所提及的那樣，表達式被替換兩次: 一次由 Tcl 解釋器，一次由 expr 命令。例如，命令 set a 3 set b {$a + 2} expr $b*4 返回 11，而不是 4 的倍數。這是因為 Tcl 分析器將首先把變量 b替換成 $a + 2，接著 expr 命令將求值表達式 $a + 2*4。

多數表達式不需要兩輪替換。要它們被包圍在花括號中，要麼它們的變量和命令替換生成數值或本身不需要替換的字符串。但是，因為一些未用化括號包圍起來的表達式需要兩輪替換，字節碼編譯器必須散佈(emit)額外的指令來處理這些情況。對於未用化括號包圍起來的表達式，代價最高昂的代碼是包含命令替換的代碼。必須通過在每次執行這個表達式時生成新的代碼來實現這些表達式。

關鍵字 KEYWORDS
arithmetic, boolean, compare, expression, fuzzy comparison

[中文版維護人]
寒蟬退士

[中文版最新更新]
2001/07/22

《中國 Linux 論壇 man 手冊頁翻譯計劃》:
http://cmpp.linuxforum.net