名称
expr - 评估一个表达式
概要
expr arg ? arg arg ... ?
连接arg (在它们之间添加分隔符空格),将结果评估为Tcl表达式,并返回该值。 Tcl表达式中允许的运算符是C表达式中允许的运算符的子集,它们与相应的C运算符具有相同的含义和优先级。 表达式几乎总是产生数值结果 (整数或浮点值)。 例如,表达式
表达8.2 + 6评估为14.2。 Tcl表达式与C表达式在指定操作数的方式上不同。 另外,Tcl表达式支持非数字操作数和字符串比较。
操作数
Tcl表达式由操作数,运算符和括号组成。 操作数和运算符与括号之间可以使用空格; 它被表达式的指示忽略。 在可能的情况下,操作数被解释为整数值。 整数值可以用十进制(正常情况下),八进制(如果操作数的第一个字符为0 )或十六进制(如果操作数的前两个字符为0x )指定。 如果一个操作数没有上面给出的整数格式之一,那么它将被视为一个浮点数,如果这是可能的话。 浮点数可以用符合ANSI的C编译器接受的任何方式指定(除了在大多数安装中不允许使用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 + $ a6.1 expr 2 +“$ a。$ b”5.6 expr 4 * [llength“6 2”] 8 expr {{word one} <“word $ a”} 0运营商
下面列出了有效的运算符,按照优先级的降序进行分组:
- +〜!
一元减号,一元加号,按位不是,逻辑非。 这些操作数中没有一个可以应用于字符串操作数,而按位NOT可以仅应用于整数。
* /%
相乘,除,余数。 这些操作数中没有一个可以应用于字符串操作数,余数可能仅适用于整数。 其余的将始终具有与除数相同的符号和小于除数的绝对值。
+ -
加减法。 适用于任何数字操作数。
<< >>
左右移动。 仅对整数操作数有效。 右移总是传播符号位。
<> <=> =
布尔减少,大于,小于或等于,大于或等于。 如果条件为真,则每个运算符产生1,否则为0。 这些运算符可以应用于字符串以及数字操作数,在这种情况下使用字符串比较。
==!=
布尔相等而不相等。 每个运算符产生一个零/一个结果。 适用于所有操作数类型。
&
按位与。 仅对整数操作数有效。
^
按位独占OR。 仅对整数操作数有效。
|
按位或。 仅对整数操作数有效。
&&
逻辑AND。 如果两个操作数都为非零,则产生1结果,否则为0。 仅对布尔型和数字(整数或浮点型)操作数有效。
||
逻辑或。 如果两个操作数均为零,则产生0结果,否则为1。 仅对布尔型和数字(整数或浮点型)操作数有效。
x ? y : z
If-then-else,如在C.如果x评估为非零,那么结果是y的值。 否则,结果就是z的值。 x操作数必须有一个数值。
有关每个操作员生成的结果的更多详细信息,请参阅C手册。 所有的二元运算符在相同的优先级内从左到右分组。 例如,该命令
expr 4 * 2 <7返回0。
&& , || ,和?:运算符具有“懒惰评估”,就像在C中一样,这意味着如果不需要确定结果,操作数就不会被评估。 例如,在命令中
expr {$ v? [a]:[b]}根据$ v的值,实际上只会评估[a]或[b]中的 一个 。 但是请注意,只有整个表达式用大括号括起来才是正确的。 否则,在调用expr命令之前,Tcl解析器将同时评估[a]和[b] 。
数学函数
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 sinhabs( arg )
返回arg的绝对值。 Arg可以是整数或浮点数,结果以相同的形式返回。
acos( arg )
返回arg的反余弦,范围为[0,pi]弧度。 Arg应该在[-1,1]的范围内。
asin( arg )
返回arg的反正弦值,范围为[-pi / 2,pi / 2]弧度。 Arg应该在[-1,1]的范围内。
阿坦( 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的双曲余弦。 如果结果会导致溢出,则返回错误。
双( arg )
如果arg是一个浮点值,则返回arg ,否则将arg转换为浮点并返回转换后的值。
exp( arg )
返回arg的指数,定义为e ** arg 。 如果结果会导致溢出,则返回错误。
地板( arg )
返回不大于arg的最大整数值。
fmod( x,y )
返回x除以y的浮点余数。 如果y为0,则返回错误。
hypot( x,y )
计算直角三角形( x * x + y * y )斜边的长度。
int( arg )
如果arg是整数值,则返回arg ,否则通过截断将arg转换为整数并返回转换后的值。
日志( arg )
返回arg的自然对数。 Arg必须是正值。
log10( arg )
返回arg的 10进制的对数。 Arg必须是正值。
pow( x,y )
计算x增加到y的值 。 如果x是负数,则y必须是整数值。
RAND()
返回从零到小于1的浮点数,或者在数学术语中,返回范围[0,1)。 种子来自机器的内部时钟,或者可以通过srand功能进行手动设置。
圆( arg )
如果arg是整数值,则返回arg ,否则通过舍入将arg转换为整数并返回转换后的值。
罪( arg )
返回arg的正弦值,以弧度为单位。
sinh( arg )
返回arg的双曲正弦值。 如果结果会导致溢出,则返回错误。
sqrt( arg )
返回arg的平方根。 Arg必须是非负的。
srand( arg )
arg必须是一个整数,用于重置随机数生成器的种子。 返回该种子的第一个随机数。 每个口译员都有自己的种子。
tan( arg )
返回arg的正切值,以弧度为单位。
tanh( arg )
返回arg的双曲正切。
除了这些预定义的函数之外,应用程序还可以使用Tcl_CreateMathFunc ()定义附加函数。
类型,溢出和精度
所有涉及整数的内部计算都是用C型long来完成的,所有涉及浮点的内部计算都是用C型double来完成的。 将字符串转换为浮点时,检测到指数溢出并导致Tcl错误。 对于从字符串转换为整数,溢出的检测取决于本地C库中一些例程的行为,因此应视为不可靠。 在任何情况下,对于中间结果,通常不会可靠地检测到整数溢出和下溢。 在硬件支持的程度上检测浮点溢出和下溢,通常非常可靠。
整数,浮点和字符串操作数的内部表示之间的转换根据需要自动完成。 对于算术计算,整数一直使用,直到引入一些浮点数,然后使用浮点数。 例如,
expr 5/4返回1,while
expr 5 / 4.0 expr 5 /([字符串长度“abcd”] + 0.0)两者都返回1.25。 浮点值总是以``返回。 ''或e,这样它们看起来不像整数值。 例如,
expr 20.0 / 5.0返回4.0 ,而不是4 。
字符串操作
字符串值可以用作比较运算符的操作数,尽管表达式计算器可能会尝试将其作为整数或浮点进行比较。 如果比较操作数中的一个是字符串,另一个是数字值,则数字操作数将转换回使用C sprintf格式说明符%d作为整数, %g作为浮点值的字符串。 例如,命令
expr {“0x03”>“2”} expr {“0y”<“0x12”}两者都返回1.第一个比较是使用整数比较完成的,第二个比较是在第二个操作数转换为字符串18后使用字符串比较完成的。 由于Tcl倾向于尽可能将值视为数字,因此,如果您真的想要字符串比较,并且操作数的值可以是任意的,那么使用像==这样的运算符通常不是一个好主意; 在这些情况下最好使用string命令。
性能考虑
将表达式括在大括号中以获得最佳速度和最小存储要求。 这允许Tcl字节码编译器生成最佳代码。
如上所述,表达式被替换两次:一次由Tcl解析器取代,一次由expr命令取代。 例如,命令
设置3 组b {$ a + 2} expr $ b * 4返回11,不是4的倍数。这是因为Tcl解析器将首先用变量b代替$ a + 2 ,然后expr命令将计算表达式$ a + 2 * 4 。
大多数表达式不需要第二轮替换。 要么它们被括在大括号中,要么它们的变量和命令替换产生不需要替换的数字或字符串。 但是,由于少数无束缚的表达式需要两轮替换,所以字节码编译器必须发出额外的指令来处理这种情况。 包含命令替换的无支撑表达式需要最昂贵的代码。 每次执行表达式时都必须通过生成新代码来实现这些表达式。
关键词
算术, 布尔值 ,比较,表达式,模糊比较
重要提示:使用man命令( %man )查看特定计算机上的命令使用方式。