Tcl can';t读取变量:没有这样的变量

Tcl can';t读取变量:没有这样的变量,tcl,ns2,Tcl,Ns2,以下代码产生错误: can't read "n": no such variable while executing "$ns duplex-link $n$i $n([expr ($i+1)%120]) 1Mb 10ms DropTail" ("for" body line 2) invoked from within "for {set i 7} {$i < 120} {incr i} { $ns duplex-link $n$i $n([expr

以下代码产生错误:

can't read "n": no such variable
    while executing
"$ns duplex-link $n$i $n([expr ($i+1)%120]) 1Mb 10ms DropTail"
    ("for" body line 2)
    invoked from within
"for {set i 7} {$i < 120} {incr i} {
      $ns duplex-link $n$i $n([expr ($i+1)%120]) 1Mb 10ms DropTail
}"
    (file "multicast.tcl" line 44)
无法读取“n”:没有此类变量
执行时
“$ns双工链路$n$i$n([expr($i+1)%120])1Mb 10ms DropTail”
(“适用于”车身第2行)
从内部调用
“对于{set i 7}{$i<120}{incr i}”{
$ns双工链路$n$i$n([expr($i+1)%120])1Mb 10ms下拉式
}"
(文件“multicast.tcl”第44行)
似乎$n$i未按所需格式$n7等进行评估。非常感谢您在解决方案中提供的任何帮助

for {set i 0} {$i < 120} {incr i} {
set n$i "[$ns node]"
global n$i
}

# Create links
$ns duplex-link $n0 $n1 1.5Mb 10ms DropTail
$ns duplex-link $n0 $n2 1.5Mb 10ms DropTail
$ns duplex-link $n2 $n3 1.5Mb 10ms DropTail
$ns duplex-link $n2 $n4 1.5Mb 10ms DropTail
$ns duplex-link $n1 $n7 1.5Mb 10ms DropTail
$ns duplex-link $n1 $n5 1.5Mb 10ms DropTail
$ns duplex-link $n4 $n6 1.5Mb 10ms DropTail

#create the rest of the links
for {set i 7} {$i < 120} {incr i} {
      $ns duplex-link $n$i $n([expr ($i+1)%120]) 1Mb 10ms DropTail
}
对于{set i 0}{$i<120}{incr i}{
设置n$i“[$ns节点]”
全球n$i
}
#创建链接
$ns双工链路$n0$n1 1.5Mb 10ms垂尾
$ns双工链路$n0$n2 1.5Mb 10ms垂尾
$ns双工链路$n2$n3 1.5Mb 10ms垂尾
$ns双工链路$n2$n4 1.5Mb 10ms垂尾
$ns双工链路$n1$n7 1.5Mb 10ms垂尾
$ns双工链路$n1$n5 1.5Mb 10ms垂尾
$ns双工链路$n4$n6 1.5Mb 10ms DropTail
#创建其余的链接
对于{set i 7}{$i<120}{incr i}{
$ns双工链路$n$i$n([expr($i+1)%120])1Mb 10ms下拉式
}

Tcl的
$
语法不解析非字母数字变量名(我稍后将介绍一些例外情况),因此它停止解析
n
后面的
$n$I
的第一部分。这是解析器的一个限制,但Tcl本身几乎允许语法中的任何内容

其中一个例外是
::
名称空间分隔符也是允许的,另一个例外是您可以在
{
大括号
}
中放置一个复杂的文字变量名,如
${n$i}
。但这在这里并没有帮助,因为您不能用这种方式将变量替换为变量名

你该怎么办 使用数组。表单
$somename(stuff to do a index)
允许在
stuff to do a index
中进行全范围的替换,但括号中的一些限制并不重要

global ni;  # <-- you might not need this!
for {set i 0} {$i < 120} {incr i} {
    set ni($i) "[$ns node]"
}

# Create links
$ns duplex-link $ni(0) $ni(1) 1.5Mb 10ms DropTail
$ns duplex-link $ni(0) $ni(2) 1.5Mb 10ms DropTail
$ns duplex-link $ni(2) $ni(3) 1.5Mb 10ms DropTail
$ns duplex-link $ni(2) $ni(4) 1.5Mb 10ms DropTail
$ns duplex-link $ni(1) $ni(7) 1.5Mb 10ms DropTail
$ns duplex-link $ni(1) $ni(5) 1.5Mb 10ms DropTail
$ns duplex-link $ni(4) $ni(6) 1.5Mb 10ms DropTail

#create the rest of the links
for {set i 7} {$i < 120} {incr i} {
    $ns duplex-link $ni($i) $n([expr ($i+1)%120]) 1Mb 10ms DropTail
}
您还可以使用
upvar 0
为变量创建别名,然后可以正常操作该别名:

upvar 0 n$i myAlias
$ns duplex-link $myAlias $n([expr ($i+1)%120]) 1Mb 10ms DropTail
更难看的是这种带有
subst
的结构:

$ns duplex-link [subst "\$n$i"] $n([expr ($i+1)%120]) 1Mb 10ms DropTail

在那之后,
eval
return-level0
(这实际上是有效的:奇怪但真实!)和诸如此类的东西会让事情变得非常糟糕,但真的不要这样做。数组真的非常适合这种类型的东西。

Tcl的
$
语法不解析非字母数字变量名(我稍后将介绍一些例外情况),因此它停止解析
n
之后的
$n$I
的第一部分。这是解析器的一个限制,但Tcl本身几乎允许语法中的任何内容

其中一个例外是
::
名称空间分隔符也是允许的,另一个例外是您可以在
{
大括号
}
中放置一个复杂的文字变量名,如
${n$i}
。但这在这里并没有帮助,因为您不能用这种方式将变量替换为变量名

你该怎么办 使用数组。表单
$somename(stuff to do a index)
允许在
stuff to do a index
中进行全范围的替换,但括号中的一些限制并不重要

global ni;  # <-- you might not need this!
for {set i 0} {$i < 120} {incr i} {
    set ni($i) "[$ns node]"
}

# Create links
$ns duplex-link $ni(0) $ni(1) 1.5Mb 10ms DropTail
$ns duplex-link $ni(0) $ni(2) 1.5Mb 10ms DropTail
$ns duplex-link $ni(2) $ni(3) 1.5Mb 10ms DropTail
$ns duplex-link $ni(2) $ni(4) 1.5Mb 10ms DropTail
$ns duplex-link $ni(1) $ni(7) 1.5Mb 10ms DropTail
$ns duplex-link $ni(1) $ni(5) 1.5Mb 10ms DropTail
$ns duplex-link $ni(4) $ni(6) 1.5Mb 10ms DropTail

#create the rest of the links
for {set i 7} {$i < 120} {incr i} {
    $ns duplex-link $ni($i) $n([expr ($i+1)%120]) 1Mb 10ms DropTail
}
您还可以使用
upvar 0
为变量创建别名,然后可以正常操作该别名:

upvar 0 n$i myAlias
$ns duplex-link $myAlias $n([expr ($i+1)%120]) 1Mb 10ms DropTail
更难看的是这种带有
subst
的结构:

$ns duplex-link [subst "\$n$i"] $n([expr ($i+1)%120]) 1Mb 10ms DropTail

在那之后,
eval
return-level0
(这实际上是有效的:奇怪但真实!)和诸如此类的东西会让事情变得非常糟糕,但真的不要这样做。阵列真的非常适合这种情况。

为了清晰起见,我将介绍一些临时变量:

for {set i 7} {$i < 120} {incr i} {
      set node1 n$i
      set node2 n[expr {($i + 1)%120}]
      $ns duplex-link [set $node1] [set $node2] 1Mb 10ms DropTail
}
对于{set i 7}{$i<120}{incr i}{
设置节点1 n$i
设置节点2 n[expr{($i+1)%120}]
$ns双工链路[设置$node1][设置$node2]1Mb 10ms下拉列表
}
仅使用单个参数(变量名称)调用set将返回该变量的值

或者,可以使用subst命令:

for {set i 7} {$i < 120} {incr i} {
      set node1 n$i
      set node2 n[expr {($i + 1)%120}]
      $ns duplex-link [subst $$node1] [subst $$node2] 1Mb 10ms DropTail
}
对于{set i 7}{$i<120}{incr i}{
设置节点1 n$i
设置节点2 n[expr{($i+1)%120}]
$ns双工链路[subst$$node1][subst$$node2]1Mb 10ms DropTail
}

为了清晰起见,我将介绍一些临时变量:

for {set i 7} {$i < 120} {incr i} {
      set node1 n$i
      set node2 n[expr {($i + 1)%120}]
      $ns duplex-link [set $node1] [set $node2] 1Mb 10ms DropTail
}
对于{set i 7}{$i<120}{incr i}{
设置节点1 n$i
设置节点2 n[expr{($i+1)%120}]
$ns双工链路[设置$node1][设置$node2]1Mb 10ms下拉列表
}
仅使用单个参数(变量名称)调用set将返回该变量的值

或者,可以使用subst命令:

for {set i 7} {$i < 120} {incr i} {
      set node1 n$i
      set node2 n[expr {($i + 1)%120}]
      $ns duplex-link [subst $$node1] [subst $$node2] 1Mb 10ms DropTail
}
对于{set i 7}{$i<120}{incr i}{
设置节点1 n$i
设置节点2 n[expr{($i+1)%120}]
$ns双工链路[subst$$node1][subst$$node2]1Mb 10ms DropTail
}

实际上,为了清晰起见,最好使用Donal的解决方案。它还有一个额外的好处,就是为了调试和诊断的目的,可以更容易地列出所有定义的元素,并且如果您最终将其分解为进程并需要将其作为参数传递,那么它会更清晰。实际上,为了清晰起见,最好使用Donal的解决方案。它还有一个额外的好处,就是可以更容易地列出所有已定义的元素,以用于调试和诊断目的,并且如果您最终将其分解为进程并需要将其作为参数传递,那么它会更加清晰。