Другие языки программирования и технологии

*.bat - Не работает set /a внутри цикла for!

*.bat - Не работает set /a внутри цикла for

Таблица умножения через bat-ник

@echo off
FOR /L %%i IN (1,1,9) DO FOR /L %%j IN (1,1,9) DO (
set /a d=%%i*%%j
echo %%i*%%j=%d%
if %%j==9 echo -------------)

Подскажите пожалуйста, почему не работает set /a "Умножение переменных цикла"
Все очень просто. Разгадка содержится в хелпе команды set:
===================
Связывание времени выполнения для переменных среды окружения полезно при обходе
ограничений раннего связывания, которое происходит при первом чтении текстовой
строки, а не при ее выполнении. Следующий пример демонстрирует возникающую
проблему при использовании раннего связывания переменных:

set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "%VAR%" == "after" @echo Тело внутреннего оператора сравнения
)

Данное сообщение не будет выводиться, т. к. %VAR% в ОБОИХ выражениях IF
подставляется в момент первого использования в первом IF, в том числе и в тело
первого ветвления IF, которое является составным выражением. В IF внутри
составного выражения в действительности сравниваются значения "before" и
"after", что заведомо ложно. Следующий пример демонстрирует подобную ошибку:

set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%

в данном случае список файлов текущей папки никогда не будет построен. Вместо
этого, значением переменной LIST будет имя последнего найденного файла.
И вновь, это случилось потому, что %LIST% подставляется всего один раз -
в момент обработки выражения FOR, когда список еще пуст.
Фактически, приведенный фрагмент эквивалентен следующему примеру:

for %i in (*) do set LIST= %i

в котором имя последнего найденного файла сохраняется в переменной LIST.

Связывание времени выполнения для переменных среды окружения происходит при
использовании специального символа (восклицательного знака) , обозначающего
проведение сопоставления во время выполнения. Если включена поддержка связывания
времени выполнения, то для достижения ожидаемых результатов приведенные выше
фрагменты должны быть изменены следующим образом:

set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "!VAR!" == "after" @echo Тело внутреннего оператора сравнения
)

set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%
============

Таким образом, меняем текст таким образом:
@echo off
setlocal EnableDelayedExpansion
FOR /L %%i IN (1,1,9) DO FOR /L %%j IN (1,1,9) DO (
set /a d=%%i*%%j
echo %%i*%%j=!d!
if %%j==9 echo -------------
)
АС
Александр Санычев
14 270
Лучший ответ
прикольно) проверила, работает