Форум программистов, компьютерный форум, киберфорум
CoderHuligan
Войти
Регистрация
Восстановить пароль
Карта форума Блоги Сообщество Поиск Заказать работу  
Рейтинг: 2.14. Голосов: 7.

goto и switch

Запись от CoderHuligan размещена 24.06.2019 в 10:22
Обновил(-а) CoderHuligan 24.06.2019 в 13:08

Вижу, что многие не понимают сути "народного" подхода, поступают вопросы, на которые следует ответить.
Цитата:
Сообщение от voral
Более того применение флагов не имеет отношение к выбору с GOTO или без оного. Это вещи разного порядка. (Мне все больше кажется, что вы не совсем верно толкуете "структурное" программирование). Флаги это не состояние программы в целом, или на какой то момент времени... Это лишь характеристика конкретной сущности. Которая может меняться, а может не меняться.
Вы несколько ошибаетесь. Флаги не описывают свойства обьекта управления. Флаг это чисто логическая переменная, которая может содержать лишь два значения - false и true. В структурном программировании, так как goto запрещен, флаги используются для изменения потока управления. По сути это костыль, который неуклюжим образом заменяет прямой переход. Если с goto я могу перейти в единственное состояние, то с флагами я вынужден дробить это состояние на множество блоков кода и множество идентичных флагов, при помощи которых, эти блоки кода "включаются" и "выключаются". Прямо скажем: ужасный подход, что отмечали многие. Доцент кафедры программирования ИТМО Шалыто говорит, что это просто преступный подход, так программировать нельзя. Он предлагает свитч-технологию для избавления от этих флагов. Например взять прежний пример подсчёта слов на goto:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#define N 255
char s[N]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed";
int main(void)
{
 
    int nw = 0;
    
    char *p=s;
        --p;
    OUT:
        ++p;
        if(!*p)
            goto K;
        if(*p == ' ' || *p == ',' || *p == '\n')
            goto OUT;
        nw++; 
            goto IN;
    IN:
        if(!*p)
            goto K;
        if(*p == ' ' || *p == ',' || *p == '\n')
            goto OUT;
        ++p; 
            goto IN;
    K:
    printf ("%d \n",  nw);
    return 0;
}
и преобразуем его в соответствии с свитч-технологией:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#define N 255
#define IN 1
#define OUT 2
#define K 3
#define END 4
char s[N]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed";
int main(void)
{
 
    int nw = 0, state;
    
    char *p=s;
    state = OUT;
        --p;
    while(state!=END)
    {
        switch(state)
        {
            case OUT:
                ++p;
                if(!*p)
                    {state = K; break;}
                if(*p == ' ' || *p == ',' || *p == '\n')
                    {state = OUT; break;}
                nw++; 
                    {state = IN; break;}
            break;
            case IN:
                if(!*p)
                    {state = K; break;}
                if(*p == ' ' || *p == ',' || *p == '\n')
                    {state = OUT; break;}
                ++p; 
                   {state = IN; break;}
                    break;
            case K:
            printf ("%d \n",  nw);
            state = END; break;
 
        }
    }
    return 0;
}
Как видим логика осталась практически той же. Переходы обеспечиваются попаданием через цикл в соответствующие ветки case. Умный компилятор преобразует их в таблицу указателей на метки и на выходе получим те же самые goto. Эта технология гораздо лучше структурного подхода, так как позволяет избавится от флагов, и позволяет реализовать даже самый супер-пупер сложный алгоритм. Это будущее робототехники и ИИ.
В моём случае я действую по старинке, не пряча оператор goto. Мой код может обработать любой компилятор, даже самый "тупой".

Цитата:
Сообщение от voral
Сути не меняет, я тоже именно про условную конструкцию, она всегда имеет, по сути одну точку выхода, эта точка следует срезу после конструкции... "Внутри" возможны лишь искусственные выходы, а это уже дело рук программиста. И вот тут и проявляется правильность подхода. В общем случае программ не должна улетать куда либо (как раз в вашем случае она делает это всегда). И лишь четко в обоснованных случаях это обоснованно
Если эта конструкция имеет не одну точку выхода, то она уже не имеет права называться структурной. Это первое.
Во-вторых, моя программа никуда "не улетает". Она просто делает то, что предписано алгоритмом решения задачи. Если алгоритм предписывает куда-то перейти, например в начало, то код обеспечивает эту возможность. Вы же видите, даже такой простой код, уже настолько умён, что позволяет прерывать программу на любом шаге, входить в режим помощи на любом шаге и рестартовать программу. Даже если мы находимся на полпути расстановки кораблей на поле, можно сразу всё начать заново, сбросив все настройки. Из режима помощи можно вернутся в туже точку расстановки кораблей и продолжить с того же самого места. Напишите это в традиционном стиле.
Размещено в Без категории
Показов 5125 Комментарии 46
Всего комментариев 46
Комментарии
  1. Старый комментарий
    Аватар для CoderHuligan
    locm, это потому, что ваша функция ничего не возвращает. Допустим в си, если функция возвращает что-то, допустим int, всё в порядке:
    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    #include <stdio.h>
     
    int func(void)
    {
        int a=0;
        while(a<=3)
        {
            if(a==2)
                goto END;
            ++a;
        }
        END:
            return 0;
     
    }
     
    int main(void)
    { 
         return func();
    }
    Если же функция возвращает void, то придётся ставить завершающий оператор:
    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    #include <stdio.h>
     
    void func(void)
    {
        int a=0;
        while(a<=3)
        {
            if(a==2)
                goto END;
            ++a;
        }
        END:;
    }
     
    int main(void)
    { 
         func();
    }
    Ваш pure basic тоже на сях написан, поэтому ошибка всеобщая, но не критичная.
    Запись от CoderHuligan размещена 25.06.2019 в 12:39 CoderHuligan вне форума
  2. Старый комментарий
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Проверил ваш код и код voral.
    Не все так однозначно. тест получился не очень показателен. Т.к. показывает всегда разные результаты. Причем кардинально. В т.ч. и когда мой код быстрее вашего.. И уж точно у меня не был он ни разу на 30% медленнее. К тому же надо еще разобраться как это все в реальности происходит, потому что в цикле производится одно и то же действие. Такая ситуация в реальных проектах ОЧЕНЬ маловероятна.

    Но, одна очень важная деталь, о которой не однократно здесь замечали. Код гораздо сложнее в поддержке. Он может быть сколь угодно удобен кому то конкретно (да и то на маленьких проектах), но большинство говорит "Нет, это не удобно". Я бы еще понял, если бы речь шла о каком либо новом подходе. А это нет... программирование эволюционирует, и как раз где то там в истории и было это goto программирование.. .К чему бы это?

    В больших сложных проектах фактор понятности кода имеет очень большое значение. И с этой точки зрения я профита пока не вижу совсем. (Хотя были времена и GOTO было много в моем коде - т.е. сам по себе подход для меня совсем не новость).

    Ну а с быстродейстивем все это фигня. Современные компляторы с оптимизацией все сделают отлично, а доля проектов там где "нехватает" там вообще подход к другой, который тащить в большую часть проектов совсем не рационально
    Запись от voral размещена 25.06.2019 в 12:45 voral вне форума
  3. Старый комментарий
    Сорри. Смотрел первую версию теста. Вторая уже стабильнее работает. Профит скорости c GOTO 1.5 - 4.1%

    gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
    Запускал: gcc -Wall -o compare compare.c && ./compare

    Т.е. не существенно... (Опять же с учетом того, что этот тест мало показателен с точки реального большого проекта и, особенно, когда проект ведет всю жизнь не один программист сам с собой изо дня в день.
    Запись от voral размещена 25.06.2019 в 12:58 voral вне форума
    Обновил(-а) voral 25.06.2019 в 13:00
  4. Старый комментарий
    Аватар для XLAT
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    так как код с goto современные компиляторы не оптимизируют
    а седня для вас у меня хорошие новости:
    https://yadi.sk/i/DTp8c-Wtmi86Iw
    как видите GCC8.2 рулит!
    собсно, рулит на ура его оптимизатор.
    Для меня, как оказалось, это был не только развлекательный, но и полезный тест.
    Тот же тест + поддержка VS C++


    CoderHuligan, GCC 8.2 просто создан для вас! Под виндоз тож есть версия. Берите и пользуйте.

    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Вы смогли это сделать потому, что код примера очень прост.
    хех, это больше касается вас с вашими перекрестными переходами меж блоками,
    ах, да, блоки в игноре.

    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    В коде вы разделили оба состояния
    Да! на идею алгоритма я потратил минуту, согласитесь что это идея просто лежит
    на поверхности и сама кричит во весь рот.

    Цитата:
    Сообщение от voral Просмотреть комментарий
    Не все так однозначно. тест получился не очень показателен
    тут был еще какой то тест, на который все время ссылается Хулиган?
    Но я его не нашел.

    Цитата:
    Сообщение от voral Просмотреть комментарий
    потому что в цикле производится одно и то же действие
    ну, что вы, это не так!
    там в цикле то буквы идут, то небуквы ползут.
    и для каждого символа нужно понять буква это или небуква и уже решать,
    что с этим делать.

    Цитата:
    Сообщение от voral Просмотреть комментарий
    Но, одна очень важная деталь
    это можно не обсуждать: Хулиган дойдет до этого сам, когда завалит сибатл.
    Или кучу сибатлов.

    Цитата:
    Сообщение от voral Просмотреть комментарий
    Ну а с быстродействием все это фигня. Современные компиляторы с оптимизацией все сделают отлично
    это очевидные вещи, если про них сказать, то никто не обратит внимание.
    Запись от XLAT размещена 25.06.2019 в 17:18 XLAT на форуме
    Обновил(-а) XLAT 25.06.2019 в 17:27
  5. Старый комментарий
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    locm, это потому, что ваша функция ничего не возвращает.
    По вашему это приводит к тому что из стека не убирается лишний элемент? Не важно возвращает что-то функция или нет (для этого используется не стек, а регистр EAX), ошибка из-за некорректных данных в стеке и возникает из-за Goto. Из-за него не выполняется одна из POP инструкций.
    Цитата:
    Сообщение от CoderHuligan Просмотреть комментарий
    Ваш pure basic тоже на сях написан, поэтому ошибка всеобщая, но не критичная.
    Код генерируется для FASM, а это ассемблер, а не Си.
    Ошибка критичная и винда завершит приложение, ведь происходит возврат из функции (инструкция RET) на адрес 0, а не по адресу вызова.
    Еще раз повторю, ошибка не при компиляции, а при выполнении программы.
    Запись от locm размещена 25.06.2019 в 22:41 locm вне форума
  6. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от locm Просмотреть комментарий
    По вашему это приводит к тому что из стека не убирается лишний элемент? Не важно возвращает что-то функция или нет (для этого используется не стек, а регистр EAX), ошибка из-за некорректных данных в стеке и возникает из-за Goto. Из-за него не выполняется одна из POP инструкций.
    Я что-то никак не пойму.. Как можно винить лексему языка в особенностях её реализации в конкретном компиляторе? Вы сами-то себя слышите? Ещё раз повторяю, что на си всё в порядке, если соблюдать некоторые меры. Создатели компиляторов просто не обратили внимание на это, видимо жутко ненавидя данный оператор. Дык я жутко ненавижу их самих за это..
    Цитата:
    Сообщение от locm Просмотреть комментарий
    Ошибка критичная и винда завершит приложение, ведь происходит возврат из функции (инструкция RET) на адрес 0, а не по адресу вызова.
    Еще раз повторю, ошибка не при компиляции, а при выполнении программы.
    Выкиньте свой pure basic в топку и проверьте в работе free basic.
    Запись от CoderHuligan размещена 26.06.2019 в 12:00 CoderHuligan вне форума
  7. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от XLAT Просмотреть комментарий
    а седня для вас у меня хорошие новости:
    https://yadi.sk/i/DTp8c-Wtmi86Iw
    как видите GCC8.2 рулит!
    собсно, рулит на ура его оптимизатор.
    Приятно слышать. На gcc сам не проверял.

    Цитата:
    Сообщение от XLAT Просмотреть комментарий
    GCC 8.2 просто создан для вас! Под виндоз тож есть версия. Берите и пользуйте.
    Так он у меня установлен, пользуюсь часто.

    Цитата:
    Сообщение от XLAT Просмотреть комментарий
    хех, это больше касается вас с вашими перекрестными переходами меж блоками,
    ах, да, блоки в игноре.
    В игноре. Действовать последовательно, значит действовать последовательно. С прицелом на будущий язык, в котором всё это будет, и не будет блоков, разве что в определении функций.
    Потому что если потребуется прыгнуть прямо в структурный блок выглядеть это будет не ком-иль-фо. Даже если делаем выход из вложенных циклов по goto, то уже не красиво. А если всё на goto построено, то всё выглядит как надо.
    В современных структурных языка наблюдается семантическое расхождение с настоящим комьютерным языком - ассемблером. Поэтому когда программист вынужден программировать в силу разных причин на ассемблере, то просто не может реализовать даже простейший алгоритм. В моём варианте семантического расхождения не наблюдается.
    Ещё надо помнить про "бритву Оккама" - "Не следует привлекать новые сущности без крайней на то необходимости". Если хватает существующих.
    Цитата:
    Да! на идею алгоритма я потратил минуту, согласитесь что это идея просто лежит
    на поверхности и сама кричит во весь рот.
    Не для всех очевидно судя по коду даже хороших программистов. Ведь не додумались создатели языка си до наших с вами примеров, а реализовали медленный алгоритм на флагах. Выглядит действительно кратко и "прилично", а вот работает неэффективно.
    Запись от CoderHuligan размещена 26.06.2019 в 14:18 CoderHuligan вне форума
    Обновил(-а) CoderHuligan 26.06.2019 в 14:23
  8. Старый комментарий
    Аватар для liv
    Цитата:
    Сообщение от CoderHuligan
    Поэтому когда программист вынужден программировать в силу разных причин на ассемблере, то просто не может реализовать даже простейший алгоритм
    Очередная глупость! Говорите только о себе...
    Что за примитивизм? Зачем сводить кодирование на ЯВУ к Ассемблеру? Что за бред Вы вообще несете?
    Наверное, глупые люди придумали язык Си, да и С++, со всеми ихними конструкциями. Не знали, что придет CoderHuligan и скажет, как надо правильно программировать...

    Это мне напомнило то, как Вы с пеной у рта рассказывали нам, как надо делить на ноль, и что абсолютно все вычисления нужно вести исключительно целочисленные...
    Просто откровение сошедшего до нас гуру...
    Запись от liv размещена 26.06.2019 в 16:06 liv вне форума
    Обновил(-а) liv 26.06.2019 в 16:12
  9. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от liv Просмотреть комментарий
    Очередная глупость! Говорите только о себе...
    Что за примитивизм? Зачем сводить кодирование на ЯВУ к Ассемблеру? Что за бред Вы вообще несете?
    Это не бред. Это семантическая пропасть между ассемблером и ЯВУ, а значит и между способностью генерировать правильные алгоритмы.

    Цитата:
    Сообщение от liv Просмотреть комментарий
    Наверное, глупые люди придумали язык Си, да и С++, со всеми ихними конструкциями. Не знали, что придет CoderHuligan и скажет, как надо правильно программировать...
    Не глупые, прямо скажем, а люди введённые в заблуждение. Про язык си и другие структурные языки, я расскажу более подробно. Что там не так, и как надо..
    Запись от CoderHuligan размещена 26.06.2019 в 18:33 CoderHuligan вне форума
  10. Старый комментарий
    Аватар для liv
    CoderHuligan, так создайте свой язык! Сделайте там все, "как надо"! Какие проблемы?
    Заодно и реализуете там целочисленный синус Будет прорыв века!
    Запись от liv размещена 26.06.2019 в 18:41 liv вне форума
  11. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от liv Просмотреть комментарий
    CoderHuligan, так создайте свой язык! Сделайте там все, "как надо"! Какие проблемы?
    Заодно и реализуете там целочисленный синус Будет прорыв века!
    Мысли уже давно имеются и желание тоже.
    Это будет нечто среднее между компилируемым и интерпретируемым языком. Создаём некую базовую сущность, существо-программу очень малого размера, которая может быть установлена на любом компьютере. Эта программа как некий вирус(но вирусом не являясь - там всё законно) может порождать другие программы компилируя-интерпретируя программный код, который ей предоставляет программист. Это не компилятор, а модуль для любой программы. На пример текстовый редактор главным модулем будет иметь именно вот эту программу. То есть эта программа есть некий эмбрион, который может расти, умнеть, короче - развиваться. Развивать её можно на особом языке. Преимущество в том, что каждая программа будет легко расширяема самими пользователями оной. Как сказал один из основателей корпорации Autodesk Джон Уолкер - "каждая программа должна быть программируемой". Он кстати самостоятельно реализовал нечто подобное: программу Atlast. На гитхабе можно познакомится. Я примерно хочу сделать нечто подобное, только применительно к своему языку.
    Запись от CoderHuligan размещена 26.06.2019 в 19:09 CoderHuligan вне форума
  12. Старый комментарий
    Аватар для Usaga
    Цитата:
    Это будет нечто среднее между компилируемым и интерпретируемым языком.
    Допишите, сначала, свой морской бой.
    Запись от Usaga размещена 26.06.2019 в 19:23 Usaga вне форума
  13. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от Usaga Просмотреть комментарий
    Допишите, сначала, свой морской бой.
    Угу.
    Запись от CoderHuligan размещена 26.06.2019 в 19:53 CoderHuligan вне форума
  14. Старый комментарий
    Аватар для Croessmah
    А Вы книги Шалыто-то читали?
    У него, например, также рассматривается ООП подход к построению автоматов.
    Причем можно даже без контекста некоторые фразы дернуть:
    Цитата:
    В то же время, за использование автоматов при разработке некритичного ПО приходится платить слишком высокую цену.
    Цитата:
    объектно-ориентированный подход наиболее эффективен для реализации событийных систем
    Но в общем и целом я бы не приплетал сюда switch-технологию и Шалыто. Я вот посмотрел его книжки, и скажу Вам, у него нет такого бреда, как у Вас. Вы, видимо, неправильно понимаете то, что читаете.

    P.S. И да, ужас, у Шалыто используются if-else, классы, циклы и т.д., а не Ваш Доширак.
    Запись от Croessmah размещена 28.06.2019 в 18:01 Croessmah вне форума
    Обновил(-а) Croessmah 28.06.2019 в 18:03
  15. Старый комментарий
    Аватар для liv
    Ну так, Шалыто и многие-многие другие, оказывается, введены в заблуждение...
    Запись от liv размещена 28.06.2019 в 20:04 liv вне форума
  16. Старый комментарий
    Аватар для Croessmah
    Цитата:
    Сообщение от liv Просмотреть комментарий
    Ну так, Шалыто и многие-многие другие, оказывается, введены в заблуждение...
    Я не вчитывался особо. Наш Ктулху снова всем показывает истинный путь?
    Запись от Croessmah размещена 28.06.2019 в 21:30 Croessmah вне форума
  17. Старый комментарий
    Аватар для Avazart
    Ктулху все жует свой пейот ...
    Запись от Avazart размещена 28.06.2019 в 22:31 Avazart вне форума
  18. Старый комментарий
    Аватар для Hretgir
    Вообще, оператор GOTO несколько уникален в плане ветвления - программу можно вернуть через ретёрн, а можно и не возвращать, вот в чём фокус. Только конечно это уже не ООП, но ближе к нейросетям, точнее - к эвристике, но только частично. То-есть, если через массив процедур или меток функций можно продвигать какую-то самомодификацию, то подгонять результаты вычислений под значения - не совсем и не всегда удобно, а вот GOTO и его два сразу варианта в коде (с ретёрном и без) - это особый тип ветвления и самомодификации по результату вычислений.
    Хотя...ретёрн и бреак через проверку условия - то же самое, но не совсем - GOTO не локализует участки кода - они для него глобальны все. Доступность кода - точка входа в инкапсуляции. Вроде так. Когда нечто вызывает само себя не с головы, а с той точки какая указана. С точки зрения топологии, это как возможность вывернуть код... В механике такое можно делать с механизмами и это может давать свои плюсы. Например можно вывернуть двигатель Стирлинга почти на изнанку - и это имеет свои плюсы и минусы (с обычным движком в него "фарша" не напихать столько), вопрос лишь в том - что нам надо.
    Запись от Hretgir размещена 29.06.2019 в 01:02 Hretgir вне форума
    Обновил(-а) Hretgir 29.06.2019 в 01:25
  19. Старый комментарий
    Аватар для CoderHuligan
    Цитата:
    Сообщение от Croessmah Просмотреть комментарий
    А Вы книги Шалыто-то читали?
    Прочёл книгу "автоматное программирование". Также читал его статьи. Смотрел лекцию на ю-тьюб.


    Цитата:
    Сообщение от Croessmah Просмотреть комментарий
    У него, например, также рассматривается ООП подход к построению автоматов.
    Как один из многих.

    Цитата:
    Сообщение от Croessmah Просмотреть комментарий
    Но в общем и целом я бы не приплетал сюда switch-технологию и Шалыто. Я вот посмотрел его книжки, и скажу Вам, у него нет такого бреда, как у Вас. Вы, видимо, неправильно понимаете то, что читаете.
    Вы бы посмотрели его лекцию на ю-тьюб для общего развития: https://www.youtube.com/watch?v=tUo9ssPVa4c

    Просто я иду ещё дальше него, к упрощению его подхода.
    Запись от CoderHuligan размещена 29.06.2019 в 11:36 CoderHuligan вне форума
    Обновил(-а) CoderHuligan 29.06.2019 в 11:38
  20. Старый комментарий
    Аватар для liv
    Цитата:
    Сообщение от CoderHuligan
    Просто я иду ещё дальше него, к упрощению его подхода.
    Только вот какое отношение имеет к автоматному программированию повсеместный переход на goto? Лично я практически так и пишу на Ассемблере для встроенных систем, с которыми в основном и работаю. А именно больше о Embedded системах и идёт речь в лекции...
    И ни слова там о способах реализациях. К Вашему сведению, любую здравую идею можно довести до абсурда, что Вы с успехом и делаете...
    Так понял, до Вас даже не дошла идея автоматного программирования. Подошли к этому поверхностно... Лектор говорит совершенно о другом...
    Отсюда и Ваши "упрощения", которые на деле являются усложнениями, т.к. ведут к запутыванию кода.
    Запись от liv размещена 29.06.2019 в 14:01 liv вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru