goto и switch
Запись от CoderHuligan размещена 24.06.2019 в 10:22
Показов 5521
Комментарии 46
Вижу, что многие не понимают сути "народного" подхода, поступают вопросы, на которые следует ответить.
В моём случае я действую по старинке, не пряча оператор goto. Мой код может обработать любой компилятор, даже самый "тупой".
Во-вторых, моя программа никуда "не улетает". Она просто делает то, что предписано алгоритмом решения задачи. Если алгоритм предписывает куда-то перейти, например в начало, то код обеспечивает эту возможность. Вы же видите, даже такой простой код, уже настолько умён, что позволяет прерывать программу на любом шаге, входить в режим помощи на любом шаге и рестартовать программу. Даже если мы находимся на полпути расстановки кораблей на поле, можно сразу всё начать заново, сбросив все настройки. Из режима помощи можно вернутся в туже точку расстановки кораблей и продолжить с того же самого места. Напишите это в традиционном стиле. | ||||||||||||
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 46
Комментарии
-
Вся проблема в том, что код, который вы написали для демонстрации структурного подхода написан черте как... И если вы такой код увидите в реальном проекте, можете отправлять автора смело в школу. Я еле понял чего вы хотите в этом коде сделать, могли бы уж алгоритм как то еще больше усложнить
Запись от voral размещена 24.06.2019 в 11:02
-
я бы написал так (хотя я тоже не претендую на звания аса программирования на сях, переход в нишу веб программирования накладывает свой отпечаток
)
C 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#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; int prev = 0; while (*p) { if( *p == ' ' || *p == ',' || *p == '\n') { if (prev == 1) ++nw; prev = 0; } else { prev = 1; } ++p; } nw += prev; printf ("%d \n", nw); return 0; }
Запись от voral размещена 24.06.2019 в 11:11
-
А при чем тут компилятор? Мы с вами о читабельности кода, а не о том во что превращает его компилятор.
На "супер-пупер сложный алгоритм" это будет треш и ужас с вашими GOTO... Потому что возможность ошибки возрастает многократно... Стоит опечататься (вместо L111 поставить L11) или метку на строчку раньше вбабахат ("благо" отсутпов у вас практически не будет).... И все.... В строчку 17 вашего листинга "структурного варианта" можно попасть только одним путем. В строчку 12 вашего листинга вашего метода можно попасть из любой точки программы. Привет бессоные ночи...
А если говорить о разработке в команде, чужого кода, или свой код через год....... Это жесть.. Годится только с точки зрения академической. не более.Запись от voral размещена 24.06.2019 в 11:27
-
А в чем проблема для компилятора обработать код структурного программирования? Т.е. так программирует большинство и все испытывают проблемы с компиляцией? Или вы о том что компилировать современный код, компилятором года этак 1980го?Запись от voral размещена 24.06.2019 в 11:30
-
Использование Goto может привести к ошибкам.
На анимационной картинке показаны 2 кода, отличающиеся тем что в первом выход по Break, а во втором используя Goto. Первый работает нормально, а во втором ошибка при выходе из функции. Догадайтесь почему.
Кликните здесь для просмотра всего текста
Запись от locm размещена 24.06.2019 в 12:45
-
Запись от CoderHuligan размещена 24.06.2019 в 13:18
-
Не для демонстрации структурного, а для демонстрации НЕструктурного.
Сообщение от voral
Так я от подобного алгоритма изначально отталкивался: https://www.cyberforum.ru/blog... g5834.html
Сообщение от voral
Мой код эффективнее вашего на 30-50%. Мы в том же уроке в комментах это сравнивали. Правда некоторые опять пытались выдать желаемое за действительное, но оставим это на их совести.
Неоптимизирующий компилятор не сможет преобразовать свитч в таблицу переходов.
Сообщение от voral
Это можно выявить на стадии тестирования. Вообще же здесь goto вообще не причём. Я вам покажу сотни примеров как опечатываются в обычном коде при полном молчании компилятора.
Сообщение от voral
А если программа разбита на модули? Или на функции. Каждая метка в своём модуле или функции уникальна, даже если имеет одно и то же имя.
Сообщение от voral
Соблюдая некоторые элементарные соглашения по написанию кода можно избежать проблем, тем более, что большинство из них надуманные.
Сообщение от voral
Запись от CoderHuligan размещена 24.06.2019 в 13:27
-
Да обзовите как хотите. Второй листинг это треш.
Сообщение от CoderHuligan
Как раз таки тесты показывают, что ваш код не дает ни какого профита. Да вы можете выключить оптимизацию и наслаждаться... Но на практике это ни кому не нужно. Приведу вам пример: в свое время помогал написать программу для научных расчетов температуры головки молнии. Изанчально была написали на Turbo Pascal 5.5 при запуске на 386 компе расчет длился порядка суток. Потом я исключительно саму математику переписал на asm. При тех же самых исходных данных расчет стал выполнятся 4 часа. Профит!!! Казалось бы сейчас половина кода тогда должна быть на асме и не на чем больше. Но!.... Провел я году в 2005 похожий эксперимент с бенчмарками... Фиг вам. Современные компиляторы стали значительно умнее. Так же и в этом случае.
Сообщение от CoderHuligan
Т.е. если уж проводить сравнения, то именно в тех условиях как это будет на продакшене. Ну если только вас интересует это не только с академической точки зрения.
В замен мы получаем сложно поддерживаемый код.
А давайте вообще ориентироваться на 16ти битную архитектуру всегда... Ну так, вдруг у когото супер сервер на ней построен...
Сообщение от CoderHuligan
Дело не в наличии примеров. Я вам сам могу целую книгу по этому написать, т.к. много работаю с чужим кодом. В вашем коде сделать это (допустить тихую ошибку) в разы проще.
Сообщение от CoderHuligan
Понимаете в чем дело, если бы все упиралось в соглашения, то ошибок в программах было бы значительно меньше. Но человек не робот (опять же с идеальной прошивкой).. По этому тут надо подходить по принципу "На бога надейся, но сам не оплошай".. И в случае без гото, сам код "защищает" себя от множества ошибок присущих стилю с ГОТО... При этом можете показать ошибки на которые не ругнется компилятор, и которые не возможны в вашем подходе?
Сообщение от CoderHuligan
Запись от voral размещена 24.06.2019 в 13:52
-
мой вариант:
CoderHuligan, как будем мерить эффективность то???C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#include <stdio.h> #define N 255 char s[N]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed"; int main() { int nw = 0; char *p = s; while (*p) { while ( *p == ' ' || *p == ',' || *p == '\n') p++; if(*p++ == 0) break; nw++; while ( *p != ' ' && *p != ',' && *p != '\n' && *p) p++; }; printf ("%d \n", nw); return 0; }
Запись от XLAT размещена 24.06.2019 в 13:58
-
На самом деле, никакие подобные издевательства над кодом в наше время не имеют смысла, поскольку во первых в 99% задач рост производительности на считанные проценты не приносит никакого профита, а вот усложнение написания и сопровождения кода приводит к вполне ощутимым потерям. Еще 0.99% задач, где производительность имеет значение, современные оптимизирующие компиляторы прекрасно с этой задачей справляются и опять же городить готу нет абсолютно никакого смысла, компилятор сам нагородит где нужно. Не исключено, что нагородит даже лучше, чем вы. И лишь в оставшемся мизерном 0.01% иногда приходится что-то оптимизировать вручную, или даже писать ассемблерные вставки.Запись от Катафалк размещена 24.06.2019 в 15:00
-
Вы так считаете, потому-что видите лишь часть проблемы. Код, сырой код, это ещё не весь документ, в том подходе, который я исповедую. А у вас сырой код это весь документ. А я знаю, как сложно догадываться что тут в данном месте имел в виду программист, которому лень оставить вменяемый комментарий в "самодокументируемом" коде..
Сообщение от voral
Просто. Сегодня уже не смогу сравнить. Позже выложу результаты.
Сообщение от XLAT
GOTO нужен для упрощения и реализации алгоритма. Это средство АЛГОРИТМИЗАЦИИ.
Сообщение от Катафалк
Запись от CoderHuligan размещена 24.06.2019 в 16:30
-
После этой фразы, я совсем не понимаю, что в Вашем понимании документ.
Сообщение от CoderHuligan
Запись от voral размещена 24.06.2019 в 16:33
-
Вы совершенно не верно, похоже, трактуете термин "самодокументируемый".
Сообщение от CoderHuligan
Самодокументируемый код это не одно и то же что код с комментариями. Одно другое не исключает, а дополняет. Как раз коментарии нужны исключительно там, где могут быть разночтения кода. Поскольку код построенный на GOTO имеет меньшую степень самодокументируемости, просто "по определению", то в таком коде комментариев просто обязательно должно быть больше.Запись от voral размещена 24.06.2019 в 16:37
-
ок, вот сляпал на скорую руку
Сообщение от CoderHuligan
Это первый вариант:
чуть позже может быть(если не забуду) сделаю второй,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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
///----------------------------------------------------------------------------| /// Стенд для замера пииисек: мой против хулигана. /// 1 число - счетчик слов; /// 2 число - кол-во тактов на один проход; /// 3 число - текущая сумма тактов всех проходов. ///----------------------------------------------------------------------------: #include <stdio.h> #include <cmath> ///----------------------------------------------------------------------------| /// Мерилка тактов проца. ///----------------------------------------------------------------------------: typedef unsigned long long ull; inline ull rdtsc() { unsigned int lo, hi; asm volatile ( "rdtsc\n" : "=a" (lo), "=d" (hi) ); return ((ull)hi << 32) | lo; } ///----------------------------------------------------------------------------| /// Для удобства. ///----------------------------------------------------------------------------: #define START_PERFOMANCE ull t1 = rdtsc(); static ull ss_ = 0 #define END_PERFOMANCE(v) ull v = rdtsc(); v -= t1; ss_ += v ///----------------------------------------------------------------------------| /// Хулиган. ///----------------------------------------------------------------------------: ull CoderHuligan(char* s) { int nw = 0; char *p=s; START_PERFOMANCE; --p; OUT1: ++p; if(!*p) goto K; if(*p == ' ' || *p == ',' || *p == '\n') goto OUT1; nw++; goto IN1; IN1: if(!*p) goto K; if(*p == ' ' || *p == ',' || *p == '\n') goto OUT1; ++p; goto IN1; K: END_PERFOMANCE(t2); printf ("CoderHuligan: %d %+6u ", nw, t2); printf ("%+10u \n\n", ss_); return ss_; } ///----------------------------------------------------------------------------| /// my. ///----------------------------------------------------------------------------: ull my(char* s) { int nw = 0; char *p = s; START_PERFOMANCE; while (*p) { while ( *p == ' ' || *p == ',' || *p == '\n') p++; if(*p++ == 0) break; nw++; while ( *p != ' ' && *p != ',' && *p != '\n' && *p) p++; }; END_PERFOMANCE(t2); printf ("my: %d %+6u ", nw, t2); printf ("%+10u \n", ss_); return ss_; } ///----------------------------------------------------------------------------| /// Наш кролик. ///----------------------------------------------------------------------------: char s[]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed"; ///----------------------------------------------------------------------------| /// Start. ///----------------------------------------------------------------------------: int main() { ull m,c; for(int i = 0; i < 100; ++i) { m = my (s); c = CoderHuligan(s); } double ef = 100.0/double(c) * double(m) - 100.0; printf ("Profitable CoderHuligan: %2.2f%%\n\n", ef); return 0; }
идея второго варианта будет такова: берем минимальное значение выборки из общей серии от каждой пиииски и выводим в результат.
По результатам на моем компе(TDM-GCC 4.9.2):
ваши гоутушки на 2%кручебыстрее.Запись от XLAT размещена 24.06.2019 в 16:45
-
Ошибка происходит на этапе выполнения, а не при компиляции. Ясно же написано что происходит обращение к памяти по нулевому адресу.
Сообщение от CoderHuligan
Запись от locm размещена 24.06.2019 в 17:46
-
Запись от CoderHuligan размещена 24.06.2019 в 18:53
-
Запись от CoderHuligan размещена 24.06.2019 в 18:54
-
CoderHuligan,
новости для вас неутешительные, увы...
тест по второму варианту, по моему мнению более совершенному,
ваши гоутушки провалили:
вот сам тест:
https://ideone.com/ua8I2EC++ 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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
/// TDM-GCC 4.9.2 ///----------------------------------------------------------------------------| /// Стенд для замера пииисек: мой против хулигана. /// 1 число - счетчик слов; /// 2 число - кол-во тактов на один проход; /// Каждая новая строка есть прогресс по меньшему кол-ву тактов! /// /// my - самый выдающийся финиш с 442 тактами! (100'000'000 проходов) /// ... /// 10 минут спустя: /// на миллиарде проходов(1'000'000'000) /// CoderHuligan: 462 - looser... /// my: 441 - WIN <<<---!!! /// ... /// CoderHuligan, не плачьте! ///----------------------------------------------------------------------------: #include <stdio.h> //#include <conio.h> ///----------------------------------------------------------------------------| /// Мерилка тактов проца. ///----------------------------------------------------------------------------: typedef unsigned long long ull; inline ull rdtsc() { unsigned int lo, hi; asm volatile ( "rdtsc\n" : "=a" (lo), "=d" (hi) ); return ((ull)hi << 32) | lo; } ///----------------------------------------------------------------------------| /// Для удобства. ///----------------------------------------------------------------------------: #define START_PERFOMANCE ull t1 = rdtsc(); static ull ss_ = 0xffffffff;\ bool b = false #define END_PERFOMANCE ull v = rdtsc(); v -= t1;\ if(ss_ > v){ b = true; ss_ = v;} ///----------------------------------------------------------------------------| /// Хулиган. ///----------------------------------------------------------------------------: ull CoderHuligan(char* s) { int nw = 0; char *p=s; START_PERFOMANCE; --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: END_PERFOMANCE; if(b) { printf ("CoderHuligan: %d ", nw); printf ("%10u \n", (unsigned)ss_); b = false; } return ss_; } ///----------------------------------------------------------------------------| /// my. ///----------------------------------------------------------------------------: ull my(char* s) { int nw = 0; char *p = s; START_PERFOMANCE; while (*p) { while ( *p == ' ' || *p == ',' || *p == '\n') p++; if(*p++ == 0) break; nw++; while ( *p != ' ' && *p != ',' && *p != '\n' && *p) p++; }; END_PERFOMANCE; if(b) { printf ("my: %d ", nw); printf ("%10u \n", (unsigned)ss_); b = false; } return ss_; } ///----------------------------------------------------------------------------| /// Наш кролик. ///----------------------------------------------------------------------------: char s[]="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed"; ///----------------------------------------------------------------------------| /// Start. ///----------------------------------------------------------------------------: int main() { ull m,c; //-------------------------------| // Quiet, testing! | //-------------------------------: for(int i = 0; i < 10000000; ++i) { c = CoderHuligan(s); m = my (s); } //-------------------------------| // Banners is redy... | //-------------------------------: const char* str[2] = {"WIN <<<--!!!", "looser..."}; int i1, i2; (m > c) ? (i1 = 0, i2 = 1) : (i1 = 1, i2 = 0); //-------------------------------| // Finish result. | //-------------------------------: printf ("\nFinish the race-------------------:\n"); printf ("CoderHuligan: %u - ", (unsigned)c); printf ("%s\n", str[i1]); printf ("my: %u - ", (unsigned)m); printf ("%s\n", str[i2]); //-------------------------------| // Show efficiency. | //-------------------------------: double ef = 100.0/double(c) * double(m) - 100.0; printf ("\nProfitable CoderHuligan: %2.2f%%\n\n", ef); //_getch(); return 0; }
http://cpp.sh/3zxzd
https://rextester.com/ZVJG42008Запись от XLAT размещена 24.06.2019 в 20:15
-
Проверил ваш код и код voral. Код voral всегда на 30% медленнее. Вы прекрасно справились с задачей! Поздравляю! И подтверждаю ваши результаты - сейчас сам провёл эксперимент. В коде вы разделили оба состояния, что и привело к подобному результату. Разница в 1-2% несущественна, так как код с goto современные компиляторы не оптимизируют. Например вставляют пустые операции после каждого goto, что несколько замедляет программу.
Сообщение от XLAT
Вы смогли это сделать потому, что код примера очень прост.Запись от CoderHuligan размещена 25.06.2019 в 10:40
-
Дело не в компиляторе, а в использовании Goto.
Сообщение от CoderHuligan
Состояние стека в момент ошибки. Найдите отличия.
Кликните здесь для просмотра всего текста
Запись от locm размещена 25.06.2019 в 11:34


)

