На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (32) « Первая ... 7 8 [9] 10 11 ...  31 32  ( Перейти к последнему сообщению )  
> goto vs break & continue , Кроха-сын пришел к отцу и спросила кроха: "goto - это хорошо?"
    Цитата JoeUser @
    Как-то, так:

    ...

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

    Это в твоих переходах без поллитры не разберёшься. =) Qraizer правильно сказал про КА.

    ExpandedWrap disabled
      type StateFn func() StateFn
       
      func Start() StateFn {
          if !flagPhase {
              return Exec
          }
          if flagNeedSend {
              SendRequest()
              return nil
          }
          if flagWait {
              return nil
          }
          if flagNeedExec {
              return Exec
          }
          if flagNecessity {
              CreateRequest()
              CreateWaitingFlag()
              return nil
          }
          if flagWaitReply {
              AcceptReply()
              if !accepted {
                  return nil
              }
              if reply {
                  return SO
              }
              return ExecFlag
          }
          if !recieveInfExists || recieveInfOverdue {
              CreateNecessityFlag()
              return Exec
          }
          if recieveInfOverdueFinish {
              return SO
          }
          Accept()
          if updates {
              return ExecFlag
          }
          return nil
      }
       
      func SO() StateFn {
          SendSORequest()
          CreateFlag()
          return nil
      }
       
      func ExecFlag() StateFn {
          // Create exec flag
          return Exec
      }
       
      func Exec() StateFn {
          if !execPhase {
              return nil
          }
          if flagBuilding {
              CreateRequest()
              return Start
          }
          if flagExec {
              Execute()
          }
          return nil
      }
       
      func main() {
          for f := Start(); f != nil; f = f() {
          }
      }
      С философской точки зрения, метки нужны там, где отсутствует структурное прогарммирование, например, на ассемблере, если код не выносится в функции, а пишется одной портянкой, то вызов функции заменяется goto, который вырождается в short jump или long jump. Это экономит и стек, так как никакие регистры не бэкапятся (выталкиваются) в стек и заново не перезагружаются данными. Причем, такое применение может быть как оптимизацией по скорости, так и по объему кода.

      И совершенно верно замечено, что рефакторить такой код геморно.

      Так что, опять же, с философской точки зрения, могу предположить, что в Си goto появилась как следствие "понижения" уровня языка до ассемблерного уровня, когда можно кодить "байт в байт", используя язык высокого уровня. Чем, например, был весьма хорош Turbo C 2.0 (и компилил тоже пушечно). И все эти техники неиспользования промежуточных переменных типа:

      ExpandedWrap disabled
        {
          i = f(x);
          return i;
        }


      лучше переписать как:

      ExpandedWrap disabled
        {
          return f(x);
        }


      и еще масса всяческих олдскульных штучек...

      Так как в первом случае значение функции, которое во времена i8086 обычно вычислялось только в AX(AH,AL), сначала пересылается куда-то в память, а потом возвращается обратно в AX (где по факту уже присутствует), и только потом вызывается RET...

      А сейчас и регистры стали внутри проца равноправнее, и винты толще, так что оптимизация by size тоже уже на грани удаления из компилятора напрочь...

      Сейчас никто (то есть, я в частности) asm не рефакторит, поэтому и смысла в goto в высокоуровневых языках уже нет. Но его отсутствие нарушит стандарт языка. А несовместимость со стандартом гораздо страшнее. :)

      Поэтому goto по-прежнему будет присутствовать, и его по-прежнему мало кто будет использовать, и это будет тоже очень правильно. И оптимизация by size тоже будет живее всех живых.
        Цитата p1qb0d @
        Так что, опять же, с философской точки зрения, могу предположить, что в Си goto появилась как следствие "понижения" уровня языка до ассемблерного уровня, когда можно кодить "байт в байт", используя язык высокого уровня.
        А я (см. первое сообщение темы) бы сказал, что вот бывает, что надо смотаться из двойного или тройного цикла, и тогда приходится городить лишний огород из переменных и т.п., либо просто сделать goto на выход и всё. Так что зависимость от ассемблера сомнительна. :scratch:
          Цитата Славян @
          А я (см. первое сообщение темы) бы сказал, что вот бывает, что надо смотаться из двойного или тройного цикла, и тогда приходится городить лишний огород из переменных и т.п., либо просто сделать goto на выход и всё. Так что зависимость от ассемблера сомнительна. :scratch:

          Это называется костыль и лень. Когда лень писать хороший качественный код, иногда люди начинаются писать говнокод. Вот как раз это тот описываемый тобой случай - говнокода. Что мешает тебе не городить 3 вложеных цикла? А обойтись дополнительной функцией, которая сделает твой код более читабельным, понятным и сопровождаемым?

          Добавлено
          Кстати а еще можно все писать в одной функции main, а нахрена нам другие функции? есть же волшебный goto, а блоки можно отделять коментариями, например както так:
          ExpandedWrap disabled
            /*******************************************************************************/
            ...
            /*******************************************************************************/
            ...
            /*******************************************************************************/
            Цитата KILLER @
            Что мешает тебе не городить 3 вложеных цикла? А обойтись дополнительной функцией, которая сделает твой код более читабельным, понятным и сопровождаемым?

            Это религия какая-то. Запросто может быть так, что три цикла гораздо читабельней, чем огород с вызовом функций.
              Цитата OpenGL @
              Это религия какая-то. Запросто может быть так, что три цикла гораздо читабельней, чем огород с вызовом функций.
              :yes:
              Цитата KILLER @
              Что мешает тебе не городить 3 вложеных цикла?
              Циклы бывают большие и сложные. Работают со многими данными. Пересылать весь их огород в функцию - и есть костыль, непонятно для чего. ;)
                Цитата Славян @
                ... вот бывает, что надо смотаться из двойного или тройного цикла, и тогда приходится городить лишний огород из переменных и т.п., ...
                Ладно выйти, а если войти?
                  Цитата Qraizer @
                  Ладно выйти, а если войти?
                  Мне ни разу такого не попадалось. Но так, сходу, и проблем со входом при наличии goto не вижу. А без него - точно такой же гемор с излишними плясками с переменными да условиями. :yes-sad:
                    Цитата OpenGL @

                    Это религия какая-то. Запросто может быть так, что три цикла гораздо читабельней, чем огород с вызовом функций.

                    Это не религия, 2 вложеных цикла - еще терпимо и нормально, а три и более - запутывают читающего код, а если там еще и goto, то и вовсе сбивает с толку. Если тебе так нужно запилить три цикла вложеных с возможностью выхода из третьего, оформи их в отдельную функцию/метод и ливай по return из них. Какие проблемы? Я видел функции по 5 тысяч строк кода - это читать не возможно в принципе, там и по три вложеных цикла было и по четыре. Как по мне, лучше сделать несколько мелких функций, чтобы было понятно и прозрачно, чем шаманить трехэтажные циклы.

                    Добавлено
                    Цитата Славян @
                    Циклы бывают большие и сложные. Работают со многими данными. Пересылать весь их огород в функцию - и есть костыль, непонятно для чего. ;)

                    Приведи пример такого костыля плз, я хочу посмотреть.

                    Добавлено
                    Цитата Qraizer @
                    Ладно выйти, а если войти?

                    Зачем?

                    Добавлено
                    Вообще писать можно как угодно и что угодно. Ну вот возьмет чел, напишет свою прогу в 100 000 строк тупо в функции Main, и она будет работать. Что он неверно сделал? Да все он верно сделал. Какое вам дело до того как он пишет? Религия чтоль не позволяет 100 000 строк в функции main запилить? Вот так вот и выглядят ваши аргументы со стороны.
                    А на деле, эта религия мне помогает избежать кучи ошибок, и когда я открываю свой код через год - то я сходу понимаю что там написано. В отличии, если бы там были трехэтажные циклы и метки - такой код открываешь через месяц и начинаешь репу чесать и заного изучать что же я там имел ввиду - делая такие нетривиальные телодвижения.

                    Добавлено
                    Плюс ко всему, есть мнение, что чем больше у тебя будет осознанных слов в проге - тем легче она будет восприниматься и читаться. В случае с трехэтажными циклами - их меньше, и можно легко запутаться, никто не будет называть счетчик больше 5-6 букв, особенно если он часто используется в теле цикла. С функциями эта проблема решаема, т.к. мало кто называет функции в 1-2 буквы. И программа становится более читабельной.
                    Сообщение отредактировано: KILLER -
                      Цитата KILLER @
                      Приведи пример такого костыля плз, я хочу посмотреть.
                      Пример с тремя сложными циклами со многими переменными, переписанный на "вызов функции с табуном аргументов"=костыль?.. :blink:
                        Цитата Славян @
                        Пример с тремя сложными циклами со многими переменными, переписанный на "вызов функции с табуном аргументов"=костыль?.. :blink:

                        Ну по твоему видимо да:
                        Цитата Славян @
                        Пересылать весь их огород в функцию - и есть костыль

                        Ок, приведи пример некостыля
                        Цитата Славян @
                        с тремя сложными циклами со многими переменными

                        Я просто хочу посмотреть, если я туда вставлю вызов функции - действительно хуже станет или нет.
                          Цитата KILLER @
                          Ок, приведи пример некостыля...
                          Я просто хочу посмотреть, если я туда вставлю вызов функции - действительно хуже станет или нет.
                          Допустим так:
                          ExpandedWrap disabled
                            int
                            GetBestChessPos( void )
                            {
                               int count1[20];
                               float terVer[8][8], pokaz;
                               char superVertical[8];
                               ...
                               // заполняем все массивы для работы
                               // ...
                             
                               // ниже = расчёт
                               for( int row=0; row<8; row++)
                                  for( int col=colA; col<colH; col++)
                                  {
                                     pokaz += ...;
                                     if( ... ) terVer[2][5] *= ...;
                                     // испытываем воздействие
                                     if( count1[15] + (int)pow(terVer[3][4] + terVer[2][5], pokaz) > count1[2] ) // опасное положение!
                                       if( superVertical[2]<3 ) // мат нам грядёт
                                         goto LBL_matPrideHanaBude;
                                  }
                                ...
                              LBL_matPrideHanaBude:
                               // попытка рискнуть:
                               ...
                            }
                            Цитата KILLER @
                            Если тебе так нужно запилить три цикла вложеных с возможностью выхода из третьего, оформи их в отдельную функцию/метод и ливай по return из них.

                            Это если из трёх сразу. А если из двух? Вытаскивать эти два цикла в функцию не всегда целесообразно.
                              Цитата OpenGL @
                              Это если из трёх сразу. А если из двух? Вытаскивать эти два цикла в функцию не всегда целесообразно.

                              Заведи флаг выхода. В чем проблема?

                              Цитата Славян @
                              Допустим так:

                              Что тебе мешает эти два цикла обернуть в отдельную функцию?
                                Цитата KILLER @
                                Что тебе мешает эти два цикла обернуть в отдельную функцию?
                                Мешает то, что эти два цикла и так по сути оформлены в функцию. Плюс вагон переменных, кои засылать в функцию равносильно заново написать примерно такую же. :unsure:
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (32) « Первая ... 7 8 [9] 10 11 ...  31 32


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0665 ]   [ 15 queries used ]   [ Generated: 7.05.24, 05:37 GMT ]