Форум Программирование В помощь новичкам и любителям. |
|
Форматирование оказалось упущено из виду, хотя, видимо, применялось к приведенным примерам "плохого" говнокода. см. http://jedicodeformat.sourceforge.net/ Цитата (Ерёмин А.А.): Дай бог, чтобы как можно большее число людей это прочитало! На бога надейся, а сам не плошай. Серьезно, когда уже почините http://expert.delphi.int.ru/question/5408/#msg_26813виконання програми розпочинається з того самого мiсця, де призупинилося. | |||||||
|
виконання програми розпочинається з того самого мiсця, де призупинилося. | |||||||
|
Отступы, выравнивание. Сейчас я не буду приводить паталогических случаев типа записи всей программы в одну строчку, а просто приведу примеры, как правильные отступы могут улучшить чтение программы. Вступление. Во-первых отступы - личное дело каждого, как и идентификаторы, я лишь покажу как важно делать везде одинаковые отступы, а вы решайте какие отступы вам нужны. I. Неверные переносы строки for ... to ... do if ... then begin ... if ... then ... end; Понять что куда вложено совершенно непонятно. Давайте добавим переносы строк куда нужно и уберём ненужные. for ... to ... do if ... then begin ... if ... then ... end; Выводы: 1. begin и end должны быть на отдельных строках. Не экономьте строчку и не ставьте begin на один уровень с оператором if, while или др. 2. Каждый оператор должен быть на отдельной строке. Не поддавайтесь искушению и не пишите так: x:=0; y:=0; z:=0; в одну строчку. 3. Пустые строки позволяют отделить логически части программы. Если такое действительно требуется - создайте процедуры. 4. Не пишите действие оператора if на одной строчке с then, или на одной строке с else. Тем более не надо запихивать if-then-else в одну строку: if x>y then x:=y else y:=x; II. Горизонтальные отступы Давайте дальше разбираться с нашим примером. for ... to ... do if ... then begin ... if ... then ... end; Добавим горизонтальные отступы, чтобы было понятно куда какой оператор вложен. for ... to ... do if ... then begin ... if ... then ... end; Выводы: 1. Когда вы пишите действие для оператора - ставьте эти действия на 2 пробела правее, чем сам оператор. 2. begin и end остаются на уровне оператора. В итоге привожу код без замен на ... ResultMemo.Clear; for t := 1 to 100 do if frac( 4.5 * t - 400 ) / 5 = 0 then begin b := ( 4 * t + t div 2 - 400 ) div 5; k := 100 - b - t; if ( k > 0 ) and ( b > 0 then ResultMemo.Lines.Add( ... ); end; Как видите ничего не понятно. А теперь с предложенными отступами: ResultMemo.Clear; for t := 1 to 100 do if frac( 4.5 * t - 400 ) / 5 = 0 then begin b := ( 4 * t + t div 2 - 400 ) div 5; k := 100 - b - t; if ( k > 0 ) and ( b > 0 ) then ResultMemo.Lines.Add( '' ); end; III. Выравнивание переменных var x, y: Integer; h, w, i: Integer; Text: String; В этом коде есть ещё ряд проблем, о которых была рассказано ранее, я их устраню но не буду объяснять. var x, y: Integer; Height, Width: Integer; Index: Integer; Text: String; Выводы: 1. Разделять разные по предназначению переменные и объединять схожие - хорошая идея. Когда у вас в ряд написаны переменные x, y, h, w, i, j, txtCnt, tag, врядли кто-нибуть разберёт их предназначение. 2. Выравнивание по горизонтали улучшает читаемость кода. Когда тип переменной расположен сразу после её имени - неплохо. Но когда все данные предоставлены в виде таблицы, когда мы можем раздельно работать с разными колонками - отлично! IV. Выравнивание присваиваний Я уже выкладывал код с небольшим выравниванием присваиваний, но сейчас напишу более запущеный. if LastResult > X then begin Result := X; LastResult := X; NowX := X / 2; end else begin Result := LastResult ; X := LastResult ; LastResult := LastResult / 2; end; А теперь сделаем выравнивание по присваиванию: if LastResult > X then begin Result := X; LastResult := X; X := X / 2; end else begin Result := LastResult; X := LastResult; LastResult := LastResult / 2; end; Вывод: 1. Выравнивание даже для присваиваний позволит лучше визуально оценивать код. 2. Выравнивание эффективно для переменных с большой разницей в длине идентификаторов. Сделать выравнивание для переменных x, y, x2, y2 - небольшое улучшение, тогда как в примере длина переменных очень разная и в разы улучшает читаемость кода. Чисти код! Чисти код! Чисти код! | |||||||
|
Молодец, правильное дело пишешь. Я пишу совсем немного по-другому, но в основном именно так. Добавлю от себя: при вызове функции/процедуры/метода без параметров, ставьте скобки (в С/С++ это обязательно), в delphi такая возможность появилась, ЕМНИП, с 4-й версии. ResultMemo.Clear(); // <--- пример не очень, конечно, но таки да... Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! | |||||||
|
Ещё добавлю, пожалуй. Многие товарищи пытаются (бывает, что, успешно) писать программы на основе TTreeView, TListView, TPageControl и т.п. Причём, стараются прикручивать сложные динамические структуры к свойству Data. Это, конечно, возможно и работает, если всё сделать правильно, однако есть способ лучше, ИМХО, нашкрябать класс-потомок от TListItem, TTreeNode, TTabSheet... Лично я считаю, что так делать правильно, и везде, где возможно, пишу потомков. Даже от TStringList, TObjectList и т.д. Если кому интересно - могу научить. Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! | |||||||
|
Ну про отступы тут много личного получилось. Знаете ли вы, что те, кто ставит "операторные* скобки" по Кернигану ненавидят тех, кто их ставит по Оллмену даже больше, чем пользователи vi ненавидят пользователей emacs? if X > 0 then Y := X*X + 2*X; if X > 0 then begin Y := X*X + 2*X; end; { здесь и далее выражение приведено к трехпозиционному коду исключительно в иллюстративных целях } if X > 0 then begin Y := X/2; Y := Y + 2*X; end; if X > 0 then begin Y := X/2; Y := Y + 2*X; end; В частности, не очевиден конец предлагаемого в примере составного условного "оператора"*, вложенного в цикл. *оператор здесь подразумевает statement. виконання програми розпочинається з того самого мiсця, де призупинилося. | |||||||
|
Ключевое слово begin, как мне кажется совершенно не важно где расположено. Главное - чтобы человек ставил всегда одинаково, а исправить под себя если чего это будет легко. На паскале кстати почти все пишет по Оллману, но мне больше нравится по Кернигану (хотя привык я по Оллману из-за литературы и примеров). Чисти код! Чисти код! Чисти код! | |||||||
|
min@y™: Научи | |||||||
|
min@y™: Насчёт скобок у функций/процедур. Один человек, которого я очень уважаю сказал: "Когда процедура вызывается в отдельном утверждении, то итак ясно, что это вызов процедуры/функции. Когда же функция вызывается в выражении, она должна иметь пустые скобки, потому что необходимо помнить о накладных расходах которые возникнут при вызове этой процедуры" С тех пор я пишу круглые скобки у каждой функции. Пытаюсь у каждой процедуры, но иногда забываюсь. Чисти код! Чисти код! Чисти код! | |||||||
|
Gooddy: я вот о чём: while True do if not False < (True and False) then if 2 * 2 = 4 then begin Large; Compound; Statement; end; Another;с отступами в 2 пробела даже в таком коротком блоке сложно увидеть где какая управляющая конструкция кончается. Цитата (min@y™): при вызове функции/процедуры/метода без параметров, ставьте скобки (в С/С++ это обязательно) Ненене, у Паскаля совершенно другая идеология чем в крестах, и попытки писания C++ на паскале кончатся как всегда. Тут как бы понятна идея обозначить скобками символ с побочными эффектами, но это не будет работать в 100% случаев, ибо геттеры свойств как раз и призваны прятать вызов за простым символом (отдаю себе отчет, что геттер в принципе не должен иметь сайдэффектов) Цитата (Gooddy): Когда процедура вызывается в отдельном утверждении, то итак ясно, что это вызов процедуры/функции. Когда же функция вызывается в выражении, она должна иметь пустые скобки, потому что необходимо помнить о накладных расходах которые возникнут при вызове этой процедуры Конечно, годный компромисс, но полностью описанную выше задачу не решает. виконання програми розпочинається з того самого мiсця, де призупинилося. | |||||||
Перейти в раздел:
© 2004 - 2024, Delphi.int.ru |
Версия форума: 1.10 (19.01.2010) |
Выполнено за 0.04 сек. |