Попытка использовать цикл while для следующего аргумента цикла for приводит к ошибке #arg - PullRequest
1 голос
/ 05 января 2011

Я пытаюсь научить себя программировать с использованием Tcl.Задача, которую я поставил перед собой, чтобы мотивировать свое изучение Tcl, - решить проблему 8 королев.Мой подход к созданию программы состоит в том, чтобы последовательно «прототипировать» решение.
Я задал более ранний вопрос, связанный с правильным размещением вложенных циклов for, и получил полезный ответ.
К моему ужасу, я нахожу, чтоСледующее развитие моего кода создает ту же ошибку интерпретатора: «неправильный # аргумент»
Я старался использовать открывающую скобку в конце строки, предшествующей команде 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 (действительно, именно так я впервые написал код) нижев точности использовался макет forloop r2:

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 Ответ

5 голосов
/ 05 января 2011

Пока ожидает только два аргумента. Итак, ваш код должен быть:

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

хотя я должен сказать, что это странная вещь, чтобы поставить while.

Что касается вашей второй проблемы с ошибкой, сгенерированной при попытке доступа к массиву r2, то проблема в том, что вы не использовали $ substitution для получения этого значения. Это немного другая проблема, которая возникает из-за неправильного понимания того, как переменные работают в Tcl.

Переменные Tcl на самом деле не работают так же, как переменные в других языках. Чтобы получить доступ к значению переменной, вы должны либо использовать возвращаемое значение команды set (например, [set r2p]), либо, в качестве ярлыка, использовать замену $, добавив символ $ перед именем вашей переменной (например, $r2p). С другой стороны, чтобы манипулировать переменной, вы должны использовать само имя переменной без знака $ (например, r2p).

Это не так странно, как кажется. Это работает точно так же, как работают указатели в C, только C использует символ * вместо $.

Что произошло с вашим кодом, так это то, что синтаксический анализатор expr (который используется while, if, for и т. Д. Для обработки выражений) смотрит на ваш r2($r2p) и не распознает его как доступ к переменной и поэтому пытается выполнить его как математическую функцию (например, sin() или tan() или round()), которая затем завершается ошибкой, потому что нет функции r2().


Дополнительное объяснение:

Следует отметить, что ни for, ни while не являются частью синтаксиса tcl. Это просто функции / команды, которые вы вызываете. Как и в любом другом языке, то, как функция принимает свои аргументы, зависит от того, как она была написана. Поэтому, чтобы понять, как использовать while или for, вам действительно нужно прочитать документацию по ним вместо документации по синтаксису tcl.

Прочтите мой ответ на этот другой вопрос для более подробного объяснения того, что происходит: вычисление выражения в true в операторе if с Tcl

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...