1

以下代码产生错误:

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$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
}
4

2 回答 2

4

Tcl 的$语法不解析非字母数字变量名(有一些例外,我稍后会谈到),因此它停止尝试$n$i解析n. 这是解析器的一个限制,但 Tcl 本身几乎允许任何内容。

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

你应该做什么

使用数组。该形式$somename(stuff-to-do-an-index)允许在 中进行全方位的替换stuff-to-do-an-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
}

其他选择

您可以使用单参数版本的set来读取变量(它已记录在案,但对 Tcl 新手来说有点晦涩难懂)。

$ns duplex-link [set n$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

在那之后,它变得非常讨厌evaland return -level 0(这实际上很有效:奇怪但真实!)以及各种类似的东西,但真的不要那样做。数组非常适合这种事情,真的。

于 2013-05-06T22:30:01.647 回答
0

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

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
}

仅使用单个 arg(var 的名称)调用 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
}
于 2013-05-06T22:31:14.420 回答