Форум «Всё о Паскале» _ Общие вопросы разработки программ _ Как оформлять тексты программ
Автор: Altair 11.12.2008 13:30
Совершенно случайно наткнулся на http://zed.karelia.ru/go.to/for.students/coding.rules/rules для студентов по оформлению текстов программ.
Не со всеми пунктами однозначно согласен, но думаю развивать культуру программирования необходимо.
Автор: andriano 12.12.2008 22:50
Категорически не согласен с пунктом 10 (не совсем согласен и с некоторыми из предыдущих, но ключевой - именно 10-й) Допустим, нам нужно реализовать алгоритм из 6-8 операций, не так уж много, правда? Автор совершенно сраведливо отмечает, что каждое действие, допускающее проверку, надо проверять. Сам он предлагает такой вариант (для простоты - 4 условия):
begin if not condition1 then begin break end; if not condition2 then begin break end; if not condition3 then begin break end; if not condition4 then begin break end; DoSomething; end;
мой вариант:
begin if not condition1 then begin if not condition2 then begin if not condition3 then begin if not condition4 then begin DoSomething; end; end; end; end; end;
Если в варианте автора для того, чтобы понять, что DoSomething выполняется только при выполнении всех условий, необходимо просмотреть процедуру ЦЕЛИКОМ, то у меня это видно СРАЗУ.
Отсюда вытекают и несколько иные оценки допустимой глубины вложенности (у автора - не более 3, что при указанном мною подходе никак не применимо, а также требованием 8 позиций на каждый уровень вложенности (что вытекает из предыдущего). Я использую 2. Отсюда косвенно вытекает и сомнительность целесообразности применения символа табуляции при недопустммости пробелов, т.к. обычно вьюеры настроены именно на 8 и при рекомендуемой автором ширине экрана 80 символов уже при глубине вложенности 10 ни одного символа на экране уместить нельзя.
Автор: Lapp 12.12.2008 23:06
На мой взгляд, чем короче, тем лучше:
begin if not (condition1 or condition2 or condition3 or condition4) then DoSomething; end;
Автор: volvo 12.12.2008 23:15
Lapp, очень опасный код на самом деле: где гарантия, что вычисление Condition1 произойдет раньше, чем вычисление Condition2 (если вообще произойдет)? А это может иметь значение...
Автор: Lapp 12.12.2008 23:18
Цитата(volvo @ 12.12.2008 23:15)
где гарантия, что вычисление Condition1 произойдет раньше, чем вычисление Condition2
Гарантия - в соответствующих опциях компилятора.
Автор: volvo 12.12.2008 23:24
Нет никакой гарантии... Паскаль не определяет порядок вычисления выражений... Ты можешь гарантировать только, что все выражения вычислятся (если не выбрана "короткая схема"), но вот в каком порядке - вопрос... С другой стороны, "короткая схема" вычисляет выражение всегда слева направо, но, возможно, будут вычислены не все его составляющие... http://zeus.sai.msu.ru:7000/programming/bp70_lr/lr23.shtml#9
P.S. Я правильно понимаю, что Condition1, Condition2 и так далее - это не переменные типа Boolean, а, скажем, функции или вычисляемые выражения? В случае с переменными все просто...
Автор: andriano 12.12.2008 23:44
Lapp, я надеялся, что наличие "лишних" begin/end наведут на мысль, что condition - это не один оператор, а несколько. Примерно так:
begin result := MyFunc1; if result = 0 then begin result := MyFunc2; if result = 0 then begin ... DoSomething1; DoSomething2; ... end else begin DoError(2,result); WriteError(2); end; end else begin DoError(1result); WriteError(1); end; end;
Увы, не вышло.
Автор: Lapp 12.12.2008 23:56
Цитата(volvo @ 12.12.2008 23:24)
"короткая схема" вычисляет выражение всегда слева направо, но, возможно, будут вычислены не все его составляющие...
Именно, короткая схема (то есть то же самое, что && и || в С). Меня всегда восхищало, что, при хорошо продуманной схеме, она практически всегда (за исключением ооочень редких случаев) очень органично встраивается в алгоритм. Фактически, это именно ТО, что привел adriano - тоже вычисляются не все составляющие.
Помню, когда мне нужно было придумать пример (реальный, ненадуманный) необходимости использования "длинной" схемы, пришлось немало потрудиться..
Цитата(andriano @ 12.12.2008 23:44)
Lapp, я надеялся, что наличие "лишних" begin/end наведут на мысль, что condition - это не один оператор, а несколько. ...Увы, не вышло.
Не навело . Еще хорошо, что volvo уточнил про переменные..
Но, опять же, во многих случаях имеет смысл организовать Булевы функции, чтоб всю логику собрать компактно в одном месте.
Автор: andriano 13.12.2008 10:49
Цитата(Lapp @ 12.12.2008 23:56)
Помню, когда мне нужно было придумать пример (реальный, ненадуманный) необходимости использования "длинной" схемы, пришлось немало потрудиться..
По этому поводу хочу сразу заметить, что в расчете на короткую схему следовало бы писать так:
begin if not (condition1 or condition2 or condition3 or condition4 or DoSomething) then; end;
Т.е. принципиально с пустым телом. Что наводит на мысль о введении в ЯВУ новой высокоуровневой конструкции с гарантированным условным выполнением в заданном порядке вне зависимости от компилятоа и его настроек.
Цитата
Не навело . Еще хорошо, что volvo уточнил про переменные..
Спасибо, я уже заметил. Но и вторая итерация также оказалась недостаточно полной. Подправил.
Цитата
Но, опять же, во многих случаях имеет смысл организовать Булевы функции, чтоб всю логику собрать компактно в одном месте.
В данном случае речь идет именно о последовательном выполнении некоторой последовательности инструкций с проверками перед переходом к следующему шагу. Я часто пользуюсь локальными булевыми переменными, но считаю, что в данном случае (линейный алгоритм с роверками) это нецелесообразно.
Собственно, речь шла о записи алгоритмов. И на примере рекомендаций по ссылке я еще раз убедился, что break/exit - "вредные" операторы. А еще одно наблюдение - одни предпочтения неизбежно влекут за собой другие. Так, отказ о exit в подобных конструкциях автоматически потребовал бы пересмотра ограничения на вложенность, затем размера табуляции, а затем и самого применения символа табуляции вместо пробелов.
PS. А насчет "На мой взгляд, чем короче, тем лучше" - полностью согласен. Из-за этого даже очень редко использую пустые строки - дабы разместить на экране максимальное количество "полезных" строк.
Автор: Altair 26.01.2009 16:35
Цитата
Lapp, очень опасный код на самом деле: где гарантия, что вычисление Condition1 произойдет раньше, чем вычисление Condition2 (если вообще произойдет)? А это может иметь значение...
Поддерживаю, тем более речь не только о Паскале, где выполнением операций можно хоть как-то управлять директивами.
Вот например я на работе часто вынужден проверять не пуста ли коллекция (язык похож на бейсик) Если написать вот так:
Код
if coll_docs is Nothing And coll_docs.Count<>0 then ' работаем с коллекцией, она не пуста end if
то может возникнуть ошибка, если coll_docs = nothing (т.е. объекта нет, и возникнет ошибка обращения к памяти при попытке обратиться к свойству Count, как следствие ошибка исполнения Object variable not set) Поэтому приходится разделять на две конструкции:
Код
if coll_docs is Nothing then ' диагностика и выход end if
if coll_docs.Count<>0 then ' диагностика и выход end if
Это самый простой вариант. Вообще тексты кодов в бизнес приложениях, особенно в которых обрабатываются деньги (различные платежи и т.п.) очень просты по содержанию, т.е. там нет каких-то алгоритмических изысков, зато очень много всевозможных проверок.