我试图用Tcl自学编程。我自己设定的任务是激励我学习Tcl是为了解决8皇后问题。我创建程序的方法是先后“原型化”解决方案
我已经问过一个与正确布置嵌套for循环有关的早期问题,并得到了一个有用的答案
令我沮丧的是,我发现我的代码的下一个开发会产生相同的解释器错误:“错误#args”
我一直小心在while循环命令之前的行末尾有一个开括号。
我也尝试将while循环的参数放在括号中。这会产生不同的错误。我真诚地试图理解Tcl语法手册页 - 不太成功 - 由我之前的问题的回答者提出。
这是代码
set allowd 1
set notallowd 0
for {set r1p 1} {$r1p <= 8} {incr r1p } {
puts "1st row q placed at $r1p"
;# re-initialize r2 'free for q placemnt' array after every change of r1 q pos:
for {set i 1 } {$i <= 8} {incr i} { set r2($i) $allowd }
for { set r2($r1p) $notallowd ; set r2([expr $r1p-1]) $notallowd ;
set r2([expr $r1p+1]) $notallowd ; set r2p 1} {$r2p <= 8} {
;# 'next' arg of r2 forloop will be a whileloop :
while r2($r2p)== $notallowd incr r2p } {
puts "2nd row q placed at $r2p" ;# end of 'commnd' arg of r2 forloop
}
}
我哪里错了?
编辑:提供明确答复@slebetmanfor { set r2($r1p) $notallowd ; set r2([expr $r1p-1]) $notallowd ;
set r2([expr $r1p+1]) $notallowd ; set r2p 1} {$r2p <= 8} {
;# 'next' arg of r2 forloop will be a whileloop :
while { r2($r2p)== $notallowd } { incr r2p } } {
puts "2nd row q placed at $r2p" ;# end of 'commnd' arg of r2 forloop
}
但这会产生致命的解释器错误:“未知数学函数'r2'在编译期间{r2($ r2p ....”
答案 0 :(得分:5)
虽然只需要两个参数。所以你的代码应该是:
while {$r2($r2p) == $notallowd} {incr r2p}
虽然我不得不说,放while
这是一个奇怪的地方。
至于您在尝试访问数组r2
时产生错误的第二个问题,问题是您没有使用$ substitution来获取该值。这是一个稍微不同的问题,源于对变量如何在Tcl中起作用的误解。
Tcl变量与其他语言中的变量的工作方式不同。要访问变量的值,您必须使用set
命令的返回值(例如[set r2p]
),或者,作为快捷方式,通过在变量前面附加$字符来使用$ substitution名称(例如$r2p
)。另一方面,要操作变量,必须使用不带$符号的变量名称(例如r2p
)。
这并不像听起来那么奇怪。这与指针在C中的工作方式完全相同,只有C使用*字符而不是$。
您的代码发生的事情是,expr解析器(while
,if
,for
等用来处理表达式的内容)会查看您的{{1}并且不会将其识别为变量访问,因此尝试将其作为mathfunc(如r2($r2p)
或sin()
或tan()
)执行,然后失败,因为没有{{1功能。
补充说明:
应该注意,round()
和r2()
都不是tcl语法的一部分。它们只是您调用的函数/命令。与任何其他语言一样,函数如何接受其参数取决于它的编写方式。因此,要弄清楚如何使用for
或while
,您真的需要阅读它们的文档而不是tcl语法文档。
请阅读我对其他问题的回复,以便更详细地了解正在发生的事情:evaluating an expression to true in a if statement with Tcl