表达式将值(或操作数)与操作符联合起来,产生新的值。
常用的具有表达式参数的命令:
expr arg1 [arg2...]
功能:把参数作为表达式处理,获得表达式的值并把这个值作为字符串返回。if{表达式}{...}
4.1 数值操作数
- 整数的表达格式:
- 十进制(普通格式):
335
- 二进制(
0b
开头):0b101001111
- 八进制(
0o
开头):0o517
- 十六进制(
0x
开头):0x14f
- 十进制(普通格式):
- 实数的表达格式:ANSI C定义的大多数格式
2.1
7.91e+16
6E4
3.
4.2 操作符及其优先级
Tcl表达式支持的所有操作符相同优先级从左到右进行计算,优先级从高到低排列:
语法 | 结果 | 操作数类型 |
---|---|---|
-a | a的负值 | int,real |
+a | 对a进行一元加操作 | int,real |
!a | 逻辑非 | int,real |
~a | a按位取反 | int |
a**b | 指数:a^b | int,real |
a*b | a乘b | int,real |
a/b | a除b | int,real |
a%b | a除b取余 | int |
a+b | a加b | int,real |
a-b | a减b | int,real |
a<<b | a左移b位,低位补0 | int |
a>>b | a算术右移b位,高位补符号位 | int |
a<b | a小于b | int,real,string |
a>b | a大于b | int,real,string |
a<=b | a小于等于b | int,real,string |
a>=b | a大于等于b | int,real,string |
a==b | a等于b | int,real,string |
a!=b | a不等于b | int,real,string |
a eq b | a等于b | string |
a ne b | a不等于b | string |
a in b | 列表b包含a元素 | a:string,b:list |
a ni b | 列表b不包含a元素 | a:string,b:list |
a&b | a和b按位与 | int |
a^b | a和b按位异或 | int |
a|b | a和b按位或 | int |
a&&b | a和b逻辑与 | int,real |
a||b | a和b逻辑或 | int,real |
a?b:c | 三目运算 | a:int,real |
4.3 数学函数
Tcl表达式支持数学函数。
调用:
expr 2*sin($x)
Tcl中的内建函数:
函数 | 结果 |
---|---|
abs(x) | 求绝对值 |
acos(x) | 反余弦函数 |
asin(x) | 反正弦函数 |
atan(x) | 反正切函数 |
atan2(x,y) | x/y的反正切函数 |
bool(x) | 将表达式转化为bool类型 |
ceil(x) | 向上取整 |
cos(x) | 余弦函数 |
cosh(x) | 双曲余弦函数 |
double(i) | 整数转为实数 |
exp(x) | e的x次方 |
floor(x) | 向下取整 |
fmod(x,y) | x除以y的实余数 |
hypot(x,y) | 求模 |
int(x) | 取整数部分 |
log(x) | 自然对数 |
log10(x) | 以10为底的自然对数 |
max(arg,…) | 最大值 |
min(arg,…) | 最小值 |
pow(x,y) | x的y次方 |
rand() | [0,1]的随机数 |
round(x) | 四舍五入取整 |
sin(x) | 正弦 |
sinh(x) | 双曲正弦 |
sqrt(x) | 开方 |
srand(x) | 整数种子的随机数 |
tan(x) | 正切 |
tanh(x) | 双曲正切 |
wide(x) | 表示x的宽度的整型值 |
4.4 表达式操作数的替换
两种替换方式:
- 普通的Tcl解析器机制。
expr 2*sin($x)
- 通过表达式处理,在表达式处理时会再进行一轮变量替换和命令替换。
expr {2*sin($x)}
说明:大括号阻止了Tcl解析器替换x的值,将整个表达式传给expr,在表达式处理时进行替换。
这种两次替换的方式对while这种反复处理表达式的命令有很大的影响:
set pow 1
while {$pow<$num} {
set pow [expr $pow*2]
}
表达式$pow<$num
在每次迭代开始前都要处理一次去判断终止条件,如果没有大括号,则只有Tcl解析器的一次替换(比如替换为1<2
),循环要么不进行要么进入死循环。
注意:最好总是把表达式用{}
括起来。
- 提高处理效率。
- 避免安全漏洞。
4.5 字符串操作
和ANSIC不同,Tcl的部分操作符接收字符串操作数。具体见操作数类型包含string的相关语法。
注意:要指定一个字符串操作数,必须把它放在大括号或双引号中,或使用变量替换或命令替换。
set x "hello w0shishabi"
set result [expr {$x eq "hello w0shishabi"}]
# 1
set result [expr $x eq "hello w0shishabi"]
# 无法解析
4.6 列表操作
set a [list {s1} {s2} {s3}]
expr {"s1" in $a}
# 1
expr {"s2" ni $a}
# 0