If statement 完全被这个TCL代码迷惑了
我刚刚开始在TCL中编写代码,有以下while循环代码:If statement 完全被这个TCL代码迷惑了,if-statement,while-loop,tcl,If Statement,While Loop,Tcl,我刚刚开始在TCL中编写代码,有以下while循环代码: set x 0 while "$x < 5" { set x [expr {$x + 1}] if {$x > 7} break if "$x > 3" continue puts "x is $x" } puts "exited second loop with X equal to $x" 这让我很困惑。我很好奇,“$x>3”的计算结果是否会像[expr{“$x>3”}]或(这是一
set x 0
while "$x < 5" {
set x [expr {$x + 1}]
if {$x > 7} break
if "$x > 3" continue
puts "x is $x"
}
puts "exited second loop with X equal to $x"
这让我很困惑。我很好奇,“$x>3”
的计算结果是否会像[expr{“$x>3”}]
或(这是一个字符串,因为它本身就是一个字符串,所以它是真的。)
它是如何工作的?把机械师给我。巨大的偏头痛正在试图弄明白这一点。文件说:
if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
if命令将expr1计算为表达式(与expr计算其参数的方式相同)
这意味着$x>3
使用expr
进行评估
我注意到您在while
和if
条件中使用了双引号而不是大括号。请使用大括号,如中所示:
while {$x < 5} { ... }
文件说:
if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ... ?else? ?bodyN?
if命令将expr1计算为表达式(与expr计算其参数的方式相同)
这意味着$x>3
使用expr
进行评估
我注意到您在while
和if
条件中使用了双引号而不是大括号。请使用大括号,如中所示:
while {$x < 5} { ... }
Tcl有一个非常简单的评估模型。它总是按照它所看到的东西来评价事物;如果一个单词在大括号中,它将不被替换,但在其他情况下,它应用了
$
和[…]
(和\
,但不使用这些)替换;“…”
只是将一组字符组合成一个单词(即,它覆盖了通常的空格分隔规则)。组装好单词后,它将它们发送到命令实现(从第一个单词开始查找)以执行。就这样
建议您始终用括号括住表达式,因为这样可以避免混淆(并使Tcl能够编译代码)
适用于你的情况 没有替代品。三个字
set
将0
写入变量x
while "$x < 5" {
set x [expr {$x + 1}]
if {$x > 7} break
if "$x > 3" continue
puts "x is $x"
}
if {$x > 7} break
我们用expr
(计算表达式$x+1
,生成1
)替换了一个命令,这是整个第三个单词。最终结果是set
将值1
放入变量x
while "$x < 5" {
set x [expr {$x + 1}]
if {$x > 7} break
if "$x > 3" continue
puts "x is $x"
}
if {$x > 7} break
嗯,如果
$x>7
的计算结果为true(不为true),则对脚本进行计算中断
。不计算脚本的值
if "$x > 3" continue
puts "x is $x"
如果1>3
(有双引号,请立即替换)评估脚本继续。不计算脚本的值
if "$x > 3" continue
puts "x is $x"
将x为1
传递到put
,后者将打印它
循环,第二次/第三次迭代
与上面相同,除了使用2
/3
而不是1
循环,第四次迭代
这一次,当我们到达
if "$x > 3" continue
我们最终得到表达式4>3
,这是真的,因此我们计算“body”脚本continue
。这是一个生成continue异常的简单命令。while
捕捉到这一点,然后返回并再次测试循环条件(并开始第五次迭代)。净效果是跳过循环体末尾的put
迭代5,6,7
这些与迭代4非常相似
请注意,“…”
仅在达到它们时才进行计算。这意味着,对于循环中的循环,每次循环都会对它们进行评估/替换。但是,while
的循环条件不会在每次调用命令之前进行替换,因此不会重新替换。(这有点让人困惑,因为它们还支持类似Tcl的语法$
和[…]
和“…”
,但它们在形式上是一种独立的语言,有一个独立的解析器。)
迭代8
顶行的set
/expr
将x
设置为8
。当它到达下一行时:
if {$x > 7} break
表达式将求值为true(因为变量x
的内容大于7
),并且将求值break
。这将生成中断异常,导致while
完成
搞不清状况
现在,我们又在外面处理最后一个命令:
puts "exited second loop with X equal to $x"
您需要对这个进行演练吗
看看到底发生了什么
您可以使用来自的命令执行跟踪代码的改编,以准确地了解发生了什么。只需将代码放入一个过程中,应用跟踪程序,并启动跟踪程序,就可以准确地看到发生了什么,每一个细节。(好吧,只有替换的结果,但你可能可以从中找出答案。)
在这里,我将向您展示:
proc YourCode {} {
set x 0
while "$x < 5" {
set x [expr {$x + 1}]
if {$x > 7} break
if "$x > 3" continue
puts "x is $x"
}
puts "exited second loop with X equal to $x"
}
trace add execution YourCode {enterstep leavestep} showCalls
proc showCalls {cmd args} {
switch [lindex $args end] {
enterstep {
incr counter
puts >>>$cmd
}
leavestep {
lassign $args code result
puts "<<<$cmd <<<$code,$result<<<"
}
}
}
YourCode
proc YourCode{}{
集x0
而“$x<5”{
集合x[expr{$x+1}]
如果{$x>7}中断
如果“$x>3”继续
把“x是$x”
}
放置“退出的第二个循环,X等于$X”
}
跟踪添加执行代码{enterstep leavestep}showCalls
proc showCalls{cmd args}{
开关[lindex$args end]{
进阶{
递增计数器
放入>>$cmd
}
叶阶{
lassign$args代码结果
将“3”放在继续位置
把“x是$x”
}
>>>expr{$x+1}
Tcl有一个非常简单的评估模型。它总是按照它所看到的东西进行评估;如果一个单词在大括号中,它就没有被替换,但是它有$
和[…]
(和\
,但你没有使用这些)替换;“…
只是将一组字符组合成一个单词(也就是说,它覆盖了通常的空格分隔规则)。一旦组合好单词,它就会将它们发送到命令实现(从第一个单词开始查找)以执行。就是这样
建议您始终用括号括住表达式,因为这样可以避免混淆(并使Tcl能够编译代码)
适用于你的情况
没有替换。三个字。set<