尝试对for循环的“next”arg使用while循环会生成#arg错误

时间:2011-01-05 00:14:32

标签: tcl

我试图用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   
    }
}

我哪里错了?

编辑:提供明确答复@slebetman
正如我在文中所述,我确实支持while循环的参数(实际上这就是我第一次编写代码的方式)下面正是r2 forloop尝试的布局:

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   
}

但这会产生致命的解释器错误:“未知数学函数'r2'在编译期间{r2($ r2p ....”

1 个答案:

答案 0 :(得分:5)

虽然只需要两个参数。所以你的代码应该是:

while {$r2($r2p) == $notallowd} {incr r2p}

虽然我不得不说,放while这是一个奇怪的地方。

至于您在尝试访问数组r2时产生错误的第二个问题,问题是您没有使用$ substitution来获取该值。这是一个稍微不同的问题,源于对变量如何在Tcl中起作用的误解。

Tcl变量与其他语言中的变量的工作方式不同。要访问变量的值,您必须使用set命令的返回值(例如[set r2p]),或者,作为快捷方式,通过在变量前面附加$字符来使用$ substitution名称(例如$r2p)。另一方面,要操作变量,必须使用不带$符号的变量名称(例如r2p)。

这并不像听起来那么奇怪。这与指针在C中的工作方式完全相同,只有C使用*字符而不是$。

您的代码发生的事情是,expr解析器(whileiffor等用来处理表达式的内容)会查看您的{{1}并且不会将其识别为变量访问,因此尝试将其作为mathfunc(如r2($r2p)sin()tan())执行,然后失败,因为没有{{1功能。


补充说明:

应该注意,round()r2()都不是tcl语法的一部分。它们只是您调用的函数/命令。与任何其他语言一样,函数如何接受其参数取决于它的编写方式。因此,要弄清楚如何使用forwhile,您真的需要阅读它们的文档而不是tcl语法文档。

请阅读我对其他问题的回复,以便更详细地了解正在发生的事情:evaluating an expression to true in a if statement with Tcl