Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.01.2012, 22:31   #11
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

этот IF в начале каждого блока только ухудшает и читаемость и отяжеляет код

Код:
var
BreakCycle:boolean;
begin
 repeat
  if Breakcycle then Break;
  
  <вот здесь тонна кода>
  repeat 
   if Breakcycle then Break;
      <вот здесь тонна кода>
      repeat 
         <вот здесь тонна кода>  
          if A != B then BreakCycle:=True; break;
         <вот здесь тонна кода>
      until <>;
     <вот здесь тонна кода>
   until <>;
   <вот здесь тонна кода>
 until <>;
 
end;
теперь как?
rpy3uH вне форума Ответить с цитированием
Старый 11.01.2012, 22:45   #12
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Хм, а сколько выполняет тактов процессор за 1 строку кода?
для процессора с не RISC архитектутой неудачный вопрос.
тем более учитывая многопоточность и время ядра.
а так RDTCS(вроде так инструкция называется) и вперед, тестить.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 11.01.2012, 22:45   #13
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Метки нужны, потому что они удобны. Поэтому они есть и будут.

Противники меток (которые адекватные) говорят не против них вообще, а против злоупотребления ими, вроде такого:
Код:
i := 0;
L20:
i := i + 1;
if i <= 10 then
 goto L70;
if i > 10 then 
  goto L50;
L50:
WriteLn('Программа завершена.');
Exit;
L70:
WriteLn(i, ' квадрат = ', i * i);
goto L20;
И в этом плане мы все с ними согласны, разве не так?

Что делает этот кусок кода? Я думаю, что никто вот так сходу не скажет. Вот эквивалентный код без меток:
Код:
for i := 1 to 10 do
  WriteLn(i, ' квадрат = ', i * i);
WriteLn('Программа завершена.');
Намного проще читается, не так-ли?

Исторически, вся эта "анти-goto" кампания была направлена против кода из первого примера. Кто будет спорить, что код с GOTO запутаннее? Никто. Такой код получался десять тысяч лет назад из-за неразвитости и некоторых особенностей ранних языков программирования.

Сейчас, конечно, такой код не станет писать даже нулевой студент-заочник. Так что никакой проблемы с GOTO, с которой нужно бороться, сегодня нет.

(кстати, вот ещё такой финт ушами: переход на метку внутрь цикла из кода вне цикла - тоже отвратительная штука).

Итак, когда метками злоупотребляют и используют их не по назначению, это - плохо. Именно так надо понимать "goto/метки - зло", а не то, что они зло сами по себе (звучит знакомо? ага, указатели - ровно так же).

Два примера сценариев, где использование меток предпочтительнее других подходов:
1. Прерывание двухкратно вложенного цикла (уже привели пример).
2. Обработка ошибок:
Код:
K := DoSomething;
if K = 0 goto Error;
K := DoSomethingElse;
if K = 0 goto Error;
K := Funcenstein;
if K = 0 goto Error;
Result := True;
Exit;

Error:
WriteLn('Ошибка');
Result := False;
end;
По второму пункту - конечно, в современных языках есть SEH с его конструкцией try/finally, которая отлично обрабатывает в т.ч. и Exit, но в более ранних языках (досовский Паскаль, например), ничего такого нет, так что метки тогда были существенно полезнее.

Итого: в реальных программах метки/goto может встретиться несколько раз.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 11.01.2012, 22:48   #14
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

P.S. Сколько ни работал в Delphi, единственные случаи в моей практике, когда мне нужно было использовать GOTO/метки - выход из вложенных циклов. Случается это крайне редко.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 11.01.2012, 22:54   #15
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

В подобных ситуациях метки тоже по делу
Код:
Query.First;
while not Query.Eof do begin
  if ... then goto QueryNext;
  ...
  if ... then goto QueryNext;
  ...
  if ... then goto QueryNext;
  ...
  QueryNext: Query.Next;
end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 12.01.2012, 00:06   #16
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,544
По умолчанию

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
2. Обработка ошибок:
Код:
K := DoSomething;
if K = 0 goto Error;
K := DoSomethingElse;
if K = 0 goto Error;
K := Funcenstein;
if K = 0 goto Error;
Result := True;
Exit;

Error:
WriteLn('Ошибка');
Result := False;
end;
Не понравился код, читабельность снижается, т.к. надо еще найти, где этот Error находится.
Уж лучше что-то такое:
Код:
if (DoSomething = 0) or (DoSomethingElse = 0) or (Funcenstein = 0) then
begin
  WriteLn('Ошибка');
  Result := False;
else Result := True;
Exit тоже без сильной надобности использовать не стоит.

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
P.S. Сколько ни работал в Delphi, единственные случаи в моей практике, когда мне нужно было использовать GOTO/метки - выход из вложенных циклов. Случается это крайне редко.
Конечно, все зависит от конструкций языков. Я вот даже с вложенными циклами обхожусь break, ни разу в голову не приходило goto применять.
А вот в одном из языков есть такая удобная конструкция. Что бы не вдаваться в подробности, приведу кусок кода, думаю, все понятно:
Код:
scopeName "main";
while {true} do
{
  scopeName "loop1";
  while {true} do
  {
    scopeName "loop2";
    if (condition1) then {breakTo "main"}; // Breaks all scopes and return to "main"
    if (condition2) then {breakOut "loop2"}; // Breaks scope named "loop2"
    sleep 1;
  };
  sleep 1;
};
Цитата:
Сообщение от Аватар Посмотреть сообщение
В подобных ситуациях метки тоже по делу
Код:
Query.First;
while not Query.Eof do begin
  if ... then goto QueryNext;
  ...
  if ... then goto QueryNext;
  ...
  if ... then goto QueryNext;
  ...
  QueryNext: Query.Next;
end;
Опять же, что мешает записать так:
Код:
Query.First;
while not Query.Eof do begin
  repeat
    if ... then break;
    ...
    if ... then break;
    ...
    if ... then break;
    ...
  until false;
  Query.Next;
end;
Или вынести обработку в отдельную функцию, что даже лучше:
Код:
procedure QueryXXX (Query: TQuery);
begin
  if ... then Exit;
  ...
  if ... then Exit;
  ...
  if ... then Exit;
  ...
end; {proc QueryXXX}

...

Query.First;
while not Query.Eof do begin
  QueryXXX;
  Query.Next;
end;
Все зависит от требуемых действий.

Последний раз редактировалось Arigato; 12.01.2012 в 00:10.
Arigato вне форума Ответить с цитированием
Старый 12.01.2012, 00:15   #17
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
Не понравился код, читабельность снижается
Это субъективный фактор. Тебе читабельнее продублировать код, мне - вынести в одно место.

Цитата:
Уж лучше что-то такое
Несложно сообразить, что между вызовами функций может стоять код. Если не понятно, то код примера - аналог try/finally.

Цитата:
Я вот даже с вложенными циклами обхожусь break, ни разу в голову не приходило goto применять.
Аналогично: кому-то удобнее использовать флаги, мне - использовать GOTO.

Цитата:
Опять же, что мешает записать так
Ну, началось....

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

Цитата:
А вот в одном из языков есть такая удобная конструкция. Что бы не вдаваться в подробности, приведу куски кода, думаю, все понятно
Как видно из примера, это замаскированный GOTO.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 12.01.2012, 00:17   #18
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Интересен вопрос, зачем в паскале/delphi реализованы местки(Label)?
Нет не TLabel.
По которым можно прыгать используя goto.

Если ихопасно использовать, почему они поддерживаются компилятором, и где их БЕЗОПАСНО использовать?



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

Если их опасно использовать, почему все едят вилками, когда можно руками загребать еду и где их БЕЗОПАСНО использовать?

Не бойся ножа, бойся вилки: один удар - четыре дырки!

Rififi вне форума Ответить с цитированием
Старый 12.01.2012, 00:39   #19
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

ещё пример где метки очень нужны

Код:

if (not func1()) then
begin
  obj1.free;  
  obj2.free;  
  CloseWindow();
  ReleaseDC();
..... 
  (ещё тонна строк для освобождения какие-то там объектов) 
end

//здесь обработка результатов выполения func1 для передачи в func2

if (not func2(<данные от func1>)) then
begin
  obj1.free;  
  obj2.free;  
  CloseWindow();
  ReleaseDC();
..... 
  (ещё тонна строк для освобождения какие-то там объектов) 
end

//здесь обработка результатов выполения func2 для передачи в func3

if (not func3(<данные от func2>)) then
begin
  obj1.free;  
  obj2.free;  
  CloseWindow();
  ReleaseDC();
..... 
  (ещё тонна строк для освобождения какие-то там объектов) 
end

............

//здесь обработка результатов выполения func_N-1 для передачи в funcN

if (not funcN(<данные от func_N-1>)) then
begin
  obj1.free;  
  obj2.free;  
  CloseWindow();
  ReleaseDC();
..... 
  (ещё тонна строк для освобождения какие-то там объектов) 
end
и представляем насколько будет загромождён код этими пстоянными повторами удаления объектов

а с goto как всё просто, чётко и понятно, и без загромождения кода
Код:
if (not func1()) then goto ERROR;

//здесь обработка результатов выполения func1 для передачи в func2

if (not func2(<данные от func1>)) then goto ERROR;

//здесь обработка результатов выполения func2 для передачи в func3

if (not func3(<данные от func2>)) then goto ERROR;

............

//здесь обработка результатов выполения func_N-1 для передачи в funcN

if (not funcN(<данные от func_N-1>)) then goto ERROR;

..............

ERROR:
  obj1.free;  
  obj2.free;  
  CloseWindow();
  ReleaseDC();
..... 
  (ещё тонна строк для освобождения какие-то там объектов) 
 exit;
rpy3uH вне форума Ответить с цитированием
Старый 12.01.2012, 00:42   #20
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

rpy3uH, я бы лучше спроектировал код на работу с исключениями. и тогда привет try finally.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
зачем учить Pascal krot_zdes Свободное общение 52 31.05.2011 16:48
Зачем эта перменная (Delphi) reasons Помощь студентам 9 15.07.2010 22:22
Метки в Tbarseries (Delphi 7) Николай ПН Помощь студентам 0 31.03.2010 18:40
Что такое коды ASCII и зачем они?? Ларик Помощь студентам 2 27.01.2008 19:41
обновление в блоге - Ресурсы. Зачем они нужны. Pblog Обсуждение статей 0 27.05.2007 03:17