2013-10-27 5 views
-1

Прекрасно зная о вечном обсуждении является ли хорошей практики использовать GOTO (GOTO still considered harmful?), что я пытаюсь спросить здесь, если есть некоторые недостатки при помощи GOTO , особенно в оболочке CMD/DOS.Недостатки использования GOTO в CMD

К недостатки Я имею в виду, что есть некоторая потеря производительности или некоторые ситуации, когда широкое использование GOTO может привести к прекращению моего сценария (как описано ниже). Я знаю, потому что у TI-BASIC нет хорошего способа создания структурированных программ без него, что повторное использование GOTO на этой платформе в конечном итоге истощит память. Следующая цитата из TIBasicDev объясняет такое поведение:

Используя Goto, чтобы выйти из любого блока кода требует команда End вызывает утечку памяти, которая не будет использоваться, пока программа не завершит работу или выполняет команду возврата, и что замедлит работу вашей программы.

Другим «способом» циклических команд в CMD является использование операторов FOR, которые чрезвычайно специфичны в отношении ожидаемых им аргументов и поэтому не могут использоваться ни в какой ситуации.

+1

«каждый раз, когда используется GOTO, информация о предыдущем GOTO хранится в памяти» - что? Я ничего не знаю о TI-BASIC, но ни один объект, подобный GOTO, который я знаю, не имеет ничего похожего, я не могу представить себе случай использования, и это сильно испортило бы платформу программирования, поэтому я хотел бы получить разъяснения и источники. – delnan

+0

Я на 99.9% уверен, что вы запутываете 'GOTO' с' GOSUB' в TI-BASIC. По крайней мере, в каждом микрокомпьютере BASIC, с которым я когда-либо сталкивался, «GOTO» не хранит, откуда он появился, и фактически на всех других языках программирования. –

+0

@delnan Из [this] (http://tibasicdev.wikidot.com/goto): Использование Goto для выхода из любого блока кода, требующего команды End, вызывает утечку памяти, которая не будет использоваться до завершения работы программы или выполняет команду Return, и это замедлит вашу программу. –

ответ

2

GOTO в сценарии Windows, как правило, безопасен в использовании, а иногда и необходим. Но есть три не интуитивные элементы дизайна, которые стоит отметить:

1) Не GOTO метка помещается в скобки блок кода

Вы можете GOTO метка помещается в скобки блока, но это, вероятно, не даст вам результат, который вы намереваетесь. Например, GOTO в блоке DO цикла FOR цикла немедленно прекратит цикл. Если GOTO ссылается на метку в блоке DO, управление передается правильно в расположение метки, но парсерный анализатор теперь ничего не знает о контексте цикла FOR. Код будет выполнен, как если бы он не был в цикле. См. Принятый ответ (Windows batch) Goto within if block behaves very strangely для получения дополнительной информации.

2) Расположение этикетки может повлиять на производительность.

Это, как правило, не проблема, если вы не имеете дело с действительно большим сценарием.

При выполнении GOTO :label (или CALL :label) пакетный процессор начинает сканирование из текущего места сценария, ища первое вхождение :label. Если он достигнет конца файла, не найдя метку, он возвращается к вершине и продолжает поиск. Ошибка будет поднята, если она достигнет начальной точки, не найдя метку. Поэтому производительность иногда может быть улучшена в очень больших сценариях, структурируя скрипт таким образом, чтобы метки появлялись вскоре после их соответствующего GOTO (или CALL). Конечно, если метка ссылается на многие местоположения, это может быть невозможно.

3) То же метка на самом деле можно безопасно использовать в нескольких местах (не рекомендуется)

После того, как вы понимаете, процесс сканирования метки, описанной в пункте 2 выше, вы можете смело использовать повторно этикетку, если вы внимательны ,

Например, следующий сценарий будет работать должным образом:

@echo off 

for %%A in (1 2 3 X Y Z) do (
    echo %%A 
    if %%A equ 3 goto break 
) 
:break 

for %%A in (A B C 8 9 10) do (
    echo %%A 
    if %%A equ C goto break 
) 
:break 

- ВЫВОД -

1 
2 
3 
A 
B 
C 

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

1

GOTO :label является неотъемлемой частью пакетного кодирования и не имеет встроенных недостатков - это необходимая часть пакетного сценария.

Смежные вопросы