Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.22.51.241] |
|
Страницы: (32) « Первая ... 7 8 [9] 10 11 ... 31 32 ( Перейти к последнему сообщению ) |
Сообщ.
#121
,
|
|
|
Цитата JoeUser @ Как-то, так: ... Но все равно - это не тепичный алгоритм для GOTO, нет возвратов в ветви предыдущих вычислений. Много времени прошло с момента написания этого "робота", помницца и не все реализовано было (как-то, зависание на время формирования ответа серверной частью, возвраты от пустого ответа, на повторный прием ответа и пр.). Тем не менее - в том что я написал, ИМХО, "чтение" кода и сопоставление с блок-схемой проще, нежели в твоих разбиениях на области в виде функций. Без паллитры и карандаша с бумагой не разбересся. У меня "что видно, то и написано". Это в твоих переходах без поллитры не разберёшься. =) Qraizer правильно сказал про КА. type StateFn func() StateFn func Start() StateFn { if !flagPhase { return Exec } if flagNeedSend { SendRequest() return nil } if flagWait { return nil } if flagNeedExec { return Exec } if flagNecessity { CreateRequest() CreateWaitingFlag() return nil } if flagWaitReply { AcceptReply() if !accepted { return nil } if reply { return SO } return ExecFlag } if !recieveInfExists || recieveInfOverdue { CreateNecessityFlag() return Exec } if recieveInfOverdueFinish { return SO } Accept() if updates { return ExecFlag } return nil } func SO() StateFn { SendSORequest() CreateFlag() return nil } func ExecFlag() StateFn { // Create exec flag return Exec } func Exec() StateFn { if !execPhase { return nil } if flagBuilding { CreateRequest() return Start } if flagExec { Execute() } return nil } func main() { for f := Start(); f != nil; f = f() { } } |
Сообщ.
#122
,
|
|
|
С философской точки зрения, метки нужны там, где отсутствует структурное прогарммирование, например, на ассемблере, если код не выносится в функции, а пишется одной портянкой, то вызов функции заменяется goto, который вырождается в short jump или long jump. Это экономит и стек, так как никакие регистры не бэкапятся (выталкиваются) в стек и заново не перезагружаются данными. Причем, такое применение может быть как оптимизацией по скорости, так и по объему кода.
И совершенно верно замечено, что рефакторить такой код геморно. Так что, опять же, с философской точки зрения, могу предположить, что в Си goto появилась как следствие "понижения" уровня языка до ассемблерного уровня, когда можно кодить "байт в байт", используя язык высокого уровня. Чем, например, был весьма хорош Turbo C 2.0 (и компилил тоже пушечно). И все эти техники неиспользования промежуточных переменных типа: { i = f(x); return i; } лучше переписать как: { return f(x); } и еще масса всяческих олдскульных штучек... Так как в первом случае значение функции, которое во времена i8086 обычно вычислялось только в AX(AH,AL), сначала пересылается куда-то в память, а потом возвращается обратно в AX (где по факту уже присутствует), и только потом вызывается RET... А сейчас и регистры стали внутри проца равноправнее, и винты толще, так что оптимизация by size тоже уже на грани удаления из компилятора напрочь... Сейчас никто (то есть, я в частности) asm не рефакторит, поэтому и смысла в goto в высокоуровневых языках уже нет. Но его отсутствие нарушит стандарт языка. А несовместимость со стандартом гораздо страшнее. Поэтому goto по-прежнему будет присутствовать, и его по-прежнему мало кто будет использовать, и это будет тоже очень правильно. И оптимизация by size тоже будет живее всех живых. |
Сообщ.
#123
,
|
|
|
Цитата p1qb0d @ А я (см. первое сообщение темы) бы сказал, что вот бывает, что надо смотаться из двойного или тройного цикла, и тогда приходится городить лишний огород из переменных и т.п., либо просто сделать goto на выход и всё. Так что зависимость от ассемблера сомнительна. Так что, опять же, с философской точки зрения, могу предположить, что в Си goto появилась как следствие "понижения" уровня языка до ассемблерного уровня, когда можно кодить "байт в байт", используя язык высокого уровня. |
Сообщ.
#124
,
|
|
|
Цитата Славян @ А я (см. первое сообщение темы) бы сказал, что вот бывает, что надо смотаться из двойного или тройного цикла, и тогда приходится городить лишний огород из переменных и т.п., либо просто сделать goto на выход и всё. Так что зависимость от ассемблера сомнительна. Это называется костыль и лень. Когда лень писать хороший качественный код, иногда люди начинаются писать говнокод. Вот как раз это тот описываемый тобой случай - говнокода. Что мешает тебе не городить 3 вложеных цикла? А обойтись дополнительной функцией, которая сделает твой код более читабельным, понятным и сопровождаемым? Добавлено Кстати а еще можно все писать в одной функции main, а нахрена нам другие функции? есть же волшебный goto, а блоки можно отделять коментариями, например както так: /*******************************************************************************/ ... /*******************************************************************************/ ... /*******************************************************************************/ |
Сообщ.
#125
,
|
|
|
Цитата KILLER @ Что мешает тебе не городить 3 вложеных цикла? А обойтись дополнительной функцией, которая сделает твой код более читабельным, понятным и сопровождаемым? Это религия какая-то. Запросто может быть так, что три цикла гораздо читабельней, чем огород с вызовом функций. |
Сообщ.
#126
,
|
|
|
Цитата OpenGL @ Это религия какая-то. Запросто может быть так, что три цикла гораздо читабельней, чем огород с вызовом функций. Цитата KILLER @ Циклы бывают большие и сложные. Работают со многими данными. Пересылать весь их огород в функцию - и есть костыль, непонятно для чего. Что мешает тебе не городить 3 вложеных цикла? |
Сообщ.
#127
,
|
|
|
Цитата Славян @ Ладно выйти, а если войти? ... вот бывает, что надо смотаться из двойного или тройного цикла, и тогда приходится городить лишний огород из переменных и т.п., ... |
Сообщ.
#128
,
|
|
|
Цитата Qraizer @ Мне ни разу такого не попадалось. Но так, сходу, и проблем со входом при наличии goto не вижу. А без него - точно такой же гемор с излишними плясками с переменными да условиями. Ладно выйти, а если войти? |
Сообщ.
#129
,
|
|
|
Цитата OpenGL @ Это религия какая-то. Запросто может быть так, что три цикла гораздо читабельней, чем огород с вызовом функций. Это не религия, 2 вложеных цикла - еще терпимо и нормально, а три и более - запутывают читающего код, а если там еще и goto, то и вовсе сбивает с толку. Если тебе так нужно запилить три цикла вложеных с возможностью выхода из третьего, оформи их в отдельную функцию/метод и ливай по return из них. Какие проблемы? Я видел функции по 5 тысяч строк кода - это читать не возможно в принципе, там и по три вложеных цикла было и по четыре. Как по мне, лучше сделать несколько мелких функций, чтобы было понятно и прозрачно, чем шаманить трехэтажные циклы. Добавлено Цитата Славян @ Циклы бывают большие и сложные. Работают со многими данными. Пересылать весь их огород в функцию - и есть костыль, непонятно для чего. Приведи пример такого костыля плз, я хочу посмотреть. Добавлено Цитата Qraizer @ Ладно выйти, а если войти? Зачем? Добавлено Вообще писать можно как угодно и что угодно. Ну вот возьмет чел, напишет свою прогу в 100 000 строк тупо в функции Main, и она будет работать. Что он неверно сделал? Да все он верно сделал. Какое вам дело до того как он пишет? Религия чтоль не позволяет 100 000 строк в функции main запилить? Вот так вот и выглядят ваши аргументы со стороны. А на деле, эта религия мне помогает избежать кучи ошибок, и когда я открываю свой код через год - то я сходу понимаю что там написано. В отличии, если бы там были трехэтажные циклы и метки - такой код открываешь через месяц и начинаешь репу чесать и заного изучать что же я там имел ввиду - делая такие нетривиальные телодвижения. Добавлено Плюс ко всему, есть мнение, что чем больше у тебя будет осознанных слов в проге - тем легче она будет восприниматься и читаться. В случае с трехэтажными циклами - их меньше, и можно легко запутаться, никто не будет называть счетчик больше 5-6 букв, особенно если он часто используется в теле цикла. С функциями эта проблема решаема, т.к. мало кто называет функции в 1-2 буквы. И программа становится более читабельной. |
Сообщ.
#130
,
|
|
|
Цитата KILLER @ Пример с тремя сложными циклами со многими переменными, переписанный на "вызов функции с табуном аргументов"=костыль?.. Приведи пример такого костыля плз, я хочу посмотреть. |
Сообщ.
#131
,
|
|
|
Цитата Славян @ Пример с тремя сложными циклами со многими переменными, переписанный на "вызов функции с табуном аргументов"=костыль?.. Ну по твоему видимо да: Цитата Славян @ Пересылать весь их огород в функцию - и есть костыль Ок, приведи пример некостыля Цитата Славян @ с тремя сложными циклами со многими переменными Я просто хочу посмотреть, если я туда вставлю вызов функции - действительно хуже станет или нет. |
Сообщ.
#132
,
|
|
|
Цитата KILLER @ Допустим так:Ок, приведи пример некостыля... Я просто хочу посмотреть, если я туда вставлю вызов функции - действительно хуже станет или нет. int GetBestChessPos( void ) { int count1[20]; float terVer[8][8], pokaz; char superVertical[8]; ... // заполняем все массивы для работы // ... // ниже = расчёт for( int row=0; row<8; row++) for( int col=colA; col<colH; col++) { pokaz += ...; if( ... ) terVer[2][5] *= ...; // испытываем воздействие if( count1[15] + (int)pow(terVer[3][4] + terVer[2][5], pokaz) > count1[2] ) // опасное положение! if( superVertical[2]<3 ) // мат нам грядёт goto LBL_matPrideHanaBude; } ... LBL_matPrideHanaBude: // попытка рискнуть: ... } |
Сообщ.
#133
,
|
|
|
Цитата KILLER @ Если тебе так нужно запилить три цикла вложеных с возможностью выхода из третьего, оформи их в отдельную функцию/метод и ливай по return из них. Это если из трёх сразу. А если из двух? Вытаскивать эти два цикла в функцию не всегда целесообразно. |
Сообщ.
#134
,
|
|
|
Цитата OpenGL @ Это если из трёх сразу. А если из двух? Вытаскивать эти два цикла в функцию не всегда целесообразно. Заведи флаг выхода. В чем проблема? Цитата Славян @ Допустим так: Что тебе мешает эти два цикла обернуть в отдельную функцию? |
Сообщ.
#135
,
|
|
|
Цитата KILLER @ Мешает то, что эти два цикла и так по сути оформлены в функцию. Плюс вагон переменных, кои засылать в функцию равносильно заново написать примерно такую же. Что тебе мешает эти два цикла обернуть в отдельную функцию? |