Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.91] |
|
Сообщ.
#1
,
|
|
|
В Дельфи есть Аналог функции GOTO которая когда то помнится была в Бейсике?
|
Сообщ.
#2
,
|
|
|
goto
|
Сообщ.
#3
,
|
|
|
можно пример использования..? если не сложно
Спасибо. |
Сообщ.
#4
,
|
|
|
... ... кнопку F1 уже отменили?
procedure FindFirstAnswer; var X, Y, Z, Count: Integer; label FoundAnAnswer; begin Count := SomeConstant; for X := 1 to Count do for Y := 1 to Count do for Z := 1 to Count do if ... { some condition holds on X, Y, and Z } then goto FoundAnAnswer; ... {code to execute if no answer is found } Exit; FoundAnAnswer: ... { code to execute when an answer is found } end; (с) Delphi Help |
Сообщ.
#5
,
|
|
|
goto - мат в Паскале
|
Сообщ.
#6
,
|
|
|
Тестировщица, уж не обижайтесь, что то я похоже вместо работы спать пойду.. неработает котелок... слишком сложная программка...
Ct757, да знаю... ноиногда по другому нельзя.... сам не люблю |
Сообщ.
#7
,
|
|
|
Тестировщица, ну зачем ты так? Тебе бы всё шутки шутить..
На самом деле нет никакого GoTo, его махровые противники структурированного программирования просто придумали, чтоб код сделать нечитаемым! Конечно же можно его использовать время от времени, там, где структурный аналог будет более громоздким и менее прозрачным, но злоупотреблять им (как в ASM или BASIC), имхо, не стоит. |
Сообщ.
#8
,
|
|
|
Mechanic Ложки тоже не существует
|
Сообщ.
#9
,
|
|
|
Конечно же можно его использовать время от времени, там, где структурный аналог будет более громоздким и менее прозрачным, но злоупотреблять им (как в ASM или BASIC), имхо, не стоит.
В примере Тестировщицы из Help как раз такой случай |
Сообщ.
#10
,
|
|
|
Цитата Тестировщица @ Mechanic Ложки тоже не существует Знаю. И всю жизнь пытаюсь это доказать, хоть это и не имеет никакого смысла! Цитата Демо @ В примере Тестировщицы из Help как раз такой случай Ну, даже не совсем такой случай. Тут хоть можно простыми Break'ами всё разрулить. Бывают ситуёвины, когда просто есть множественные условия в разных ветках, и если следовать структуре, то придётся несколько раз дублировать блоки (пересекать стрелки на flowchart'е). Добавлено Цитата Айсид @ вместо работы спать пойду.. неработает котелок... слишком сложная программка... Многа букав, ниасилил.. Цитата Graphics32 FAQ > Q: There are some red, green, blue (and alpha) circles on the screen, what's that? > A: You spend too much time with computer, get some rest Метки юзятся, как в АСМе, только сперва описываются через Label имена_меток;. |
Сообщ.
#11
,
|
|
|
Айсид лучше пользоваться WHILE...do..
|
Сообщ.
#12
,
|
|
|
Можно и Abort делать, а обработчик его в except-е перехватывать
Много чего еще можно |
Сообщ.
#13
,
|
|
|
"Нужность" goto - одна из самых старых тем для holywars.
|
Сообщ.
#14
,
|
|
|
Эксепшены (Exceptions) - по сути тот же GOTO, только под другим соусом.
Добавлено Эксепшены (Exceptions) - по сути тот же GOTO, только под другим соусом. Это для противников данного оператора. А вообще оператор безусловного перехода - фффтопку, ИМХО |
Сообщ.
#15
,
|
|
|
Цитата Doesntmatter @ Эксепшены (Exceptions) - по сути тот же GOTO, только под другим соусом. Добавлено Сегодня, 16:01 Эксепшены (Exceptions) - по сути тот же GOTO, только под другим соусом. Это для противников данного оператора. А вообще оператор безусловного перехода - фффтопку, ИМХО 1. Exception - это резкое замедление программы 2. Exception предназначен для других целей. 3. Оператор безусловного перехода(впрочем, как и ветвление по условию), использовать нужно там, где это удобно и необходимо, а не проповедовать религию неиспользования оператора GOTO, услышав раз историю о его вреде. Не надо в своей работе использовать догмы, к тому же вредные и неверные. |
Сообщ.
#16
,
|
|
|
Цитата Mechanic @ Многа букав, ниасилил.. Осилил... Только сегодня утром на работе на свежую голову.. Кстати насчет того что GOTO иногда использовать нужно - согласен. Goose У меня как раз такой случай много веток. если бы использовал break для выхода из циклов то сделать это конечно смог, но код процедуры бы стал сложен в понимании... |
Сообщ.
#17
,
|
|
|
Жаль что в Delphi нет step для for, как в Бейсике, иногда о нужен. А вы не знаете в 9-ом дельфи его нет? Мне сказали еще что Delphi9 это .NET. И в нём исползуиться псевдокод. Я боюсь теперь его покупать, т.к.
думаю что ему нужен FRAMEWORK совместно с VC.NET. Куда всё катиться. Лучше бы step для for ввели!! |
Сообщ.
#18
,
|
|
|
micR0 зато есть
while a<=10 do begin a:=a+0.3; end; |
Сообщ.
#19
,
|
|
|
Демо а в чем приимущество GOTO
|
Сообщ.
#20
,
|
|
|
Цитата 1. Exception - это резкое замедление программы 2. Exception предназначен для других целей. Спасибо, что напомнили. Цитата Не надо в своей работе использовать догмы, к тому же вредные и неверные. Возвращаю Вам Вашу фразу. Цитата из Уолтера Савитча: Цитата Исключения позволяют писать программы с таким запутанным механизмом передачи управления, что разобраться в них бывает очень нелегко, а иногда почти невозможно. Генерация исключений позволяет передать управление с одного места программы практически в любое другое ее место. На заре рограммирования ничем не ограниченная передача управления такого рода разрешалась порседством такой известной многим программистам конструкции, как GOTO (когда-то она называлась безусловным переходом). Современные специалисты в области программирования сошлись на мнении, что использование такого "лихого" средства передачи управления свидетельствует об очень плохом стиле программирования. Механизм исключений позволяет вернуться в во времена безусловных переходов. Поэтому исключениями нужно пользоваться очень умеренно и только определенным образом... |
Сообщ.
#21
,
|
|
|
А мне-то она зачем? Я использую любые методы, которые мне удобны и наиболее эффективны в данном конкретном случае. Если это догматизм, то да, я - догматик. Добавлено Цитата Doesntmatter @ Цитата из Уолтера Савитча: Это религия? Добавлено Цитата Doesntmatter @ Современные специалисты в области программирования сошлись на мнении, что использование такого "лихого" средства передачи управления свидетельствует об очень плохом стиле программирования. Даже специалистам свойственны заблуждения. Добавлено Цитата Doesntmatter @ Генерация исключений позволяет передать управление с одного места программы практически в любое другое ее место. Это точно религия. Предлагается управление передавать методом поднятия исключений. Значительно удобнее перадть управление по GOTO. Поднятие исключения вызывает переход в режим ядра и обратно, что не происходит мгновенно. Добавлено В общем, я атеист. Мне не свойственно смотреть на разработчиков Delphi, на крупнейших специалистов как на незыблемые авторитеты. Поэтому я использую от, что удобно и эффективно. Не думаю, что стоит начинать войну по поводу религий. |
Сообщ.
#22
,
|
|
|
Демо, Правильно! Так им, буквоедам!
А вообще, Код коду рознь, и бывает даже процовые глюки, глюки компилера, что помогают оптимизить код - всё в дело идёт! Ведь обычно интересно от компа РЕЗУЛЬТАТ получить, но реализация уже вторична. Особенно, если код не подразумевает долгой жизни, или модификации.. И любые команды, что в этом помогут - в радость. Хоть через GPF управление передавать! Всё. Поехало.. Не. Я больше сюда не писану. Честно.. |
Сообщ.
#23
,
|
|
|
Цитата Демо @ Это религия? Это утверждения, которые сложились в результате многолетнего опыта программеров |
Сообщ.
#24
,
|
|
|
Цитата Ct757 @ Это утверждения, которые сложились в результате многолетнего опыта программеров Ну тогда, думаю, надо определиться, чем мешает GOTO? |
Сообщ.
#25
,
|
|
|
Цитата Демо @ Ну тогда, думаю, надо определиться, чем мешает GOTO? Знаю, что щас скажут.. Типа "мешает тем программерам, что ЭТО не писали, но прочитать желают [|должны]".. Все. Ухожу.. |
Сообщ.
#26
,
|
|
|
GOTO это ностальгия по JMP
|
Сообщ.
#27
,
|
|
|
Цитата GOTO это ностальгия по JMP Но как ни пытайся избавиться от goto он всегда будет присутствоавть в компилированом коде в виде этих джампов :) |
Сообщ.
#28
,
|
|
|
Walter Sawitch - это один из спецов по Java.
|
Сообщ.
#29
,
|
|
|
Цитата Демо @ Ну тогда, думаю, надо определиться, чем мешает GOTO? Хм... Цитата Все знают, что нельзя использовать goto, но уже никто не помнит почему Если серьезно, то goto просто снижает читабельность кода, и портит структуру программы... А вообще тему надо закрывать - использовать или не использовать это дело каждого. |
Сообщ.
#30
,
|
|
|
Ну что вы всё goto, goto.. Ну кто их использует? Кому ещё надо лейблы обьявлять?
|
Сообщ.
#31
,
|
|
|
Цитата Doesntmatter @ Генерация исключений позволяет передать управление с одного места программы практически в любое другое ее место Ну те то чтобы совсем в другое место, но тем немение.. Именно для этого исключения и были введены. Для того чтобы код, который не может обработать ошибку мог передать управление тому коду, который ошибку МОЖЕТ обработать. И не задумываться, где именно такой код находится.. |
Сообщ.
#32
,
|
|
|
Исключения - это вообще не о том Абсолютно.
goto - если вам захотелось использовать goto и вам кажется, что он необходим, значит вы неправильно выделили функции |
Сообщ.
#33
,
|
|
|
Ну как народ до сих пор не может понять? Каждое средство лучше всего применимо для того, для чего предназначено. Если поставив один goto я избегу десятиэтажной конструкции из if/while/do - то я поставлю один goto. И мне плевать, что кто-то назовет это "моветоном".
|
Сообщ.
#34
,
|
|
|
Кхгм. Флекс. Я знаю, что мой код будут читать. И за goto меня погладят по головке. Сковородкой .
Практически использование goto является принаком того, что: 1) человек хреново представляет задачу 2) код не подвергался рефакторингу Я могу понять случаи, когда goto использован по делу. Мастером. Редко, но могу. К тому же, switch из С++ фактически тот же goto (в чём то). Но это обычно означает, что хреново продумали семантику функций или т.п. |
Сообщ.
#35
,
|
|
|
Цитата Mechanic @ но злоупотреблять им (как в ASM или BASIC), имхо, не стоит. Как в ASM? А как там обойтись без безусловных переходов? Цитата Демо @ Значительно удобнее перадть управление по GOTO. Поднятие исключения вызывает переход в режим ядра и обратно, что не происходит мгновенно. Смотря какой язык. Явисты с вами не согласятся. Цитата Flex Ferrum @ Ну как народ до сих пор не может понять? Каждое средство лучше всего применимо для того, для чего предназначено. Если поставив один goto я избегу десятиэтажной конструкции из if/while/do - то я поставлю один goto. И мне плевать, что кто-то назовет это "моветоном". Почему моветоном? В случае, описанном вами - это общепризнанный метод решения этой проблемы. |
Сообщ.
#36
,
|
|
|
Цитата Evil J @ Как в ASM? А как там обойтись без безусловных переходов? Вот и я о том, что для ASM-кодеров этот топик, будет выглядеть при прочтении ..э.. несколько странным. У них нет альтернативы. У нас есть. Но если бы команда была не нужна, и нарушала бы какие-нить принципиальные устои языка, её бы уже давно исключили. Но что-то не видно в мануалах фразы типа "Obsolete. just for backward compatibility with old-shaped stupid programmers' brains".. |
Сообщ.
#37
,
|
|
|
Не скажу, что goto мой любимый оператор, но если будет необходимо - воспользуюсь не задумываясь. Также не скажу, что набью лицо(с) любому, кто этого не сделает
|
Сообщ.
#38
,
|
|
|
Цитата Демо @ Не скажу, что goto мой любимый оператор, но если будет необходимо - воспользуюсь не задумываясь. Хотел бы я увидеть случай, в котором есть крайняя необходимость использования goto. |
Сообщ.
#39
,
|
|
|
Цитата s-mike @ Хотел бы я увидеть случай, в котором есть крайняя необходимость использования goto. парсер, построенный на основе цикла, внутри которого реализована кейс машина. там goto смотрится очень даже к месту. также goto к месту, если платформа не поддерживает механизм исключений: чтобы можно было с любого места функции ее завершить и правильно освободить ресурсы. |
Сообщ.
#40
,
|
|
|
Цитата s-mike @ Хотел бы я увидеть случай, в котором есть крайняя необходимость использования goto. А вот мне бы хотелось увидеть другой случай - когда напрашивается использование GOTO, но проще сделать по-другому. Например - пример из справки по Delphi именно по GOTO - выход из пачки вложенных циклов. |
Сообщ.
#41
,
|
|
|
Цитата Демо @ Например - пример из справки по Delphi именно по GOTO - выход из пачки вложенных циклов. Пример надуман. Abort рулит. |
Сообщ.
#42
,
|
|
|
Цитата s-mike @ Пример надуман. Abort рулит. Стоп. При чем тут Abort? Нам нужно всего лишь выйти из циклов. |
Сообщ.
#43
,
|
|
|
Цитата Evil J @ Стоп. При чем тут Abort? Нам нужно всего лишь выйти из циклов. Чтобы выйти из цикла. В Дельфи процедура Abort (иными словами "тихое исключение") вызывает рекурсивный выход из всех вложенных функций/циклов пока не встретит обработчик исключения. В самый раз для такой задачи, имхо. |
Сообщ.
#44
,
|
|
|
Цитата s-mike @ вызывает рекурсивный выход из всех вложенных функций/циклов пока не встретит обработчик исключения Тогда в чем семантическая разница между Abort, и Goto Obrabotchik_Isklyucheniya ? |
Сообщ.
#45
,
|
|
|
Цитата Mechanic @ Тогда в чем семантическая разница между Abort, и Goto Obrabotchik_Isklyucheniya ? Abort: - производит корректный выход по стеку; - приводит к корректному освобождению памяти, выделенному под переменные (если конечно правильно расставлены try..finally); - красивее и предсказуемей, имхо Я бы выход их цикла с помощью GOTO сравнил со спуском с высотного дома без лифта: можно съехать по перилам и сломать шею, а можно аккуратно спуститься по ступенькам |
Сообщ.
#46
,
|
|
|
Не, s-mike, это понятно. Но это разница техническая, так сказать разница реализации механизмов. Я вот что спрашивал:
Цитата Mechanic @ в чем семантическая разница То есть, чем отличается логика алгоритма процедуры (его графический flowchart, если угодно) с тем и другим оператором? |
Сообщ.
#47
,
|
|
|
Цитата s-mike @ Abort: - производит корректный выход по стеку; - приводит к корректному освобождению памяти, выделенному под переменные (если конечно правильно расставлены try..finally); Вот именно - если конечно правильно расставлены try..finally А зачем мне замедлять работу процедуры поднятием исключений? Если у меня не выделятеся память и ресурсы для объектов? GOTO - прямой и самый быстрый переход. Нахрена мне еще время тратить на исключения? Ну вот скажи? Ради религии? Тогда В САД такую религию и религиозных деятелей. |
Сообщ.
#48
,
|
|
|
bugger, ты что, какой goto в парсерах? Разве что на фортране...
|
Сообщ.
#49
,
|
|
|
Цитата Демо @ А зачем мне замедлять работу процедуры поднятием исключений? Если у меня не выделятеся память и ресурсы для объектов? Используй другие методы: exit, continue, break. Мне всегда удаётся ими обойтись. Если тебе не всегда - давай спорить с кодом. Ты показываешь фрагмент кода, где якобы невозможно обойтись без goto. И тогда посмотрим, насколько он нужен. И религия тут не причем. Я бы сказал, что избежание goto приводит к большей красоте и предсказуемости кода, не внося лишней путаницы. |
Сообщ.
#50
,
|
|
|
Цитата Нахрена мне еще время тратить на исключения? Ну вот скажи? Ради религии? Тогда В САД такую религию и религиозных деятелей. Месье видимо программировал исключительно Хелловый Ворлд. В проге с множеством подсистем ЗАКОЛЕБЁШСЯ вылавливать все коды ошибок, а вот, допустим, запуск исключения assert-ом (да, это опять они - исключения) позволяет на этапе отладки и без кода ошибки скажет тебе, что "не сработало условие на строке 1354 в файле RunLikeHell.cpp. И религия тут не при чём, просто это ДЕЙСТВИТЕЛЬНО УДОБНО в больших и огромных программах . Вот, у меня в проге, которую я счас делаю (она пока что скромная довольно) около 150 ассертов. Из них около 30 - assert( false ), т.е. участки кода, зайдя в которые мы точно знаем, что попали "нетуда". Попробуй на каждуй завести код ошибки , вот я посмотрю на тебя нужно помнить, что C++ - это язык для огромных программ, для которых плоский С слишком слаб. Не в плане скорости, а в плане.. ну предположим, тех же namespaces, overloading resolution и т.д. Введение assert-ов - это как раз одна из фич для огромных программ. Добавлено И получается, что система не зависит от того, насколько хорошо мы задокументировали коды ошибок, это становится просто не нужным. Тестировщик говорит: "Видел assert с указанием на такой то файл и такую то строку делая то то и то то". Всё, этого достаточно, что бы ошибку исправить. А для программера ещё и удобно - он сразу вываливается в отладчик и начинает зырить - стёк вызовов и т.д. |
Сообщ.
#51
,
|
|
|
Цитата BugHunter @ Вот, у меня в проге, которую я счас делаю (она пока что скромная довольно) около 150 ассертов. А еще лучше - до ассертов вообще не доводить. Если произошло что-то нештатное, то должно быть исключение. Тем более, что ассерт (в обычной его реализации) - коварная штука, которая (при некорректном использовании) очень хорошо может "подпортить" релизную версию сборки. Второй момент - да, ассерты помогут выявить явные косяки. Но! Только в debug-версии сборки. В тестирование, вообще говоря, нужно отдавать релизную версию, т. е. именно то, что в последствии будет продаваться. Особенно (подчеркиваю - особенно), если будет проводиться стресс-тестирование в условиях, например, нехватки ресурсов, или при большой нагрузке. debug-версия сборки этого элементарно не выдержит. |
Сообщ.
#52
,
|
|
|
Цитата А еще лучше - до ассертов вообще не доводить. Тем более, что ассерт (в обычной его реализации) - коварная штука, которая (при некорректном использовании) очень хорошо может "подпортить" релизную версию сборки. Ну, правила ассертов очень простые - в них нельзя делать какой нибудь значимый код . Цитата В тестирование, вообще говоря, нужно отдавать релизную версию, т. е. именно то, что в последствии будет продаваться. Да, но для начала можно (и нужно) и дебаг версию . Особенно если речь идёт о GUI. |
Сообщ.
#53
,
|
|
|
Цитата BugHunter @ Да, но для начала можно (и нужно) и дебаг версию Может быть, может быть... Если речь идет о GUI... |
Сообщ.
#54
,
|
|
|
Ну, с серверными приложениями всё совсем не так . Там аккуратное ведение лога ошибок (а для этого их всех нужно знать ) - первооснова всего .
|
Сообщ.
#55
,
|
|
|
Цитата s-mike @ Я бы сказал, что избежание goto приводит к большей красоте и предсказуемости кода, не внося лишней путаницы. Возьмем простейший пример из справки Delphi: procedure FindFirstAnswer; var X, Y, Z, Count: Integer; label FoundAnAnswer; begin Count := SomeConstant; for X := 1 to Count do for Y := 1 to Count do for Z := 1 to Count do if ... { some condition holds on X, Y, and Z } then goto FoundAnAnswer; ... {code to execute if no answer is found } Exit; FoundAnAnswer: ... { code to execute when an answer is found } end; Прошу продемонстрировать большую красоту и предсказуемость кода БЕЗ использования GOTO. Добавлено Цитата BugHunter @ Месье видимо программировал исключительно Хелловый Ворлд. Не будем демагогией заниматься и пороть чушь , хорошо? Цитата BugHunter @ В проге с множеством подсистем ЗАКОЛЕБЁШСЯ вылавливать все коды ошибок, а вот, допустим, запуск исключения assert-ом (да, это опять они - исключения) позволяет на этапе отладки и без кода ошибки скажет тебе, что "не сработало условие на строке 1354 в файле RunLikeHell.cpp. И религия тут не при чём, просто это ДЕЙСТВИТЕЛЬНО УДОБНО в больших и огромных программах . Вот, у меня в проге, которую я счас делаю (она пока что скромная довольно) около 150 ассертов. Из них около 30 - assert( false ), т.е. участки кода, зайдя в которые мы точно знаем, что попали "нетуда". Попробуй на каждуй завести код ошибки , вот я посмотрю на тебя Разговор идет не о повсеместном применении оператора, а том, что можно, и главное - ДОЛЖНО - применять его там, где это необходимо. Обработка ошибок - это обработка ошибок. А безусловный переход - совсем другое. Цитата s-mike @ Ты показываешь фрагмент кода, где якобы невозможно обойтись без goto. Обойтись без GOTO можно ВЕЗДЕ. Но нужно ли? Я не понимаю жестоких противников GOTO, так как они не приводят доказательств свое правоты. Т.е., по-существу, несут религиозную чушь. Добавлено Добавлю, что мне использовать GOTO надобности не возникало(пока!), потому что не возникало необходимости в коде(масса вложенных циклов), приведенном выше. Но я ни на секунду не стал бы задумываться, использовать GOTO или нет, если бы возникла такая необходимость. А необходимость - как раз простота кода, его удобочитаемость. Да и скорость не на последнем месте. |
Сообщ.
#56
,
|
|
|
Да пожалста. Для хорошего человека и дерь... дельфёвого кода не жаль.
{ Да плевал я на подсветку в этом разделе! } var X, Y, Z, Count: Integer; flag:Boolean; begin flag := false; Count:=SomeConstant; for X := 1 to Count do for Y := 1 to Count do for Z := 1 to Count do if { That f*cking condition } then begin {code to execute when answer is found} flag := true; { For the after-loop code: we have found it! } end; if not flag then { code to explicitly execute when no answer is found } end |
Сообщ.
#57
,
|
|
|
Цитата Ho Im @ Да пожалста. Для хорошего человека и дерь... дельфёвого кода не жаль. К сожалению, 1. Код неверен: выход по Break; будет только из одного цикла. 2. А если добавлять в каждый цикл if Flag then Break;, то где та простота и красота кода, про которую говорилось? |
Сообщ.
#58
,
|
|
|
Цитата Обойтись без GOTO можно ВЕЗДЕ. Но нужно ли? Я не понимаю жестоких противников GOTO, так как они не приводят доказательств свое правоты. Т.е., по-существу, несут религиозную чушь. меня за goto уволят , это вполне практичная штука Цитата Возьмем простейший пример из справки Delphi: Цитата begin Count := SomeConstant; for X := 1 to Count do for Y := 1 to Count do for Z := 1 to Count do if ... { some condition holds on X, Y, and Z } then goto FoundAnAnswer; ... {code to execute if no answer is found } Exit; FoundAnAnswer: ... { code to execute when an answer is found } end; а тут всё зависит от того, что за условие. Если оно простое, то его лучше разбить на несколько, используя при этом continue. Если оно сложное, то можно вообще выделить этот обход по циклам в ОТДЕЛЬНУЮ ФУНКЦИЮ и делать из неё return по условию. RETURN - что может быть красивее? |
Сообщ.
#59
,
|
|
|
Ho Im, не уверен, что этот вариант является аналогичным исходному.
|
Сообщ.
#60
,
|
|
|
рефакториг импрувинг, блин, вот что спасёт нас от безумных goto, к тому же, сдаётся мне, что в данном примере выделение этого куска кода в отдельную функцию есть очень и очень правильно.
|
Сообщ.
#61
,
|
|
|
Цитата BugHunter @ а тут всё зависит от того, что за условие. Согласен. А если еще на каждом уровне вложенных циклов свои проверки? Цитата BugHunter @ вообще выделить этот обход по циклам в ОТДЕЛЬНУЮ ФУНКЦИЮ и делать из неё return по условию Return лишь вернет из функций внутрь цикла. Но выглядеть это красивее точно не будет. Кроме потери простоты и наглядности кода, будет потеря в скорости на вызовах функций. Цитата BugHunter @ RETURN - что может быть красивее? Да, если он один, а не 20. Добавлено Цитата BugHunter @ в данном примере выделение этого куска кода в отдельную функцию есть очень и очень правильно. Вряд ли в этом есть необходимость. Разве что религиозная. |
Сообщ.
#62
,
|
|
|
Цитата Да, если он один, а не 20. а 20 goto, я уверен, гораздо лучше . Незачёт. Цитата Вряд ли в этом есть необходимость. Разве что религиозная. Не согласен. Категорически. Например, можно её назвать CheckPoints4Condition. И тогда читателю можно не вдаваться в подробности: вот этот вызов проверяет, выполняется ли для точек условие, .. и если, то ... иначе.. и т.д. Программы пишутся в первую очередь для людей, если функция названа правильно, то читателю как правило, нет нужды заглядывать в её тело. Пример из справки Delphi - именно такой Да, может быть это проблема религиозная. Учти, что основные заповеди этой религии: 1) писать поддерживаемый код 2) что бы глядя на код через 5 лет не хотелось материться 3) возлюби читателя кода как самого себя. и вообще, что я тут распинаюсь, ты прочитай для начала хотя бы Фаулера, что ли. |
Сообщ.
#63
,
|
|
|
О!
function check_cond(x, y, z:Integer):boolean; function answer_found(... args ...):result_type; function check_and_answer(x, y, z:Integer):boolean; begin if check_cond(x, y, z) then begin answer_found( ... ); return true; end; return false; end; procedure our_loop; var x, y, z: Integer; f: Boolean; begin x:=1; y:=1; z:=1; f:=False; while (x <= Count) and not f do begin while (y <= Count) and not f do begin while (z <= Count) and not f do begin f:=check_and_answer(x, y, z); inc(z) end; z:=1; inc(y) end; y:=1; inc(x) end end; Во. Здесь, надеюсь, все правильно? |
Сообщ.
#64
,
|
|
|
Цитата BugHunter @ CheckPoints4Condition. И тогда читателю можно не вдаваться в подробности: вот этот вызов проверяет, выполняется ли для точек условие, .. и если, то ... иначе.. и т.д. Программы пишутся в первую очередь для людей, если функция названа правильно, то читателю как правило, нет нужды заглядывать в её тело. Пример из справки Delphi - именно такой Бухантер, я все понимаю, но за такое название функции я бы вспомнил разработчика очень многими "добрыми" словами. Назначение функции должно быть понятным из его названия. А смотря на метод CheckPoints4Condition, который, к тому же, вызывается всего из одного места, я буду очень долго гадать - а зачем и кому он понадобился... Добавлено Цитата Ho Im @ О! Гм. Кто-то еще (в условии задачи) хотел красивости решения. Это раз. Второй момент. В каком варианте больше потенциальных источников ошибок - в варианте с goto или без него? |
Сообщ.
#65
,
|
|
|
Цитата BugHunter @ а 20 goto, я уверен, гораздо лучше . Незачёт. Не 20, а всего один;) Ладно. Лучше все-таки на конкретном примере. Сейчас сделаю. |
Сообщ.
#66
,
|
|
|
Начнем с того, что пример надуман и задача поставлена некрасиво. Продолжим тем, что я чего-то не видел тернарного оператора в дельфях и нормального for (в котором можно проверять не только счетчик). Так что о красоте забудьте, но мне кажется, что мой кусок кода сопровождать таки легче, особенно если эти вложенные циклы, проверки и проч. экстраполировать на задачки реального мира.
Может, Демо угодно только примеры из справки делать... не знаю... |
Сообщ.
#67
,
|
|
|
Во. Здесь, надеюсь, все правильно?[/quote]
А здесь дополнительное условие в каждом цикле разве не усложняет код? Добавлено Цитата BugHunter @ и вообще, что я тут распинаюсь, ты прочитай для начала хотя бы Фаулера, что ли. Ты апологет Фаулера? Не надо молиться на знаменитости. Они тоже ошибаются. Им точно так же свойственны заблуждения. |
Сообщ.
#68
,
|
|
|
Цитата Ho Im @ Начнем с того, что пример надуман и задача поставлена некрасиво. На счет надуманности примера... Ну как тебе сказать, я, когда ковырялся в алгоритмах уравнивания геодезических сетей, достаточно часто сталкивался с необходимостью подобного нагромождения циклов и постпроцессинга результатов. |
Сообщ.
#69
,
|
|
|
Цитата Бухантер, я все понимаю, но за такое название функции я бы вспомнил разработчика очень многими "добрыми" словами. Назначение функции должно быть понятным из его названия. А смотря на метод CheckPoints4Condition, который, к тому же, вызывается всего из одного места, я буду очень долго гадать - а зачем и кому он понадобился... Ну, к данному названию придираться не стоит, я его придумал за 0.5 секунды. Тут всё зависит от конкретного условия. CheckPoints4Condition - за это я бы тоже растерзал . Цитата Добавлено Сегодня, 12:49 Цитата (Ho Im @ Сегодня, 12:40) О! Хоим, такой большой, а дурачком притворяешься. Вот тебе правильный ответ. bool CheckPoint4Condition( CMatrix* matrix ) { for ( int i = 0; i < matrix.GetMaxX(); i++ ) { for ( int j = 0; i < matrix.GetMaxY(); j++ ) { for ( int k = 0; i < matrix.GetMaxZ(); k++ ) { if ( condition ) { return true; } } } } return false; } //... if ( CheckPoint4Condition( &matrix ) ) { //условие выполнилось } else { //беда с условием } Цитата Гм. Кто-то еще (в условии задачи) хотел красивости решения. Это раз. Второй момент. В каком варианте больше потенциальных источников ошибок - в варианте с goto или без него? |
Сообщ.
#70
,
|
|
|
BugHunter
Кхм. Чем лучше вызов функции, чем один безусловный переход? |
Сообщ.
#71
,
|
|
|
Цитата BugHunter @ Вот тебе правильный ответ. А если в постусловии мне нужно знать - в какой строке/столбце/слое это условие выполнилось? |
Сообщ.
#72
,
|
|
|
Цитата Начнем с того, что пример надуман и задача поставлена некрасиво. Пример абсолютно реальный, 3-х мерность - это ещё что, вот когда у нас в задаче 9 и более параметров... я бы посмотрел на того героя, который бы корректно разрулил это goto-ами. Цитата Ты апологет Фаулера? а ты читал его? У него книжка состоит из противоположных советов: "выделите" / "соберите", в зависимости от ты можешь выбрать что нибудь на свой вкус . Он придерживается той же религии, что и я - читаемость кода . ..Хоим, я вижу, ты маргинал во всём. Это.. хм. Странно Цитата Не надо молиться на знаменитости. Они тоже ошибаются. Им точно так же свойственны заблуждения. Я не молюсь, а всего лишь учусь у старших товарищей. Чего и вам желаю. Цитата Не 20, а всего один;) Ладно. Лучше все-таки на конкретном примере. Сейчас сделаю. Давай, давай, хочу на это посмотреть |
Сообщ.
#73
,
|
|
|
Цитата Flex Ferrum @ А если в постусловии мне нужно знать - в какой строке/столбце/слое это условие выполнилось? Да даже если и надо знать. Непонятно, чем лучше дополнительная функция... |
Сообщ.
#74
,
|
|
|
Цитата BugHunter @ Он придерживается той же религии, что и я - читаемость кода В этом я совершенно согласен. НО! Я и без Фаулера достаточно книг прочитал. И в каждой из них достаточно ошибок. Поэтому старший это или не старший товарищ, но прежде всего нужно думать своей головой и подходить критически к тому, что пишут "старшие товарищи", руководствуясь прежде всего целесообразностью и здравым смыслом. Цитата BugHunter @ Давай, давай, хочу на это посмотреть Без меня уже привели примеры. |
Сообщ.
#75
,
|
|
|
BugHunter, человеку, кажется, пример был нужен именно на убогом недоязычке Object Pascal.
|
Сообщ.
#76
,
|
|
|
Цитата А если в постусловии мне нужно знать - в какой строке/столбце/слое это условие выполнилось? А это уже зависит от. Вариантов разрулить масса. Это, скорее, зависит от предполагаемых размеров программы и желаем ли мы этот код хоть как то использовать в будущем . Можно, например, возвращать не bool, а объект "точка", с невалидным состоянием если условие не выполнилось. Цитата Непонятно, чем лучше дополнительная функция... Посмотри на мой пример, разве не красавец? При отладке мы чаще всего будем CheckPoint4Condition пропускать мимо, зная, что именно происходит в нём исключительно из названия . ...я допускаю, что можно придумать извращённые случаи. Но вот 99% случаев к ним не относится. Конец истории. |
Сообщ.
#77
,
|
|
|
Пока Демо думает над своим примером, я предложу задачу коллегам по цеху (т. е. С-шникам). Задачка проста:
for (int n = 0; n < some_value; ++ n) { switch (...) { case 0: break; case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; } } Задача: модифицировать код так, чтобы при выполнении веток 0, 1 и 4 в том числе выполнился некий набор действий (назовем его А), и цикл завершился, при выполнении веток 2 и 5 - в том числе выполнился некий набор действий B и цикл завершился. Во всех остальных случаях ни А ни B выполняться не должно и цикл должен крутиться дальше. |
Сообщ.
#78
,
|
|
|
Цитата Ho Im @ BugHunter, человеку, кажется, пример был нужен именно на убогом недоязычке Object Pascal. Мне все равно, на недоязычке Си приведен пример или на любом другом. Добавлено Цитата BugHunter @ Конец истории. Вряд ли. Категоричность свойственна лишь тем, кто еще мало знает;) Цитата BugHunter @ Посмотри на мой пример, разве не красавец? Вряд ли он красивее и целесообразнее единственного вызова GOTO в той же функции. Добавлено Цитата Ho Im @ BugHunter, человеку, кажется, пример был нужен именно на убогом недоязычке Object Pascal. Еще добавлю, что чем мазать - дело вкуса, поэтому оставь свои выпады при себе. |
Сообщ.
#79
,
|
|
|
Flex, я не знаю, чем goto туда, goto обратно будет в твоём примере лучше, чем вызов функции .
Это раз. А во вторых - когда я вижу большие case, я чаще всего вспоминаю про полиморфизм, но это конечно, не про плоский C. |
Сообщ.
#80
,
|
|
|
Цитата BugHunter @ Можно, например, возвращать не bool, а объект "точка", с невалидным состоянием если условие не выполнилось. Ну вот, уже объекты в ход пошли. Лишь бы goto не использовать... Цитата BugHunter @ ...я допускаю, что можно придумать извращённые случаи. Но вот 99% случаев к ним не относится. Конец истории. Но так ведь никто и не говорит, что goto нужно использовать везде и вся. Но, честно говоря, если, например, использование goto существенно поднимет скорость выполнения критичного по времени участка программы - то велика вероятность, что я им воспользуюсь. Все очень просто. Вариант с дополнительным флагом вводит пенальти на сравнении с bool. В большинстве случаев это сравнение будет выполняться медленней, чем, например, просто сравнение двух int'ов на неравенство. Вариант с вызовом функции, содержащей 3 цикла, чуть лучше, но тоже имеет свое пенальти, если, например, вызов не будет раскрыт в inline. Особенно, если в функцию придется передавать или возвращать из нее какую-то дополнительную информацию. |
Сообщ.
#81
,
|
|
|
BugHunter
Твой пример красив, но он не демонстрирует, почему GOTO НЕЛЬЗЯ использовать... |
Сообщ.
#82
,
|
|
|
Цитата BugHunter @ Это раз. А во вторых - когда я вижу большие case, я чаще всего вспоминаю про полиморфизм, но это конечно, не про плоский C. Ууу... А у нас уже придумали полиморфизм по значению аргумента? Не знал, не знал... А реализация такой фишки имеющимися средствами (по сложности) не войдет ни в какое сравнение с одним маленьким goto. Цитата BugHunter @ Flex, я не знаю, чем goto туда, goto обратно будет в твоём примере лучше, чем вызов функции Какой? Напиши. |
Сообщ.
#83
,
|
|
|
Цитата Категоричность свойственна лишь тем, кто еще мало знает;) Ты не мычи, ты пальцем покажи . |
Сообщ.
#84
,
|
|
|
Цитата BugHunter @ Ты не мычи, ты пальцем покажи Так если ты сишников лучше понимаешь, то аргументы тебе Flex Ferrum приводит пока. Я вот с краю тут сижу, жду ответов(и аргументов) |
Сообщ.
#85
,
|
|
|
Цитата Ну вот, уже объекты в ход пошли. Лишь бы goto не использовать... Ну, я ж говорю, всё зависит от объёма задачи . Если она маленькая, то можно конечно, и goto применить . Но что то мне в последнее время (года 3 ) такие не попадаются . Цитата Все очень просто. Вариант с дополнительным флагом вводит пенальти на сравнении с bool. В большинстве случаев это сравнение будет выполняться медленней, чем, например, просто сравнение двух int'ов на неравенство. Вариант с вызовом функции, содержащей 3 цикла, чуть лучше, но тоже имеет свое пенальти, если, например, вызов не будет раскрыт в inline. Особенно, если в функцию придется передавать или возвращать из нее какую-то дополнительную информацию. Согласен bool DoHast( int arg ) switch ( arg ) { case 0: break; case 1: case 2: // AddAction1(); return false; case 3: // AddAction2(); //расставил случайно return false; case 4: break; case 5: AddAction1(); return false; case 6: break; } for (int n = 0; n < some_value; ++ n) { if ( !DoHast( arg ) ) { break; } } тут, правда, довольно сложно будет выбрать удчаное имя для выделяемой функци, т.к. имя должно сигнализировать и об условии окончания цикла, и о том, что же в ней на самом деле происходит Возможно, я бы разбил это даже на 2 функции с более понятными именами. 2 switch-а вместо одного? Да. Ну и ладно. Нехай будет, но пускай будет прозрачно. |
Сообщ.
#86
,
|
|
|
procedure FindFirstAnswer; function FindAnAnswer: Boolean; var X, Y, Z, Count: Integer; begin Result := False; Count := SomeConstant; for X := 1 to Count do for Y := 1 to Count do for Z := 1 to Count do if ... { some condition holds on X, Y, and Z } then begin Result := True; Exit; end; end; begin if FoundAnAnswer then ... { code to execute when an answer is found } else ... {code to execute if no answer is found } end; |
Сообщ.
#87
,
|
|
|
s-mike
Это просто аналог сишного примера. Тоже не видно плюсов, кроме минуса в виде дополнительного вызова функции... -) |
Сообщ.
#88
,
|
|
|
Цитата BugHunter @ тут, правда, довольно сложно будет выбрать удчаное имя для выделяемой функци, т.к. имя должно сигнализировать и об условии окончания цикла, и о том, что же в ней на самом деле происходит Мало того, при таком варианте могут быть проблемы в том случае, если набор действий А и набор действий B "завязаны" на текущее состояние переменных в методе, где крутится цикл. Грубо говоря, если каждый кейс меняет состояние нескольких переменных, объявленных за пределами цикла, то просто так ты это не разрулишь. Добавлено А примеры того, где такое может понадобиться, можно найти в реализациях алгоритмов, хорошо описываемых логикой конечных автоматов. |
Сообщ.
#89
,
|
|
|
Цитата Демо @ Это просто аналог сишного примера. Тоже не видно плюсов, кроме минуса в виде дополнительного вызова функции... -) Это правильный вариант решения. Чтобы небыло лишней функции в коде, можно применить inline. В новых дельфях это уже есть. А что тебе там не нравится? Хорошо структурированный код, наглядный, однозначный, легче вносить правки. Добавлено Цитата Ho Im @ BugHunter, человеку, кажется, пример был нужен именно на убогом недоязычке Object Pascal. Для тебя Object Pascal недоязык, потому что ты его не знаешь? Именно это показали твои попытки написать пример без goto на нем. Лови -. |
Сообщ.
#90
,
|
|
|
Цитата BugHunter @ меня за goto уволят , это вполне практичная штука Так бы и сказал сразу. Все остальные доводы надуманы.. |
Сообщ.
#91
,
|
|
|
Цитата s-mike @ А что тебе там не нравится? Хорошо структурированный код, наглядный, однозначный, легче вносить правки. Хорошо структурированный, согласен. А вот этот плохо структурирован? function FindAnAnswer: Boolean; var X, Y, Z, Count: Integer; label LEnd; begin Result := False; Count := SomeConstant; for X := 1 to Count do for Y := 1 to Count do for Z := 1 to Count do if ... { some condition holds on X, Y, and Z } then begin Result := True; goto LEnd; end; LEnd: end; Цитата s-mike @ можно применить inline. В новых дельфях это уже есть. Ну только если выше D6. Но зачем на нее переходить? |
Сообщ.
#92
,
|
|
|
Убогий недоязык, так как 1) слишком verbose, 2) его break не позволяет задать уровень вложенности, что можно сделать даже в убогоньком недоязычке PHP (кстати, вложенность цикла всегда известна на этапе компиляции), 3) его for способен лишь крутить счетчик в арифметической поргрессии с шагом +1 или -1. Этого мало, учитывая то, что нельзя задать дополнительное условие выхода из цикла. Поэтому пришлось извратиться с while. 4) наконец, удобная штука -- тернарный оператор ?: отсутствует напрочь. Поэтому даже простое вычисление с условием нельзя задать одним выражением, надо бить на if ... then ... else.
И еще: 5) единственным воркараундом на многоуровневый break является таки goto. За сей аргументированный ответ можешь проставить еще один минус. Мне не жаль. |
Сообщ.
#93
,
|
|
|
Цитата Демо @ А вот этот плохо структурирован? Плохо. Я бы сказал, что совсем не структурирован. Нарисуй блок-схему. |
Сообщ.
#94
,
|
|
|
Кстати, смайк, потрудись объяснить, при каком монахе здесь Windows/Linux? Мы пока что _языки_ обсуждаем, независимо от их реализаций.
|
Сообщ.
#95
,
|
|
|
Цитата Mechanic @ Плохо. Я бы сказал, что совсем не структурирован. Нарисуй блок-схему. Так он точно так же структурирован, как и у тебя. За исключением GOTO. Добавлено Цитата Ho Im @ Убогий недоязык Ты давно отыскивал ошибки в своей программе из-за несоответсвия типов, например? Знаю я программеров, которые из-за нестрогости и неструктурированности языка пишут программы как попало. отладка занимает времени больше, чем написание кода раз в 20. |
Сообщ.
#96
,
|
|
|
Цитата Ho Im @ Кстати, смайк, потрудись объяснить, при каком монахе здесь Windows/Linux? Мы пока что _языки_ обсуждаем, независимо от их реализаций. А я о них вспоминал? Твои доводы - смешны. Ты считаешь недостатком языка то, что нельзя сделать что-то так, как в другом языке. А смысл делать все одинаково во всех языках? Тогда ни у одного из них не было бы своих преимуществ и недостатков. |
Сообщ.
#97
,
|
|
|
Цитата А я о них вспоминал? В статистике рейтинга. Коль ставишь минус, то хоть причину придумай нормальную. Цитата Ты считаешь недостатком языка то, что нельзя сделать что-то так, как в другом языке. Не "как в других", а в принципе. Это разные вещи. Цитата Знаю я программеров, которые из-за нестрогости и неструктурированности языка пишут программы как попало. Структурированные по-настоящему языки позволяют обойтись без goto. |
Сообщ.
#98
,
|
|
|
Демо, это мелкий пример потипу "Hello world", а если код строк этак на XXX тысяч?
Да еще и подобных стуктур дофига? Ну и будеш ты прыгать по своим меткам попусту теряя время. Хотя я программирование забросил, но вспоминается подобный случай, когда по молодости и наивности начал юзать goto там, где можно было обойтсь условиями и циклами. О чем через неделю написания кода горько об этом пожалел. |
Сообщ.
#99
,
|
|
|
Цитата Букер @ Да еще и подобных стуктур дофига? Ну и будеш ты прыгать по своим меткам попусту теряя время. Хотя я программирование забросил, но вспоминается подобный случай, когда по молодости и наивности начал юзать goto там, где можно было обойтсь условиями и циклами. О чем через неделю написания кода горько об этом пожалел. Ну так сколько можно раз повторять то, что использовать соответствующие возможности языка нужно там, где это действительно оптимально. Кто говорит, что надо заменить условные ветвления и функции оператором GOTO? В приведенном примере НЕ НАДО усложнять простой и читаемый код излишними конструкциями. Повторю еще раз, что лично у меня ни разу не появлялась необходимость использовать тот же пресловутый оператор GOTO. И я не сторонник его использования. Использования без веских причин, коими я назову максимальную читабельность и простоту кода. Я лишь противник религиозного фанатизма без всяких причин и аргументов. Кто-то где-то кому-то сказал, кто-то где-то прочитал, что использовать GOTO - плохой стиль. НУ И ЧТО? В результате, не поняв, почему его вдруг нельзя стало использовать, целиком полагаясь на авторитеты("старших товарищей"), программисты вдруг становятся апологетами этих "проповедников", по-существу, ограничивая ширину инструментов, средств программирования. И это касается не только оператора GOTO. Я сам иногда за собой замечаю, что некоторое высказывание, даже доказанное(якобы) строго, довлеет над сознанием, и становится догмой. НО, иногда - вдруг(вот ведь какая оказия!), появляется другое доказательство, которое опровергает первое. Я к чему последний абзац написал? А к тому, что иногда для правильной оценки не хватает малого - знаний. Поэтому и не надо принимать все на веру и становиться догматиком, так как этому может быть только 2 причины: 1. Максимализм. 2. Закостенелость мышления. |
Сообщ.
#100
,
|
|
|
Цитата Ho Im @ В статистике рейтинга. Коль ставишь минус, то хоть причину придумай нормальную. Цитата Довольно показывать свою некомпетентность! Хоть одно слово о Windows покажи. Видно не там прочитал. Цитата Ho Im @ Не "как в других", а в принципе. Это разные вещи. "В принципе" в Дельфи возможно все то, что ты написал. И без goto можно обойтись. Так что оставьте, батенька, свои линуховские предубеждения. И повкуривай книги Вирта и Borland'овские RTFM. Разве можно спорить и пытаться что-то доказать, ну выучив матчасть? Демо, имхо goto остался в языках не как возможность языка, а скорее просто для обратной совместимости. |
Сообщ.
#101
,
|
|
|
Эт, предубеждения у меня кроссплатформеннее эмакса и программы Hello World :-) Так что не примешивай одно к другому.
|
Сообщ.
#102
,
|
|
|
Цитата Демо @ Вот именно - если конечно правильно расставлены try..finally А зачем мне замедлять работу процедуры поднятием исключений? Если у меня не выделятеся память и ресурсы для объектов? GOTO - прямой и самый быстрый переход. Нахрена мне еще время тратить на исключения? Ну вот скажи? Ради религии? Тогда В САД такую религию и религиозных деятелей. Причем тут время? В примере со вложенными циклами подразумевается большоее кол-во итераций - и исходя из этого дополнительная проверка условия выхода становится нежелательной (помимо некрасивости такого решения). А время, потраченное на обработку исключения и пр. - по сравнению с общим временем выполнения итераций - ничтожно. И вообще не всегда исключения в языках реализованы так, как вы похоже думаете. Цитата BugHunter @ а тут всё зависит от того, что за условие. Если оно простое, то его лучше разбить на несколько, используя при этом continue. Если оно сложное, то можно вообще выделить этот обход по циклам в ОТДЕЛЬНУЮ ФУНКЦИЮ и делать из неё return по условию. RETURN - что может быть красивее? Красивее? Вообще то красиво, когда точка возврата одна. Цитата Демо @ Кто-то где-то кому-то сказал, кто-то где-то прочитал, что использовать GOTO - плохой стиль. НУ И ЧТО? В результате, не поняв, почему его вдруг нельзя стало использовать, целиком полагаясь на авторитеты("старших товарищей"), программисты вдруг становятся апологетами этих "проповедников", по-существу, ограничивая ширину инструментов, средств программирования. И это касается не только оператора GOTO. Хорош goto или плох... но тем не менее он нарушает принципы структурного программирования и это факт, не зависящий ни от проповедников, ни от кого бы то ни было... А самому мне все равно - в Java goto просто нет. И исключения - мне не кажутся чем то страшным. Упреждая скажу - всякую чушь насчет недоязыка и пр. комментировать не собираюсь. |
Сообщ.
#103
,
|
|
|
Цитата Демо @ Ну только если выше D6. Но зачем на нее переходить? По моему это естественно Помимо новых возможностей и поддержки новых версий ОС (новыми компонентами, изменениями в VCL/RTL) мы получаем еще более продвинутую и удобную среду (особенно в Д2006 ) и техническую поддержку. Версии 5 и ниже уже давно никто не поддерживает и не продает. |
Сообщ.
#104
,
|
|
|
Цитата Хоть одно слово о Windows покажи. Видно не там прочитал. Каюсь, текстовый браузер не показал рамок таблицы, а выравнивание по центру -- получилось с виду, как будто первый абзац предпоследнего (по хронологии) минуса приходится еще на последний. |
Сообщ.
#105
,
|
|
|
"Ни в коем случае не использовать GOTO, лучше его вообще отменить" - это лозунг ортодоксального структурного программирования. Использовать RETURN где-либо, кроме как перед завершающим функцию END'ом там такой же грех, если не больший чем использовать GOTO.
Кстати в оригинальном варианте языка Паскаль, предложенном Н.Виртом оператора RETURN вообще не было, вместо него использовался GOTO. Также не было операторов BREAK, EXIT, HALT и других, которые нарушали стройную структуру программы (для GOTO было сделано исключение). |
Сообщ.
#106
,
|
|
|
return в Paskal???? А с какой версии?
|
Сообщ.
#107
,
|
|
|
Цитата 02077461 @ return в Paskal???? А с какой версии? По-Pascal'евски Return звучит как Exit. |
Сообщ.
#108
,
|
|
|
Я Паскалем давно не пользовался, так что напутал. Действительно, не Return ..., а Result := ...; Exit. Или FuncName := ...; Exit.
|
Сообщ.
#109
,
|
|
|
В последующих языках Никлауса Вирта вернулся return.
|
Сообщ.
#110
,
|
|
|
Вернулся return — надо записать. Хорошо сказано.
|
Сообщ.
#111
,
|
|
|
Цитата amk @ Также не было операторов BREAK, EXIT, HALT и других, которые нарушали стройную структуру программы отличие break/exit/continue (halt - лишний в этом списке) от goto в том, что для этих операторов однозначно определена метка перехода. Если мы встретим в коде Exit, то мы сразу поймем, что тут заканчивает процедура. или цикл(break) или итерация цикла. В случае же goto - вообще ничего определенного сказать нельзя. Этим он и плох.... |
Сообщ.
#112
,
|
|
|
Пробелма была не в этом. goto не вписывается в методологию структурного программирования. Программу с ними практически невозможно записать в виде блок-схемы. В этом то вся суть. А в плюсах еще деструкторы и пр...
|
Сообщ.
#113
,
|
|
|
Цитата Evil J @ Пробелма была не в этом. goto не вписывается в методологию структурного программирования. Программу с ними практически невозможно записать в виде блок-схемы. В этом то вся суть. А в плюсах еще деструкторы и пр... почему нельзя ? по сути это же условие с переходом. в чем отличие ? |
Сообщ.
#114
,
|
|
|
Если вспомнили про GoTo Значит он кому-то нужен.
|
Сообщ.
#115
,
|
|
|
Вставлю свой комментарий
Приходилось мне реализовывать функцию... К сожалению, там такой алгоритм, который я сумел решить только через рекурсию. Ибо слаб в теории групп симметрии кристаллов, а американцы, которые уже 20 лет решают эту задачу, вообще признали ее нерешаемой на имеющихся компьютерных мощностях и решили нафиг приближенно. Так вот, глубина этой рекурсии - около 5 миллиардов вызовов. Естественно, стэк на этом деле загибается подчистую. Ну и пришлось мне реализовывать рекурсию через динамическую память (со свапом, естественно, на 90 Гб), и естественно, через goto. Не знаю, честно говоря, способа, вручную реализовать рекурсию без использования goto. Насчет оптимизации... Честно говоря, в таких проектах на удобство порграммирования смотрят непонимающе, как на средство для дебилов, которые не умеют думать, как компьютер. Ибо даже лишнее обращение к переменной - это лишний такт процессора (и памяти). А когда кусок кода выполняется на протяжении работы программы несколько триллионов раз... То за такое по голове бьют. С другой стороны, подрабатываю в крупном проекте на С++. Тут, наоборот, все - для удобства программирования. Все пишется на языке постановки задач, объекты выделяются даже там, где вроде бы не нужны Иногда больше половины времени уходит на написание комментариев ))) И тут, конечно, goto приводит просто к непониманию Вот такие разны люди, вот такие разные проекты... |
Сообщ.
#116
,
|
|
|
Цитата SCINER @ почему нельзя ? по сути это же условие с переходом. в чем отличие ? Есть некие элементы блок-схемы, более широкие, чем базовые (ромдики и пр.). Ветвление, цикл и пр. Вот в них то все и упирается. Цитата SCINER @ по сути это же условие с переходом. в чем отличие ? Позволю напомнить, что goto - безусловный переход. |
Сообщ.
#117
,
|
|
|
Цитата Marbledore @ Вот такие разны люди, вот такие разные проекты... Я бы сказал, что цели у проектов разные. В коммерческих проектах, где надо осуществлять последующую поддержку кода, естественно, заботся о том, чтобы можно было с минимальными усилиями найти и исправить возникшую ошибку, т. е. навызывают единый стиль программирования, заставляют писать комментарии и т. д. В научных проектах все по-другому: любое исследование направлено на получение результата, поэтому люди науки пишут так... В общем, единожды увидев, больше не захочется. Да и Fortran, используемый в научных кругах, ИМХО никак не способствует хорошему стилю. |
Сообщ.
#118
,
|
|
|
Цитата Marbledore Ну и пришлось мне реализовывать рекурсию через динамическую память (со свапом, естественно, на 90 Гб), и естественно, через goto. Не знаю, честно говоря, способа, вручную реализовать рекурсию без использования goto. бу-га-га... рекурсия в целых 90гигов свапа через goto ака jmp? вроде бы само -каллбачные(self-callback) ака рекурсивные фун-кции в конечном итоге юзают CALL и RET.. типа {$APPTYPE CONSOLE} program test; procedure xren_evo_znaet(xz:integer ); begin xz:= xz + 1; writeln ('xren_evo_znaet: ', xz ); xren_evo_znaet (xz); end; begin xren_evo_znaet(0); end. хе.. доктор ватсон пришел за ней когда оно отсчитало до: xren_evo_znaet: 129466 xren_evo_znaet: 129467 xren_evo_znaet: 129468 xren_evo_znaet: 129469 xren_evo_znaet: 129470 |
Сообщ.
#119
,
|
|
|
Так ведь Marbledore написал, что ПРИШЛОСЬ делать в динамической памяти.
Я конечно не знаю, не пробовал, может где-нибудь в опциях компилятора и можно выставить stacksize=90G... |
Сообщ.
#120
,
|
|
|
Есть такая известная функция, пришедшая еще из RX Library, теперь перекочивавшая в JVCL. Она переводит числа в римскую систему счисления из десятичной.
function IntToRoman(Value: Longint): string; label A500, A400, A100, A90, A50, A40, A10, A9, A5, A4, A1; begin Result := ''; while Value >= 1000 do begin Dec(Value, 1000); Result := Result + 'M'; end; if Value < 900 then goto A500 else begin Dec(Value, 900); Result := Result + 'CM'; end; goto A90; A400: if Value < 400 then goto A100 else begin Dec(Value, 400); Result := Result + 'CD'; end; goto A90; A500: if Value < 500 then goto A400 else begin Dec(Value, 500); Result := Result + 'D'; end; A100: while Value >= 100 do begin Dec(Value, 100); Result := Result + 'C'; end; A90: if Value < 90 then goto A50 else begin Dec(Value, 90); Result := Result + 'XC'; end; goto A9; A40: if Value < 40 then goto A10 else begin Dec(Value, 40); Result := Result + 'XL'; end; goto A9; A50: if Value < 50 then goto A40 else begin Dec(Value, 50); Result := Result + 'L'; end; A10: while Value >= 10 do begin Dec(Value, 10); Result := Result + 'X'; end; A9: if Value < 9 then goto A5 else Result := Result + 'IX'; Exit; A4: if Value < 4 then goto A1 else Result := Result + 'IV'; Exit; A5: if Value < 5 then goto A4 else begin Dec(Value, 5); Result := Result + 'V'; end; goto A1; A1: while Value >= 1 do begin Dec(Value); Result := Result + 'I'; end; end; Правда ужасно? И это действительно так! Я легко переписал её в гораздо более удобоваримый вид: function IntToRoman(Value: Longint): string; type TRomanRec = record Str: string; Amount: Integer end; const Roman: array [1..13] of TRomanRec = ( (Str: 'M'; Amount: 1000), (Str: 'CM'; Amount: 900), (Str: 'D'; Amount: 500), (Str: 'CD'; Amount: 400), (Str: 'C'; Amount: 100), (Str: 'XC'; Amount: 90), (Str: 'L'; Amount: 50), (Str: 'XL'; Amount: 40), (Str: 'X'; Amount: 10), (Str: 'IX'; Amount: 9), (Str: 'V'; Amount: 5), (Str: 'IV'; Amount: 4), (Str: 'I'; Amount: 1) ); var R: TRomanRec; begin Result := ''; for R in Roman do while Value >= R.Amount do begin Result := Result + R.Str; Dec(Value, R.Amount); end; end; Правда так гораздо лучше? Вот вам и еще один гвоздь в гроб GOTO |
Сообщ.
#121
,
|
|
|
GoTo пришло из великого Фортрана! Засим все кто думает что Goto "пережиток..." отступники и подлежат сожжению на костре!
ЗЫ Мое высказывание прошу воспринимать шуткой. |
Сообщ.
#122
,
|
|
|
Цитата Smike @ Правда так гораздо лучше? Это и без такой большой переделки можно без всяких goto написать. Но исходный код работает на неоптимизирующих компиляторах несколько быстрее твоего. Да и оптимизация не слишком-то поможет. |
Сообщ.
#123
,
|
|
|
Использую goto до сих пор (в VB/PB/C/C++), и собираюсь использовать впредь. Комплексами, как Смайк, например, по этому поводу не страдаю.
У goto есть свое предназначение, и если им не злоупотреблять - получается весьма читаемый и оптимизированный код. Цитата Smike @ Правда ужасно? Кому как, знаешь ли... |
Сообщ.
#124
,
|
|
|
Цитата amk @ Но исходный код работает на неоптимизирующих компиляторах несколько быстрее твоего. Где бенчмарк? Вообще-то есть узкие места: - цикл for..in по записям (record) не больно эффективен, потому что копирует каждый раз запись в переменную. Если переписать цикл на индексы, будет немного быстрее, но не так красиво - можно еще сделать кое-какие оптимизации, например добавлять не по 1-2 знака в цикле, а сразу скопом. Целочисленным делением подсчитать, сколько нужно знаков, установить длину строки и занести данные копированием области памяти. Но нужно ли? Чрезмерная оптимизация в отнюдь не самых узких местах тоже вредна. Цитата B.V. @ Комплексами, как Смайк, например, по этому поводу не страдаю. Причем тут комплексы? Я лишь подтвердил, что это уродливо, не универсально, неудобно, нелогично и некрасиво. И не соответствует стандартам структурного программирования. А ты только кидаешься штампами вместо того чтобы показать код и таким образом аргументировать свои тезисы. Цитата У goto есть свое предназначение, и если им не злоупотреблять - получается весьма читаемый и оптимизированный код. Можно пример подобного кода? Или мой первый фрагмент по твоему более читаемый и простой? |
Сообщ.
#125
,
|
|
|
Цитата Есть такая известная функция, пришедшая еще из RX Library, теперь перекочивавшая в JVCL. Она переводит числа в римскую систему счисления из десятичной. охоспади, застрелил бы "аффтора", чесслово. |
Сообщ.
#126
,
|
|
|
Цитата Smike @ Причем тут комплексы? При том, что твой пример мне не кажется "уродливым". Цитата Smike @ Я лишь подтвердил Не подтвердил. Цитата Smike @ А ты только кидаешься штампами вместо того чтобы показать код и таким образом аргументировать свои тезисы. Ничем я не кидаюсь, это раз. Аргументировать бессмысленно, так как у нас противоположные взгляды на один и тот же код, это два. |
Сообщ.
#127
,
|
|
|
Цитата Бобёр @ охоспади, застрелил бы "аффтора", чесслово. Такое впечатление, что она переведена с какого-то раннего бейсика для спектрума. А переводивший решил не морочить голову переписыванием её на нормальный язык. А зря, времени на писанину не пришлось бы столько тратить Цитата B.V. @ При том, что твой пример мне не кажется "уродливым". Обоснуй. В моем примере 3 строчки кода (не считая управляющих конструкций и данных). Разобраться в них элементарно просто. Расширить - раз плюнуть, наращиваем только массив. А в коде с goto? Да там с пивом и за день можно не разобраться, от чего он вдруг стал глючить. Вопрос в лоб: какой фрагмент кода лучше? С GOTO или без? Дождемся от тебя примеров "читаемого и оптимизированного кода с GOTO"? Цитата B.V. @ Ничем я не кидаюсь, это раз. А это что: Цитата B.V. @ Не подтвердил. ? Цитата B.V. @ Аргументировать бессмысленно, так как у нас противоположные взгляды на один и тот же код, это два. Аргумент, если это действительно аргумент, способен убедить любого. А если это фразы типа "венда-слюникс ацтой", "не убедил", "не подтвердил", "о вкусах не спорят", то конечно доказать ничего не удастся. |
Сообщ.
#128
,
|
|
|
ну, вариант с goto непонятно для кого писался, поддерживать такое я не взялся бы.
во-первых: процедура не умещается на экран, во-вторых: странные ветвления, её спасает только то, что спецификация римской записи не производится каждые полгода |
Сообщ.
#129
,
|
|
|
Эту функцию поддерживать уже не нужно. И читать даже не обязательно. Один раз запихнул в библиотекуу и пользуйся.
Или вы думаете, что на запись римских чисел время от времени новые стандарты выходят? А код и в оригинале не так эффективен, каким мог бы быть. Совершенно не учитывается возможная встречаемость этих чисел. Я бы в начало еще строк несколько добавил, чтобы сперва диапазон определить, хотя бы до степени десятки. И вполне может быть что он именно переведен либо действительно с бейсика или даже с фортрана. И тот кто переводил здраво рассудил, что от добра добра не ищут, и не стал заморачиваться тем, как ему пару часов убить на то, чтобы от goto избавиться, а по-тупому переписал все минут за пятнадцать как было. Может только метки поменял, чтобы самому понятнее было, хотя они и в оригинале скорее всего такими были. Цитата Smike @ А как я его тебе сделаю? У меня паскаля уже лет пятнадцать, как не стояло. Можешь сам попробовать перевести с миллион так чисел "уродливым" алгоритмом и своим и посмотреть какой быстрее Где бенчмарк? |
Сообщ.
#130
,
|
|
|
Цитата amk @ пару часов Я перевел минут за 10. Ну может за 20. Цитата amk @ а по-тупому переписал все минут за пятнадцать как было Сомневаюсь. Набрать такой текстик за такое время сложновато. Даже копипастом. А потом проверить, отладить. Ужас. Цитата amk @ Можешь сам попробовать перевести с миллион так чисел "уродливым" алгоритмом и своим и посмотреть какой быстрее Это мысль! |
Сообщ.
#131
,
|
|
|
Провел бенчмарк. Да, функция без GOTO работает дольше, примерно на 30%. Но я не долго думая написал более оптимизированный вариант:
function IntToRomanOptimized(Value: Longint): string; type TRomanRec = record Symbol: Char; Amount: Word; end; const // Отмеченные "+" элементы используются для уменьшения предыдущих значений, // все они на нечетных местах Roman: array [1..7] of TRomanRec = ( (Symbol: 'M'; Amount: 1000), // 1 (Symbol: 'D'; Amount: 500), // 2 (Symbol: 'C'; Amount: 100), // 3 + (Symbol: 'L'; Amount: 50), // 4 (Symbol: 'X'; Amount: 10), // 5 + (Symbol: 'V'; Amount: 5), // 6 (Symbol: 'I'; Amount: 1) // 7 + ); var I: Integer; R: TRomanRec; begin Result := ''; for I := Low(Roman) to High(Roman) do begin R := Roman[I]; if Value >= R.Amount then begin Result := Result + StringOfChar(R.Symbol, Value div R.Amount); Dec(Value, Value div R.Amount * R.Amount); end else if R.Amount > 1 then with Roman[I + Ord(Odd(I)) + 1] do if Value >= R.Amount - Amount then begin Result := Result + Symbol + R.Symbol; Dec(Value, R.Amount - Amount); end; end; end; Так вот, этот вариант работает быстрее в арифметической прогрессии На 100 000 итераций он быстрее в 2 раза, чем с GOTO На 200 000 - в 3 раза На 300 000 - в 4 раза На 400 000 - в 5 раз ... На 1 000 000 - в 13 раз! В структурном программировании сила. GOTO - в могилу! Добавлено ЗЫ: под итерациями подразумевается преобразование в римскую систему счисления чисел от единицы до количества итераций отсюда и скорость, потому что числа становятся все время длиннее. |
Сообщ.
#132
,
|
|
|
погодь.. а твоя ускоренная процедура точно работает правильно?.. какое то подозрительное ускорение то.
и опять таки, супротивники там чего то про неоптимизируюищие компиляторы говорили.. только вот где их взять то, неоптимизирующие? |
Сообщ.
#133
,
|
|
|
Ну, несколько тестовых примеров прогнал - полет нормальный. Сейчас попробую еще в файл вывод сделать и сравнить.
Кстати, оптимизация была отключена. А ускорение в первую очередь за счет того что символы добавляются StringOfChar, она работает в разы быстрее, чем цикл, так как написана на асме. |
Сообщ.
#134
,
|
|
|
Цитата Smike @ Сейчас попробую еще в файл вывод сделать и сравнить. зачем в файл.. просто результаты выполнения каждой функции сохраняй гденить. А потом програмно и сравнивай - ищи отличия. Добавлено Цитата Smike @ Кстати, оптимизация была отключена. зачем ? |
Сообщ.
#135
,
|
|
|
Ага, есть ошибка. Но небольшая. И её исправление ощутимо не влияет на скорость.
function IntToRomanOptimized(Value: Longint): string; type TRomanRec = record Symbol: Char; Amount: Word; end; const // Отмеченные "+" элементы используются для уменьшения предыдущих значений, // все они на нечетных местах Roman: array [1..7] of TRomanRec = ( (Symbol: 'M'; Amount: 1000), // 1 (Symbol: 'D'; Amount: 500), // 2 (Symbol: 'C'; Amount: 100), // 3 + (Symbol: 'L'; Amount: 50), // 4 (Symbol: 'X'; Amount: 10), // 5 + (Symbol: 'V'; Amount: 5), // 6 (Symbol: 'I'; Amount: 1) // 7 + ); var I: Integer; R: TRomanRec; begin Result := ''; for I := Low(Roman) to High(Roman) do begin R := Roman[I]; if Value >= R.Amount then begin Result := Result + StringOfChar(R.Symbol, Value div R.Amount); Dec(Value, Value div R.Amount * R.Amount); end; if R.Amount > 1 then with Roman[I + Ord(Odd(I)) + 1] do if Value >= R.Amount - Amount then begin Result := Result + Symbol + R.Symbol; Dec(Value, R.Amount - Amount); end; end; end; Добавлено Сравнивал на числах до миллиона. Файлы выходят идентичные. Добавлено Цитата LuckLess @ зачем ? Для отладки. Сейчас попробую с оптимизацией, в релизной конфигурации. Добавлено Цитата LuckLess @ А потом програмно и сравнивай - ищи отличия. Так неудобно. А я сохранил 3 текстовых файлика, потом скормил их Total Commander и сразу увидел различия, после чего быстро нашел и исправил ошибку. |
Сообщ.
#136
,
|
|
|
хм.. на вид ошибка небольшая, но алгоритмически очень важная
|
Сообщ.
#137
,
|
|
|
Скомпилил с оптимизацией - разницы практически нет. У оптимизированного варианта чуть-чуть больше преимущество
|
Сообщ.
#138
,
|
|
|
Smike
А ты уверен, что твоя программа правильно в римское представление числа выводит? Как, например, она выписывает числа 4, 9, 14, 99? Кстати, если кто не знает, число 99 можно написать не только как 'XCIX', но и как и как 'IC', а 8 как 'IIX', а не только 'VIII'. Но это не совсем стандартные варианты, особенно с восьмеркой. |
Сообщ.
#139
,
|
|
|
Цитата amk @ Кстати, если кто не знает, число 99 можно написать не только как 'XCIX', но и как и как 'IC', а 8 как 'IIX', а не только 'VIII'. Известно, но также известно, что такой способ записи не соответствует каноничным правилам и не рекомендуется. Да и не один из вышеприведенных алгоритмов этого не реализует. Можно конечно сделать, но это будет нерационально, так как придется вместо with Roman[I + Ord(Odd(I)) + 1] do Прогонять по циклу через все цифры, меньше текущей. Цитата amk @ А ты уверен, что твоя программа правильно в римское представление числа выводит? Последний вариант (пост №136) работает абсолютно идентично варианту с GOTO и с 2 циклами на числах до 1 000 000. Цитата amk @ 4, 9, 14, 99 IV, IX, XIV, XCIX |
Сообщ.
#140
,
|
|
|
XCIX == IC ?
|
Сообщ.
#141
,
|
|
|
Возможно когда-то (в Древнем Риме) использовались оба обозначения, но сейчас общепринятым является только левый
В принципе и VC можно понимать как 95, но так не пишут (пишут XCV) |