尝试使用 while 循环来执行“下一个”操作。 for 循环的 arg 生成 #arg 错误

发布于 2024-10-10 12:36:51 字数 1486 浏览 4 评论 0原文

我正在尝试自学使用 Tcl 进行编程。我为自己设定的学习 Tcl 的任务是解决 8 个皇后问题。我创建程序的方法是连续“原型化”解决方案。
我之前问过一个与正确布局嵌套 for 循环相关的问题,并收到了有用的答案。
令我沮丧的是,我发现我的代码的下一个开发会创建相同的解释器错误:“错误的#args”
我一直小心地在 while 循环命令之前的行末尾有一个左大括号。 我还尝试将 whileloop 的参数放在大括号中。这会产生不同的错误。我真诚地尝试理解 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
正如我的文本中所述,我确实支撑了 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   
}

但这会产生致命的解释器错误:“编译时未知数学函数‘r2’ while { r2($r2p ....”

Am attempting to teach myself to program using Tcl. The task i've set myself to motivate my learning of Tcl is to solve the 8 queens problem. My approach to creating a program is to successively 'prototype' a solution.
I have asked an earlier question related to the correctly laying out the nested for loops and received a helpful answer.
To my dismay I find that the next development of my code creates the same interpreter error : "wrong # args"
I have been careful to have an open brace at the end of the line preceding the while loop command.
I've also tried to put the arguments of the whileloop in braces. This generates a different error. I have sincerely tried to understand the Tcl syntax man page - not too successfully - suggested by the answerer of my earlier question.
Here is the code

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

Where am I going wrong?

EDIT : to provide clear reply @slebetman
As stated in my text, I did brace the arguments of the whileloop (indeed that was how i first wrote the code) below is exactly the layout of the r2 forloop tried:

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   
}

but this generates the fatal interpreter error : "unknown math function 'r2' while compiling while { r2($r2p .... "

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

捂风挽笑 2024-10-17 12:36:51

虽然期望只有两个参数。所以你的代码应该是:

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

尽管我不得不说,这是一个放置 while 的奇怪地方。

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

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

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

您的代码发生的情况是 expr 解析器(这是 whileiffor 等用来处理表达式的)看起来在您的 r2($r2p) 处,并且不将其识别为变量访问,因此尝试将其作为 mathfunc 执行(例如 sin()tan ()round()) 然后失败,因为没有 r2() 函数。


补充说明:

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

请阅读我对另一个问题的回复,以更详细地解释发生的情况:使用 Tcl 将 if 语句中的表达式计算为 true

While expects only two arguments. So your code should be:

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

though I have to say, that's a weird palce to put a while.

As for your second problem of an error generated while trying to access the array r2, the problem is you didn't use $ substitution to get to that value. That is a slightly different problem which stems from a misunderstanding of how variables work in Tcl.

Tcl variables don't really work the same way as variables in other languages. To access the value of a variable you must either use the return value of the set command (for example [set r2p]) or, as a shortcut, use $ substitution by appending the $ character in front of your variable name (for example $r2p). On the other hand, to manipulate a variable you must use the variable name itself without the $ sign (for example r2p).

This is not really as strange as it sounds. This works exactly the same way pointers work in C only C uses the * character instead of $.

What was happening with your code is that the expr parser (which is what is used by while, if, for etc to handle expressions) looks at your r2($r2p) and doesn't recognize it as a variable access and so tries to execute it as a mathfunc (like sin() or tan() or round()) which then fails because there is no r2() function.


Additional explanation:

It should be noted that neither for nor while are part of tcl syntax. They are merely functions/commands that you call. Like in any other language, how a function accepts its arguments depends on how it was written. So to figure out how to use while or for you really need to read the documentation for them instead of the tcl syntax documentation.

Read my reply to this other question for a more detailed explanation of what's going on: evaluating an expression to true in a if statement with Tcl

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文