Особенности процедур

Особенности возврата данных из подпрограммы

Поскольку в программах командного языка допустимы процедуры, следует осветить важный вопрос - область видимости переменных.
Процедуре доступны все переменные родительского блока.
Это создает определенные неудобства, особенно при использовании сторонних процедур.
Возможно при помощи команды setlocal определить в процедуре собственный уровень локализации, тогда переменные родительского контента будут недоступны. Безусловно, это более безопасный подход, но возникают сложности с возвратом значений в родительский блок.
Рассмотрим это на примерах.


:ADD :: НЕВЕРНО setlocal enableextensions set /a Summa=%1 + %2 set /a k=%Summa% endlocal exit /b 0


В данном случае значение переменной k в процедуре никак не повлияет на значение переменной с тем же именем в родительском блоке. После выполнения команды endlocal значение этой переменной теряется.
Еще один неверный пример:

:ADD :: НЕВЕРНО setlocal enableextensions set /a Summa=%1 + %2 endlocal set /a k=%Summa% exit /b 0


В момент присвоения переменной k родительского блока значение переменной SUMMA уже не существует (точнее, равна пустой строке).
Разобравшись в чем именно здесь сложности перейдем к возможным вариантам решения этой задачи.


:ADD setlocal enableextensions enabledelayedexpansion set /a Summa=%1 + %2 endlocal & set /a k=%Summa% exit /b 0


Рассмотрим работу строки endlocal & set /a k=%Summa%. Командный процессор, разбирая строку, подставит значения переменных среды. Если значение переменной Summa равно, скажем, 7, то строка преобразуется в

endlocal & set /a k=7


После выполнения первой части строки - команды endlocal - значение переменной Summa уже не имеет значения, которое было внутри процедуры, но командный процессор уже подставил значение этой переменной в оператор SET !
И, после выполнения команды endlocal, переменная k уже принадлежит родительскому блоку.

Объединение операторов можно сделать не только амперсандом, но и сделав составной оператор.

:ADD setlocal enableextensions enabledelayedexpansion set /a Summa=%1 + %2 ( endlocal set /a k=%Summa% exit /b 0 )


Как вариант первого решения можно использовать errorlevel для возврата одного числового значения из процедуры.

:sqr :: Квадрат числа %1 setlocal set /a result=%1*%1 endlocal & exit /b %result%


Обращение

call :sqr %a% echo %a%^^2 = %errorlevel%



Описание этого метода есть здесь и здесь

Особенности использования команды CALL

Нельзя не упомянуть еще одну весьма интересную особенность команды CALL.
В некоторых случаях количество вложенных переменных может превышать интеллектуальные способности интерпретатора команд. Самый простой пример - извлечение подстроки в случаях, когда начальная позиция и/или длина подстроки - переменные.
В таких случаях можно использовать недокументированную возможность команды call.
В команде call можно вызывать другую команду, например, SET.
В этом случае параметры обрабатываются иначе и становиться доступными некоторые дополнительные возможности. Часть строки сначала обрабатывается как параметр процедуры, а уже потом как часть команды SET. Проще понять это на примере.


set str=123qwerty456 set n1=3 set n2=6 Call Set d=%%str:~%n1%,%n2%%% Echo d=%d%


Еще одна интересная возможность - сформировать в переменной полностью всю команду с параметрами, а затем отправить ее на исполнение командой call. Иногда в особо тяжелых случаях это помогает)). При использовании этого приема появляется возможность формировать такую строку по частям что иногда немаловажно.
В качестве примера приведу решение той же задачи - выделить подстроку.
Надо заметить, что в данном случае использование такого приема не дает никаких преимуществ по сравнению с предыдущим примером.

set n1=2 set n2=2 set str=asdfghjkl ... set we=set rrr=%%str:~%n1%,%n2%%% call %we% echo %rrr%


Я опять опубликовал чей-то пароль в качестве значения переменной str ? )

Необходимо заметить, что без особой нужды использовать данный прием не стоит, так как это значительно увеличивает время выполнения команды и уменьшает читабельность кода.
-------------------------------------------------------------------------------------------------------


Для вопросов, обсуждений, замечаний, предложений и т. п. можете использовать раздел форума этого сайта (требуется регистрация).






  TopList Rambler Top100 own counter Valid XHTML 1.0 Strict Valid CSS Rambler Top100

Фитотерапия Молитвы Водолечение Юмор Форум Кладовка link О авторе

Фитотерапия Молитвы Водолечение Юмор Форум Кладовка Ссылки О авторе Отправить сообщение Карта сайта Поиск по сайту Главная страница

Copyright © 1999 - 2017  Бронислав Краснер