Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Религиозные войны > Оператор goto


Автор: bartram 6.10.2004, 15:44
Забыл как пользоватся оператооом goto, помогите вспомнить? rolleyes.gif

Автор: Alex 6.10.2004, 15:51
А позволь спросить, ЗАЧЕМ??? qstn.gif

Автор: p0s0l 6.10.2004, 16:23
Код
label metka1;
...
begin
 goto metka1;

metka1:
 ...
end;

Автор: bartram 6.10.2004, 16:28
Цитата(Alex @ 6.10.2004, 15:51)
А позволь спросить, ЗАЧЕМ???

А ты что не знаешь зачем он используется...?

Автор: p0s0l 6.10.2004, 16:35
bartram, просто всегда можно обойтись без goto.
Я лично вообще им не пользуюсь. ИМХО, это некрасиво...

Автор: bartram 6.10.2004, 17:13
Цитата(p0s0l @ 6.10.2004, 16:35)
bartram, просто всегда можно обойтись без goto. Я лично вообще им не пользуюсь. ИМХО, это некрасиво...

Можешь предложить альтернативу?

Автор: Garabar 6.10.2004, 17:27
Цитата
Можешь предложить альтернативу?

Ууу... приведи пример где без него не обайтись biggrin.gif

Автор: p0s0l 6.10.2004, 17:29
Приведи конкрентый код, где ты используешь goto, и попробуем сделать без goto...

Автор: Garabar 6.10.2004, 17:45
Цитата
Приведи конкрентый код, где ты используешь goto, и попробуем сделать без goto...

Спорим на ящик пива не приведёт))))

Автор: Akina 6.10.2004, 17:47
Garabar
Цитата
Спорим на ящик пива не приведёт

на Дельфах, пожалуй, нет... на Барсике - запросто biggrin.gif

Автор: Garabar 6.10.2004, 18:00

[/quote]на Дельфах, пожалуй, нет... на Барсике - запросто [quote]
Ну мы же добропорядочные форумисты))) не забываем тему форума))))

Автор: p0s0l 6.10.2004, 20:11
Без goto в любом случае можно обойтись. Вот только видал тексты с goto, где уж лучше закрыть глаза на использование goto, чем переделывать (хотя если бы изначально правильно писались те проги, то можно было бы спокойно без goto обойтись)...

Автор: Pakshin A. S. 6.10.2004, 20:24
Давайте ваш код! С циклами While & Repeat всё можно решить и без break, exit и меток!!!

Автор: Alex 6.10.2004, 20:27
я бы сказал так писать как угодно, но только не с использованием goto

Автор: Pakshin A. S. 6.10.2004, 20:33
Когда меня учили, мне говорили: забудь про метки и GoTo!

Автор: Girder 7.10.2004, 09:54
Цитата
Когда меня учили, мне говорили: забудь про метки и GoTo!
Тут дело вот в чем: очень часто люди освоив что либо, перестают в последствии восполнять знания в этом вопросе.
Лично я не вижу ни чего плохого в использовании Goto в последних версия компилятора, единственное что плохо: читабельность кода ухудшается и можно запутать компилятор в генерации оптимального кода.
Рассмотрим примеры:
-Компилятор "запутался" smile.gif
Код
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
label i_Zero,i_NoZero;
begin
i:=100;
Caption:='';
if i<>0 then goto i_NoZero else goto i_Zero;
i_NoZero:
Caption:=IntToStr(i);
i_Zero:
end;
Если посмотреть мнемонику скомпилированного кода - увидем два перехода (т.е. один лишний!)
Код
test esi,esi
jz +$02
jmp +$14
Т.е. не есть гуд!
-Компилятор справился smile.gif
Код
procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
label i_Zero,i_NoZero;
begin
i:=100;
Caption:='';
if i=0 then goto i_Zero else goto i_NoZero;
i_NoZero:
Caption:=IntToStr(i);
i_Zero:
end;
Если посмотреть мнемонику этого кода - увидем один переход! Компилятор справился smile.gif
Код
test esi,esi
jz +$14

-Код без Goto
Код
procedure TForm1.Button3Click(Sender: TObject);
var i:integer;
begin
i:=100;
Caption:='';
if i<>0 then
 begin
  Caption:=IntToStr(i);
 end;
end;
Сгенерированный код полностью эквивалентен второму примеру, как говорится без комментариев. Т.е. во втором примере использование Goto не ухудшил скомпилированный код!

PS: В более ранних версиях компилятор был не такой "умный" smile.gif (когда он по умнел - уже не помню) . И не надо забывать что язык высокого уровня - это "абстракция". В реальности будут и переходы и все такое, вопрос в другом - на сколько это будет оптимально, для предсказаний ветвлений! Ну и на последок: при работе с портами очень часто необходимо добавлять "переходы-заглушки"(без комментариев).

Автор: bartram 7.10.2004, 13:33
Цитата(Girder @ 7.10.2004, 09:54)
Цитата
Когда меня учили, мне говорили: забудь про метки и GoTo!
Тут дело вот в чем: очень часто люди освоив что либо, перестают в последствии восполнять знания в этом вопросе.
Лично я не вижу ни чего плохого в использовании Goto в последних версия компилятора, единственное что плохо: читабельность кода ухудшается и можно запутать компилятор в генерации оптимального кода.
Рассмотрим примеры:
-Компилятор "запутался" smile.gif
Код
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
label i_Zero,i_NoZero;
begin
i:=100;
Caption:='';
if i<>0 then goto i_NoZero else goto i_Zero;
i_NoZero:
Caption:=IntToStr(i);
i_Zero:
end;
Если посмотреть мнемонику скомпилированного кода - увидем два перехода (т.е. один лишний!)
Код
test esi,esi
jz +$02
jmp +$14
Т.е. не есть гуд!
-Компилятор справился smile.gif
Код
procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
label i_Zero,i_NoZero;
begin
i:=100;
Caption:='';
if i=0 then goto i_Zero else goto i_NoZero;
i_NoZero:
Caption:=IntToStr(i);
i_Zero:
end;
Если посмотреть мнемонику этого кода - увидем один переход! Компилятор справился smile.gif
Код
test esi,esi
jz +$14

-Код без Goto
Код
procedure TForm1.Button3Click(Sender: TObject);
var i:integer;
begin
i:=100;
Caption:='';
if i<>0 then
 begin
  Caption:=IntToStr(i);
 end;
end;
Сгенерированный код полностью эквивалентен второму примеру, как говорится без комментариев. Т.е. во втором примере использование Goto не ухудшил скомпилированный код!

PS: В более ранних версиях компилятор был не такой "умный" smile.gif (когда он по умнел - уже не помню) . И не надо забывать что язык высокого уровня - это "абстракция". В реальности будут и переходы и все такое, вопрос в другом - на сколько это будет оптимально, для предсказаний ветвлений! Ну и на последок: при работе с портами очень часто необходимо добавлять "переходы-заглушки"(без комментариев).

Вот, вот именно это я и имел ввиду! А вы тут зачем go to без него можно обойтись! Свой пример попозже напишу...

Автор: EKoshelev 8.10.2004, 08:22
А когда меня учили (я тогда ещё на спектруме программировал и ессно не знал что такое уайл и репит-антил). Дак вот тот человек в очень корректной форме нам хотел сказать, что goto в своих прогах используют только самые распоследние "№"%:?;%"№ и #$%#@... Я конечно ни на чего не намекаю... adv/54.gif


bartram
Давай пиши свой код с готами или алгоритм кидай. Я готов спорить на миллиард ящиков пива adv/76.gif, что любую хрень можно без готов написать.

Автор: Zzz 8.10.2004, 09:03
Цитата(EKoshelev @ 8.10.2004, 00:22)
bartram
Давай пиши свой код с готами или алгоритм кидай. Я готов спорить на миллиард ящиков пива adv/76.gif, что любую хрень можно без готов написать.

Ну давай:

Сделать бесконечную (зацикливающуюся) программу на языке Паскаль без использования asm-вставок, циклов. Программа заносит в 300 порт "1". Программа носит учебный характер.

Мой пример
Код

l1 : port[$300]:=1;
goto l1;


smile.gif))))))))))

Ваш пример:

Автор: Pakshin A. S. 8.10.2004, 12:56
Код

begin
port[$300]:=1;
Exec('C:\MyProg.exe') {Точно не помню, но суть запуск exe-файла}
end.

biggrin.gif
Добавлено @ 13:00
Цитата(Zzz @ 8.10.2004, 10:03)
без использования asm-вставок, циклов.

А что, прямо так и задано?! omg.gif

Автор: EKoshelev 8.10.2004, 14:43
Zzz

A чё вот так нельзя?

Код

while true do port[$300]:=1

Добавлено @ 14:47
А чё-то это, блин, да... Я не понял, что значит без циклов? Чё ещё за условие такое имбицильное?

Автор: Girder 8.10.2004, 19:26
p0s0l спасибо... что перенес этот топик в этот раздел - где ему самое место!

PS: Большая просьба - bartram-а не обижать в последствии!

Ну... у кого какие мнения?

Автор: chipset 8.10.2004, 19:39
Цитата
без использования asm-вставок, циклов.

Это надуманная задача и непрактичная.
я видел примеры где без goto обойтись.. точно, но не помню где
в некоторых случаях оно действительно помогает, если надо быстро выпрыгнуть за пару скобок без громадины исключений и.т.д..

Добавлено @ 19:39
Всё ИМХО

Автор: MacTep 8.10.2004, 22:16
Мне сказали, что goto - это дурной тон программирования. Метки используются только в ассемблере, а это уже совсем другая история! smile.gif

Автор: Sun 8.10.2004, 22:35
http://forum.vingrad.ru/index.php?showtopic=3273

Автор: Pakshin A. S. 9.10.2004, 18:02
Цитата(Zzz @ 8.10.2004, 10:03)
без использования asm-вставок, циклов

Цитата(Girder @ 8.10.2004, 20:26)
Ну... у кого какие мнения?

Цитата(Pakshin @ 8.10.2004, 13:56)
begin
port[$300]:=1;
Exec('C:\MyProg.exe') {Точно не помню, но суть запуск exe-файла}
end.

Код

procedure Port1;
begin
port[$300]:=1;
Port1
end;

begin
Port1
end.


Вот два примера решения задачи без использования asm и циклов!

Автор: p0s0l 9.10.2004, 19:19
Только стек-то не резиновый...

Автор: Pakshin A. S. 9.10.2004, 19:25
Sorry, не понял... sad.gif

Автор: p0s0l 9.10.2004, 19:30
Во втором случае у тебя рекурсивная процедура.
При каждом вызове в стек будет заносится адрес возврата...

Автор: Dr.Death 9.10.2004, 19:46
Pakshin A. S.
При вызове процедуры у тебя заноситься в стэк адрес, откуда был вызвана она, при завершении он изымается и делается return на то место, откуда была вызвана процедура. А в твоем случае получается, что никогда не будет возвращение, все время запись в стэк. А стэк у нас ограничен в размерах.

Автор: p0s0l 10.10.2004, 03:17
Хотя, признаться, есть исключение...Если прога скомпилирована для реального режима, то при переполнении стека ничего не произойдёт критичного, т.к. никакой проверки в этом режиме не происходит: просто когда в стек занесут 64кб данных, заполнение пойдёт заново...

Автор: Pakshin A. S. 10.10.2004, 11:06
А как насчет этого:
Код

begin
port[$300]:=1;
Exec('C:\MyProg.exe') {Точно не помню, но суть запуск exe-файла}
end.

Автор: Girder 10.10.2004, 22:42
Pakshin A. S. приведу два примера, но без goto.

1)
Код
if (R=0)or(R2=0) then
begin
 ...
end;

2)
Код
if (R and R2)=0 then
begin
 ...
end;

В чем разница и если она? ответь... просто интересно лично твое мнение.

Забыл добавить smile.gif :
-вариант 1: R и R2 - есть бит;
-вариант 2: R и R2 - размерностью больше чем один бит.

Автор: Chingachguk 10.10.2004, 23:45
Girder

Прими мое уважение за хороший анализ целесообразности применения goto. Большинство людей где-то услышали эту "аксиому" - типа goto это ацтой и повторяют это не задумываясь - а собственно почему ?

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


Автор: NightGoblin 11.10.2004, 05:56
А, по-моему, если кто-то по ночам зажигает звезды, значит, это кому-нибудь нужно...

Или goto просто забыли убрать из C++ за ненадобностью?...

Согласен, читаемость он ухудшает. Согласен, почти всегда без него можно обойтись. Но иногда (подчеркиваю - иногда, даже редко) возникают такие ситуации, что писать "кошерный" код без единого goto оборачивается существенной потерей производительности. Да и читаемость ухудшить можно и без всяких goto - неужели вам не попадались программы, нечитаемые из-за одного только форматирования?
Добавлено @ 06:00
Zzz, извини, но я поддержу тех, кто сказал, что это надуманная и ненужная задача. Зачем кому-то понадобилось делать что-то без циклов?... Думаю, все же полезнее будет обсудить использование goto в реальных ситуациях...

Автор: gray_k 11.10.2004, 10:45
http://forum.vingrad.ru/index.php?showtopic=26914&hl=goto&st=0

Автор: Girder 11.10.2004, 11:14
ИМХО:
- Хорошо сказано!
Цитата
Оператор GOTO не плох сам по себе, а плох в неподходящем месте

Автор: Sail 19.10.2004, 20:53
Гото иногда все-таки стоит использовать, например, когда надо брейкнуться сразу из 2х вложенных циклов.
Пусть надо найти в 2Д-массиве индексы первого нулевого элемента.
Имхо следующий код с гото читабельнее:

Код


var a:array[0..99,0..99]of integer;
i,j:integer;

...

for i:=0 to 99 do
   for j:=0 to 99 do begin
       if a[i,j]=0 then goto bre;
   end;
bre:

Автор: Sun 20.10.2004, 11:33
Цитата(Sail @ 19.10.2004, 17:53)
Гото иногда все-таки стоит использовать, например, когда надо брейкнуться сразу из 2х вложенных циклов.

В Java в таких случаях я просто ставлю return, для выхода из функции.

Автор: Pakshin A. S. 20.10.2004, 19:20
Цитата(Sail @ 19.10.2004, 21:53)
Гото иногда все-таки стоит использовать, например, когда надо брейкнуться сразу из 2х вложенных циклов.
Пусть надо найти в 2Д-массиве индексы первого нулевого элемента.
Имхо следующий код с гото читабельнее:


Код


Код
var a:array[0..99,0..99]of integer;
i,j:integer;

...

for i:=0 to 99 do
for j:=0 to 99 do begin
  if a[i,j]=0 then goto bre;
end;
bre:


:D :) :D Классический вариант!!!

Код

var
a: array of integer;
i,j:integer;
begin
<...>
i:=0;
j:=0;
while (a[i,j]<>0) and (i<=Len_i) do
 begin
  while (a[i,j]<>0) and (j<=Len_j) do
   inc(j);
  if a[i,j]<>0
   then
    inc(i);
 end;
end;

А где тут Label & GoTo :D

Автор: Chingachguk 20.10.2004, 20:05
Цитата
А где тут Label & GoTo


Не знаю, но ошибка тут точно есть :)

Автор: Pakshin A. S. 20.10.2004, 20:30
Точно! :stena
Не дописал
Код
<>0
then
 begin
  inc(i);
  j:=0;
 end

Автор: Дрон 20.10.2004, 22:45
Pakshin A. S.
В твоём коде аж три проверки a[i,j]<>0, а в коде с goto только одна.
Как же быть с быстродействием проги? :)
Добавлено @ 22:47
Да и действительно, с goto текст кода гораздо читабельнее и компактней (в этом примере с массивом, а не вообще :) ).

ЗЫ: Сам я goto не использовал уже года два :)

Автор: Chingachguk 21.10.2004, 08:21
Цитата
Как же быть с быстродействием проги?


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

Автор: Pakshin A. S. 21.10.2004, 18:12
Дрон

Надо же чем-то иногда жертвовать, тем более при современных скоростях...
Представь: гонимся за быстродействием, поэтому везде пизаем GoTo и т. п. -> Получаем полнейший бред при чтении, допустим одной процедуры (очень большой), т. к. тама где-то с десяток переходов по ходу действия процедуры и несколько переходов назад... ;-)

Автор: Pakshin A. S. 22.10.2004, 17:02
Код

i:=0;
j:=0;
while (a[i,j[<>0) and (i <=Max_i) and (j <= Max_j) do
begin
 inc(j);
 if j > Max_j
  then
   begin
    inc(i);
    j:=0
  end
end;

:D

Автор: sergejzr 22.10.2004, 17:15
Цитата(Chingachguk @ 21.10.2004, 07:21)
а я читал этот "простой пример без GOTO" минуты 3

Дело может не в самом GOTO
В Паскале есть маленькая проблемка :)
При применении проверок итд пишется очень много слов :)
Поэтому простенькие примеры становятся трудночитабельными :)
Например если сравнить с Си:
Код
If(x=0)then  begin ....... else.........end

Это уже легче читается :)
Код
if(x){ ..... } else{.........}


Ну а на асме этот пример читается легче всего :)

Повторяю, вышесказанное относится к простеньким примерам :)


Если ваш пример на 1 КБ и в нём 5 меток и 10 GOTO, прочесть и понять его слёту практически невозможно :)

Лично я использую GOTO в маленьких функциях, строчек например на 10-20, где его работу можно конкретно проследить и понять. И всегда особенно комментирую это место.
Мне кажется, что так программировать не только можно, но и желательно из за быстродействия :)


Автор: Girder 22.10.2004, 17:43
Цитата
Как же быть с быстродействием проги? 
Проиграет 100%... код Pakshin A. S., т.к. интенсивно используются команды imul RR,RR,DD и команды вида XXX RR,[RR+RR*8] и еже с ними... при этом там будет 4 проверки(+ еще одна) :) ... в реальности. А под For будет скомпилирован совершенно другой код... :)

Автор: Zandr 1.11.2004, 07:28
Код

for i:=0 to 99 do
for j:=0 to 99 do begin
 if a[i,j]=0 then goto bre;
end;
bre:


Хммм... На Java, например это выглядит так:
Код

bre:
for (int i = 0; i < 100; i++)
   for (int j = 0; j < 100; j++)
       if (a[i][j] == 0) break bre;

Автор: Medved 23.12.2004, 16:32
Цитата(Pakshin @ 20.10.2004, 22:20)
Гото иногда все-таки стоит использовать, например, когда надо брейкнуться сразу из 2х вложенных циклов.
Пусть надо найти в 2Д-массиве индексы первого нулевого элемента.
Имхо следующий код с гото читабельнее:


Обычно для этого такой код оформляют в виде функции. Чтобы можно было выйти из вложенного цикла Return (С подобные) или Exit (Delphi)

Автор: Ser9a 9.3.2005, 00:39
Все перпода говорят что GoTo есть плохой стиль.

Автор: sergejzr 9.3.2005, 00:44
А раньше они говорили, что коммунизм - лучшаий строй общества.

GOTO - дело вкуса smile

Автор: Secandr 9.3.2005, 09:27
Я вот даже не знаю, есть ли в php и perl`е оператор goto. А в паскале применял smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)