*.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 "Умножение переменных цикла"
Другие языки программирования и технологии
*.bat - Не работает set /a внутри цикла for!
Все очень просто. Разгадка содержится в хелпе команды 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 -------------
)
===================
Связывание времени выполнения для переменных среды окружения полезно при обходе
ограничений раннего связывания, которое происходит при первом чтении текстовой
строки, а не при ее выполнении. Следующий пример демонстрирует возникающую
проблему при использовании раннего связывания переменных:
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 -------------
)
прикольно) проверила, работает
Похожие вопросы
- Цикл for в Дельфи или Паскале
- Вопрос про цикл For
- По-человечески объясните цикл "for"
- Хорошо ли использовать бесконечный цикл for в C++?
- Объясните чайнику на пальцах: Как работает цикл (for) в C# ?
- цикл for не может обрабатывать массивы? (паскаль)
- C++. В операторе switch нельзя разве использовать case x? а x пробежать в цикле for?
- Вопрос по стилю в Си. Читаю C Elements of Style (Steve Qualline), встретила такой стиль записи цикла for
- С++, Чем отличаеться цикл for, от while?
- в языке СИ (просто СИ!!!!) чем отличаются два цикла. for(t=0; t