Помощь - Поиск - Пользователи - Календарь
Полная версия: Как оформлять тексты программ
Форум «Всё о Паскале» > Разработка ПО, алгоритмы, общие вопросы > Общие вопросы разработки программ
Altair
Совершенно случайно наткнулся на инструкцию для студентов по оформлению текстов программ.

Не со всеми пунктами однозначно согласен, но думаю развивать культуру программирования необходимо.
andriano
Категорически не согласен с пунктом 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
На мой взгляд, чем короче, тем лучше:
begin
if not (condition1 or condition2 or condition3 or condition4) then DoSomething;
end;
volvo
Lapp, очень опасный код на самом деле: где гарантия, что вычисление Condition1 произойдет раньше, чем вычисление Condition2 (если вообще произойдет)? А это может иметь значение...
Lapp
Цитата(volvo @ 12.12.2008 23:15) *
где гарантия, что вычисление Condition1 произойдет раньше, чем вычисление Condition2
Гарантия - в соответствующих опциях компилятора.
volvo
Нет никакой гарантии... Паскаль не определяет порядок вычисления выражений... Ты можешь гарантировать только, что все выражения вычислятся (если не выбрана "короткая схема"), но вот в каком порядке - вопрос... С другой стороны, "короткая схема" вычисляет выражение всегда слева направо, но, возможно, будут вычислены не все его составляющие... Источник

P.S. Я правильно понимаю, что Condition1, Condition2 и так далее - это не переменные типа Boolean, а, скажем, функции или вычисляемые выражения? В случае с переменными все просто...
andriano
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;
Увы, не вышло. sad.gif
Lapp
Цитата(volvo @ 12.12.2008 23:24) *
"короткая схема" вычисляет выражение всегда слева направо, но, возможно, будут вычислены не все его составляющие...
Именно, короткая схема (то есть то же самое, что && и || в С). Меня всегда восхищало, что, при хорошо продуманной схеме, она практически всегда (за исключением ооочень редких случаев) очень органично встраивается в алгоритм. Фактически, это именно ТО, что привел adriano - тоже вычисляются не все составляющие.

Помню, когда мне нужно было придумать пример (реальный, ненадуманный) необходимости использования "длинной" схемы, пришлось немало потрудиться.. smile.gif

Цитата(andriano @ 12.12.2008 23:44) *
Lapp, я надеялся, что наличие "лишних" begin/end наведут на мысль, что condition - это не один оператор, а несколько. ...Увы, не вышло. sad.gif
Не навело lol.gif . Еще хорошо, что volvo уточнил про переменные.. smile.gif

Но, опять же, во многих случаях имеет смысл организовать Булевы функции, чтоб всю логику собрать компактно в одном месте.
andriano
Цитата(Lapp @ 12.12.2008 23:56) *
Помню, когда мне нужно было придумать пример (реальный, ненадуманный) необходимости использования "длинной" схемы, пришлось немало потрудиться.. smile.gif
По этому поводу хочу сразу заметить, что в расчете на короткую схему следовало бы писать так:

begin
if not (condition1 or condition2 or condition3 or condition4 or DoSomething) then;
end;
Т.е. принципиально с пустым телом.
Что наводит на мысль о введении в ЯВУ новой высокоуровневой конструкции с гарантированным условным выполнением в заданном порядке вне зависимости от компилятоа и его настроек.
Цитата

Не навело lol.gif . Еще хорошо, что volvo уточнил про переменные.. smile.gif
Спасибо, я уже заметил.
Но и вторая итерация также оказалась недостаточно полной. Подправил.
Цитата

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

Собственно, речь шла о записи алгоритмов. И на примере рекомендаций по ссылке я еще раз убедился, что break/exit - "вредные" операторы.
А еще одно наблюдение - одни предпочтения неизбежно влекут за собой другие. Так, отказ о exit в подобных конструкциях автоматически потребовал бы пересмотра ограничения на вложенность, затем размера табуляции, а затем и самого применения символа табуляции вместо пробелов.

PS. А насчет "На мой взгляд, чем короче, тем лучше" - полностью согласен. Из-за этого даже очень редко использую пустые строки - дабы разместить на экране максимальное количество "полезных" строк.
Altair
Цитата
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


Это самый простой вариант.
Вообще тексты кодов в бизнес приложениях, особенно в которых обрабатываются деньги (различные платежи и т.п.) очень просты по содержанию, т.е. там нет каких-то алгоритмических изысков, зато очень много всевозможных проверок.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.