错误:在TCL文件中进行循环

时间:2014-05-04 12:16:36

标签: tcl

我是ns2的新手。 在以下代码中

     for {set i 0 }{$i < $val(nn)}{incr i }
     {
        set n$i [$ns node]
        $n$i set X_[expr 10+round(rand()*40)]
     }

我想创建50个节点,但在执行tcl文件时,它会显示错误为&#34;无效的命令名称&#34; $ n0&#34;执行&#34; $ n $ i时设置X_ [expr 10 + round(rand()* 40)]&#34;。我已经提供了nn为50.

2 个答案:

答案 0 :(得分:1)

您发布的代码存在两类问题。

基本语法问题

for {set i 0 }{$i < $val(nn)}{incr i }
{

这不会起作用,因为你在<{1}}的参数之间需要空格(是的,for在Tcl中不是关键字;它是&#39;只是常规命令)你必须把身体的开头放在行尾。您强烈建议使用One True Brace style编码;这就是Tcl的语法最简单的方法。

以下是如何解决这个问题:

for

请注意,我所做的一切就是移动(并插入)空格。

更深入的语法问题

for {set i 0} {$i < $val(nn)} {incr i} {

这些行存在一个问题,即您尝试使用双重替换。好吧。 set n$i [$ns node] $n$i set X_[expr 10+round(rand()*40)] 处理确实哑,因为它之后会检查非空的“漂亮”变量名称,如果它在那里则替换它并变成普通的$除此以外。这意味着$是您从$n$i$n获得的内容的串联。

最简单的解决方法是使用另一个变量:

$i

您甚至可以将前两行合并为一行,因为 set thisnode [$ns node] set n$i $thisnode $thisnode set X_[expr 10+round(rand()*40)] 的结果是刚设置的值:

set

但我们真的应该鼓励你使用数组来做这类事情,因为他们允许对一种排序进行双重替换。

    set n$i [set thisnode [$ns node]]
    $thisnode set X_[expr 10+round(rand()*40)]

那些额外的 set n($i) [$ns node] $n($i) set X_[expr 10+round(rand()*40)] ... (会产生很大的不同!

您还可以使用列表来存储生成的项目:

)

但在这种情况下,我真的很想使用辅助变量:

    lappend n [$ns node]
    [lindex $n end] set X_[expr 10+round(rand()*40)]

其他事项

你也应该把你的表情放在花括号里。在这个特殊情况下并不重要,因为它没有任何替代,但它是一个非常的良好习惯,因为它让它更容易用于Tcl一般编译表达式;也就是说,当整个表达式是文字时,Tcl可以提前编译它并且速度很快,而当表达式是非文字时,它不能编译到最后一刻,必须编译每次通过循环,也可能有一大堆其他危害。如果你在数百万的东西上做一个循环而不是50 ......那么它会产生更大的差异。

为了清楚起见,将表达式分解为一个小程序可能是值得的:

    lappend n [set thisnode [$ns node]]
    $thisnode set X_[expr 10+round(rand()*40)]
proc random {from to} {
    expr {$from + round(rand() * ($to-$from))}
}

写一次(并调试它!)一次,然后在其他地方重复使用。它是懒惰程序员&#39;方式。

我猜这也是一个NS2问题。在这种情况下,您可能仍会遇到问题:$n($i) set X_[random 10 50] X之间的下划线有点令人惊讶,除非您确实拥有包含大量非常相似变量的对象想要随机读取(然后丢弃其中的一个)。那将是......相当令人惊讶,是吗?我怀疑你可能会更好:

[expr …]

你需要保留参考文献吗?如果没有,你甚至可以使用:

for {set i 0} {$i < $val(nn)} {incr i} {
    set n($i) [$ns node]
    $n($i) set X [expr {10+round(rand()*40)}]
}

但那可能不是你想要的东西;在实际代码中,你想要从其他地方引用节点,这样你就可以在它们之间建立链接......

答案 1 :(得分:0)

Tcl使用以空格分隔的单词(参见http://tcl.tk/man/tcl8.5/TclCmd/Tcl.htm规则1,2,3),for命令的语法是

  

开始 测试 下一步 正文

http://tcl.tk/man/tcl8.5/TclCmd/for.htm

你需要这个:

 for {set i 0} {$i < $val(nn)} {incr i} {
    set n$i [$ns node]
    [set n$i] set X_[expr {10+round(rand()*40)}]
 }