(решено) GoTo или repeat until?

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

Только будьте осторожны, АОП и AI - это не миф, это реальность.
Задумайтесь, как будут использовать AI, бандиты?
Можно миллиард раз говорить "о гуманности" и верить в "честность и порядочность людей".
Но посмотрите, что бандиты делают с солдатами? Задумайтесь, что будет когда они смогут штамповать солдат "на принтере"...
Под предлогом "бабы ещё нарожают", они никого не щадят. Задумайтесь, что для них даст AI? И у рабовладельцев(бандитов) полно денег.

К счастью, наложено вето, на понятие "сознание" и этот ларчик не так-то просто открыть, т.к. нужно много знать и уметь.
Я долго размышлял на эту тему и пришёл к выводу, что вначале нужно воспитать общество, и только потом можно давать ему AI.
То что, сейчас появилась, отечественная программа способная пройти пресловутый тест Тьюринга - это сложно но это, к счастью не AI.

Написать просто язык, это одно... а вот написать целевой язык... это другое. Какова Ваша цель? Для чего Вам язык АОП?

.
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

vitaly_l писал(а):Какова Ваша цель? Для чего Вам язык АОП?


Чтобы написать АО ось... конечно, я понимаю, что это недостижимая для меня задача... но мечтать то не вредно)))
Mikhail
энтузиаст
Сообщения: 565
Зарегистрирован: 24.10.2013 16:06:47

Сообщение Mikhail »

vitaly_l писал(а):1) А как без break остановить цикл, если например перебор по первой букве в слове и она найдена?

применить цикл с предусловием.

vitaly_l писал(а):2) А как без continue остановить итерацию, если например первая буква ненужна, а остальные востребованы?

оператор ветвления

vitaly_l писал(а):3) А как без exit, если всё что мне нужно программа уже нашла, а там ещё 555 555 итераций осталось... мне что ждать пока она всё пройдёт?

Зачем? Нужно грамотно написать условие окончания цикла.

На самом деле есть применение и для бреаков и для экситов и, даже, оооооооочень редко для континиумов и, прости господи, даже для гото, но в описанных Вами случаях они не нужны. :)
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

Лекс Айрин писал(а):Чтобы написать АО ось... конечно, я понимаю, что это недостижимая для меня задача...

Думаю Вы просто прибедняетесь. Это долго, это сложно. Важно понять цель АОП. Если для игр - это одно, для биржи это другое, для магазинов третье. Короче: цель конечная важна. Описание: АОП - есть в википедии, там кстати указаны некоторые принципы. А для всего сразу... или AI... - это самое интересное, но для этого мало знать только программирование, логику и математику и даже психологии с философией будет мало. Там, к счастью(или наоборот), очень важны другие знания, без них бессмысленно даже пытаться.

Mikhail писал(а):На самом деле есть применение и для бреаков и для экситов и, даже, оооооооочень редко для континиумов и, прости господи, даже для гото, но в описанных Вами случаях они не нужны.

Верю, этого никто и не оспаривает. Я просто выяснял: почему GoTo "зло" и выяснилось что, GoTo - самое страшное зло.

Mikhail писал(а):Зачем? Нужно грамотно написать условие окончания цикла.

А поподробнее про условие "экстренного" окончания цикла без exit? (это можно расcрассматривать как продолжение темы о GoTo, т.к. exit - выяснилось что это его разновидность) Хотя безусловно, под каждую задачу своё решение.
pupsik
энтузиаст
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13
Контактная информация:

Сообщение pupsik »

vitaly_l асм в руки. куда уж ниже (хотя есть куда)...

п.с.
ух ты: в среде программ, есть еще место стихам :wink:
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

pupsik писал(а):асм в руки. куда уж ниже (хотя есть куда)...

Я его знаю (курс прошёл), но я его никогда не пользую :(((. Мне для моих задач, Паскаль - самое оно! Лучше даже: Си++ и С#.

Mikhail писал(а):vitaly_l писал(а):
1) А как без break остановить цикл, если например перебор по первой букве в слове и она найдена?

применить цикл с предусловием.

vitaly_l писал(а):
2) А как без continue остановить итерацию, если например первая буква ненужна, а остальные востребованы?

оператор ветвления

vitaly_l писал(а):
3) А как без exit, если всё что мне нужно программа уже нашла, а там ещё 555 555 итераций осталось... мне что ждать пока она всё пройдёт?

Зачем? Нужно грамотно написать условие окончания цикла.


Ну вот например странная задача, за которую меня будут ругать, но немного знаний я нарою (наверное):

Код: Выделить всё


  for x := 0 to length(arraySomeText)-1 do
    begin
      i := 0;
      someString := arraySomeText[x];
      while i < length(someString)-1 do
        begin
          if someString[i] = 'a' then exit else
          if someString[i] = 'b' then begin inc(iCountContinue); continue; end else
          if someString[i] = 'c' then begin inc(iCountBreak); break; end else
          if someString[i] = 'g' then GoTo MyLovelyGoTo else
          begin
           //какой-то код = неважно
          end;
          inc(i);
        end;
    end; 

   ShowMessage(IntToStr(iCountContinue) + '  ' + IntToStr(iCountBreak));
   
   MyLovelyGoTo:



Как тут по другому exit ?
Как тут по другому continue ?
Как тут по другому break ?


.
pupsik
энтузиаст
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13
Контактная информация:

Сообщение pupsik »

Посмотрите на код со стороны писателя. Бываю разные произведения.
В вашем случае - не красивое и плавное творение, а код с буграми и ямами, и резкими "вылетами".
Если вынести часть кода с ифами в отдельную процедуру и заменить ифы на case можно и подправить ситуацию.
К тому же станут бесполезными брейкеры всякие. Но, необходимо добавить, возможно, маленькую "плюшку".

п.с.
Лично мое мнение...
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

vitaly_l писал(а):Как тут по другому continue ?

без компиляции вижу, что наличие в строке символа 'b' приведёт к зацикливанию.
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

скалогрыз писал(а):без компиляции вижу, что наличие в строке символа 'b' приведёт к зацикливанию.

Ох уж мне эти зоркие всё видящие профессионалы...
pupsik писал(а):Но, необходимо добавить, возможно, маленькую "плюшку".

Какую плюшку?

Это пример, просто Mikhail - сказал что, он может заменить в цикле: exit, continue и break. А я поинтересовался. Как?
Безусловно можно заменить на case, будет вот так:

Код: Выделить всё

 for x := 0 to length(arraySomeText)-1 do
    begin
      i := 0;
      someString := arraySomeText[x];
      while i < length(someString)-1 do
        begin
          case someString[i] of
              'a' : exit;
              'b' : begin inc(iCountContinue);  inc(i); continue; end;
              'c' : begin inc(iCountBreak); break; end;
              'g' : GoTo MyLovelyGoTo;
              else someFunction(i);
          end;
          inc(i);
        end;
    end; 

   ShowMessage(IntToStr(iCountContinue) + '  ' + IntToStr(iCountBreak));
   
   MyLovelyGoTo:


Поэтому вопросы для (Mikhail) или кто ответит остаются:

Как тут по другому exit ? (Mikhail - говорит можно по другому)
Как тут по другому continue ? (Mikhail - говорит можно по другому)
Как тут по другому break ? (Mikhail - говорит можно по другому)
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

vitaly_l писал(а):Ох уж мне эти зоркие всё видящие профессионалы...

так в этом и смысл, когда говорят, что continue, break, exit и goto - опасные и их следует избегать.
Ошибку совершить достаточно просто, а вот найти её получится только во время испольнения, а не во время написания кода.

И тут же появляется некое отличие continue (break, exit) от goto.
Т.к. continue, break ограничены действием только одного цикла. Т.е. и проверка кода вполне реальна (если цикл не сильно длинный).
С exit тоже всё понятно, особенно при наличии try .. finally секции, которая поможет избавится от потенциальных утечек.
Состояние исполнителя можно отследить.

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

Например:

Код: Выделить всё

var
  i : integer;
begin
  writeln(i);
end.

Компилятор ругается - "i - не инициализирована".

Естественно, это решается инициализацией переменной:

Код: Выделить всё

var
  i : integer;
begin
  i:=2;
  writeln(i);
end.

- компилятор доволен!

Но теперь добавим готу:

Код: Выделить всё

var
  i : integer;
label j;
begin
  goto j; 
  i:=2;
  j:
  writeln(i);
end.

Казалось бы, очевидный пропуск инициализации, но компилятор молчит, видя i:=2;
Нечто подобное может произайти при goto MyLovelyGoTo.
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

скалогрыз писал(а):Нечто подобное может произайти при goto MyLovelyGoTo.

Ага понял, и тогда, если будет сбой, то его будет гипер-сильно сложно найти, т.к. компилятор мне не поможет.

скалогрыз писал(а):так в этом и смысл, когда говорят, что continue, break, exit и goto - опасные и их следует избегать.

Ну и как их избежать? Вот и код:

Код: Выделить всё

 for x := 0 to length(arraySomeText)-1 do
    begin
      i := 0;
      someString := arraySomeText[x];
      while i < length(someString)-1 do
        begin
          case someString[i] of
              'a' : exit;
              'b' : begin inc(iCountContinue);  inc(i); continue; end;
              'c' : begin inc(iCountBreak); break; end;
              'g' : GoTo MyLovelyGoTo;
              else someFunction(i);
          end;
          inc(i);
        end;
    end; 

   ShowMessage(IntToStr(iCountContinue) + '  ' + IntToStr(iCountBreak));
   
   MyLovelyGoTo:
скалогрыз
долгожитель
Сообщения: 1804
Зарегистрирован: 03.09.2008 02:36:48

Сообщение скалогрыз »

vitaly_l писал(а):Поэтому вопросы для (Mikhail) или кто ответит остаются:

Как тут по другому exit ? (Mikhail - говорит можно по другому)
Как тут по другому continue ? (Mikhail - говорит можно по другому)
Как тут по другому break ? (Mikhail - говорит можно по другому)


делать академически

Код: Выделить всё

   arrayDone:=false;
   procDone:=false;
   while not arrayDone and (x<length(arraySomeText)) do
        begin
          i := 1;
          someString := arraySomeText[x];
          while not arrayDone and (i <= length(someString)) and not (someString[i] in ['g','c','a']) do
            begin
              case someString[i] of
                  'b' : inc(iCountContinue); 
                  else someFunction(i);
              end;
              inc(i);
            end; // of while
            if (i<=length(someString)) then begin
               if someString[i]='c' then  inc(iCountBreak)
               else begin
                 arrayDone:=true; // a or g is here;
                 procDone:=someString[i]='a';
               end;
            end;
           inc(x);
         end; 

       if not procDone then begin
         if not arrayDone then 
           ShowMessage(IntToStr(iCountContinue) + '  ' + IntToStr(iCountBreak));
         // MyLovelyGoTo: was here.
       end;


хотя , ещё более академически это вынос анализа someString в отдельную функцию!
Но у студентов начальных курсов, и тех у кого к программированию гены не расположены, функции на дух не переносят, и как раз начинают жаловатся, что мол непонятно нифига.

Добавлено спустя 9 минут 20 секунд:
Кстати, очень важно откоментировать слова миража:
Mirage писал(а):Поэтому не люблю не только GOTO, но и всякие BREAK, CONTINUE, EXIT в середине процедуры и т.п.

Ключевое слово здесь "в середине".

Почему программисты, вполне терпимо относятся к Exit-у в начале процедуры?!
Потому что в начале процедуры, принято проводить проверку входных параметров на правильность (sanity check)! И если входные параметры или состояние не удовлетворяют требованиям, можно смело выходить из процедуры (с ошибкой).

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

Тоже самое относится ко многим случаяем применения continue и break в циклах.
Mirage
энтузиаст
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

В данном случае, заменять GoTo и т.д. не нужно. Нужно заменить весь код. А возможно, и его автора, если он не пообещает больше так не делать.
Аватара пользователя
vitaly_l
долгожитель
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41
Контактная информация:

Сообщение vitaly_l »

Mirage писал(а):В данном случае, заменять GoTo и т.д. не нужно. Нужно заменить весь код.

Пример пожалуйста, а без примера мне непонятно. :oops: :cry:

Добавлено спустя 33 минуты 33 секунд:
скалогрыз писал(а):Ключевое слово здесь "в середине".

Хорошо, это я теперь ясно понимаю СПАСИБО! (надеюсь запомню).

скалогрыз писал(а):Но у студентов начальных курсов, и тех у кого к программированию гены не расположены, функции на дух не переносят

Я прилежный студент. Вынос в отдельную функцию, разбора слова - проблем не вызывает. Вопрос только в быстродействии, т.к. оно тогда замедлиться. Правильно? Но зачем тогда выносить в отдельную функцию, если будет медленнее?

Если я правильно понял, суть "удаления" дословно: не только GOTO, но и всякие BREAK, CONTINUE, EXIT в середине процедуры - заключается в замене их на if AND OR IN в условии циклов. И этот Ваш академический вариант, не будет разве грузить процессор на порядок больше нежели просто: BREAK, CONTINUE, EXIT ?
Последний раз редактировалось vitaly_l 03.09.2015 00:17:54, всего редактировалось 1 раз.
Аватара пользователя
Pavia
постоялец
Сообщения: 290
Зарегистрирован: 07.01.2011 11:46:51

Сообщение Pavia »

1) Избавляемся от Goto
За одно выносим код в функцию.

Код: Выделить всё

for x := 0 to length(arraySomeText)-1 do
    begin
      i := 0;
      someString := arraySomeText[x];
      while i < length(someString)-1 do
        begin
          case someString[i] of
              'a' : exit;
              'b' : begin inc(iCountContinue);  inc(i); continue; end;
              'c' : begin inc(iCountBreak); break; end;
              'g' : begin MyLovelyGoTo(); exit end;
              else someFunction(i);
          end;
          inc(i);
        end;
    end; 

   ShowMessage(IntToStr(iCountContinue) + '  ' + IntToStr(iCountBreak));
   
   MyLovelyGoTo()


2) Затем выкидываем ShowMessage(IntToStr(iCountContinue) + ' ' + IntToStr(iCountBreak));
Так как он нарушает принципы MCV.

Код: Выделить всё

procedure ShowStatistiks(Text:TText;);
bein
With TText do
 ShowMessage(IntToStr(iCountContinue) + '  ' + IntToStr(iCountBreak)); 
end;

procedure Control();
begin
 if Text.Processing=Good then
     begin
     ShowStatistiks(Text);
     MyLoveGoto();
     end else
     begin
     //Некоторый код для обработки плохого кода.
     end;
end;


Код: Выделить всё

function Text.Procesing;
var ...;
begin
Result:=Good;
for x := 0 to length(arraySomeText)-1 do
    begin
      i := 0;
      someString := arraySomeText[x];
      while i < length(someString)-1 do
        begin
          case someString[i] of
              'a' : begin Result:=Bad; exit; end;
              'b' : begin inc(iCountContinue);  inc(i); continue; end;
              'c' : begin inc(iCountBreak); break; end;
              'g' : break;
              else someFunction(i);
          end;
          inc(i);
        end;
    end; 
end;


3) Далее введём флаг. Избавимся от Brake;
Stop
И функцию проверки IsStop

Код: Выделить всё

function IsStopr:Boolean;
begin
Result:=Stop<>0;
end;


Код: Выделить всё

function Text.Procesing;
var Stop:(snNone,snError, snA,snB,snC,snD);
  Function IsStop...
var ...;
begin
x := 0;
while (Not IsStop) and x<length(arraySomeText) do
    begin
      i := 0;
      someString := arraySomeText[x];
      while (Not IsStop) and (i < length(someString)-1) do
        begin
          case someString[i] of
              'a' : Stop:=snError;
              'b' : begin inc(iCountContinue);  inc(i); continue; end;
              'c' : begin inc(iCountBreak); Stop:=snC; end;
              'g' : Stop:=snD;
              else someFunction(i);
          end;
          inc(i);
        end;
    end;
if Stop=snError then Result:=Bad else Result:=Good;
end;


4) Continue тут видно что можно легко убрать.
Но если по существу то тут лучше ввести две функции
GetNextPos(PtrPos, ) - для поиска следующей особой позиции.
EarchSomeFunction цикл по основному коду.

5) и так далее тут ещё много чего можно улучшить. Просто код становится большим.
Но так как задача абстрактная плодить осмысленные имена трудновато.
Ответить