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

Jer*_*ryK 1 tcl

我试图教自己用Tcl编程.我自己设定的任务是激励我学习Tcl是为了解决8皇后问题.我创建程序的方法是先后"原型化"解决方案.
我已经问过一个与正确布局嵌套for循环相关的早期问题并得到了一个有用的答案.
令我沮丧的是,我发现我的代码的下一个开发会产生相同的解释器错误:"wrong#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   
    }
}
Run Code Online (Sandbox Code Playgroud)

我哪里错了?

编辑:提供明确的回复@slebetman
正如我在文中所述,我确实支持了whileloop 的参数(实际上这就是我第一次编写代码的方式)下面正是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   
}
Run Code Online (Sandbox Code Playgroud)

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

sle*_*man 5

虽然只期望两个论点.所以你的代码应该是:

while {$r2($r2p) == $notallowd} {incr r2p}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

什么是你的代码发生的是,EXPR解析器(这是所使用的while,if,for等处理表达式)看你r2($r2p),不承认它作为一个变量访问,因此尝试执行它作为一个mathfunc(如sin()tan()或者round()因为没有r2()功能而失败.


补充说明:

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

阅读我对这个其他问题的回复,以获得更详细的解释:使用Tcl在if语句中将表达式计算为true