====== Оформление программ ====== ===== Соглашения по идентификаторам ===== ==== Подбор идентификаторов ==== === Все идентификаторы должны выбираться из соображений читаемости и максимальной семантической нагрузки === == Например: == const Eps = 0.0001; { точность } var Sum : Integer;{ сумма } Message: String; { сообщение } === Неудачными можно считать идентификаторы: === const UU = 0.0001; { точность } var Kk : Integer;{ сумма } Zz : String; { сообщение } === Идентификаторы рекомендуется подбирать из слов английского языка === == Например: == 1)procedure Beep(Hertz, MSec: Word); { выдает звуковой сигнал заданной частоты и длительности } 2)function ExistFile(FName: String): Boolean; { выдает True, если файл с именем FName существует } 3)var Done: Boolean; { признак окончания работы с программой } Width, Height: Real; { размеры изделия (ширина, высота) } === Не очень удачными можно считать идентификаторы: === 1)procedure Zvuk(Chast, Dlit: Word); { выдает звуковой сигнал заданной частоты и длительности } 2)function EstFile(Im: String): Boolean; { выдает True, если файл с именем Im существует } 3)var Konec: Boolean; { признак окончания работы с программой } Shirina, Vysota: Real; { размеры изделия (ширина, высота) } ==== Написание идентификаторов ==== Зарезервированные слова языка Turbo Pascal писать только маленькими буквами.\\ Например: type, var, const; procedure, function; begin, end; if, then, else; repeat, until; case; while; and, not, or; unit, uses, interface, implementation. === В любых идентификаторах каждое слово, входящее в идентификатор, писать, начиная с большой буквы, остальные буквы - маленькие === В этом смысле символ подчеркивания "_" между словами идентификатора можно считать излишним. == Например: == 1) var NextX, LastX: Real; { следующая и предыдущая итерация } BeepOnError: Boolean; { подавать ли звуковой сигнал при неправильном вводе пользователя? } 2) function GraphErrorMsg(ErrCode: Word): String; { стандартная функция модуля Graph; выдает описание ошибки использования графики по ее коду } 3) begin Write('Введите целое число, большее 10 ==>_ '); ReadLn(Num); if Num > 10 then WriteLn('OK'); end. 4) var FileName: String;{ а не File_Name } type ByteArray = array [0..65534] of Byte; { а не Array_Of_Byte } === Рекомендуется идентификаторы, состоящие из одной буквы, писать большой буквой, если они не являются счетчиками циклов === == Например: == 1) A := A + B; B := A - B; A := A - B; 2) procedure DeleteNode(var L: List; I: Word); { удалить звено c номером I из списка L } 3) for i := 1 to N do for j := 1 to N do A[i, j] := (i + j) / 2; ===== Соглашения по самодокументируемости программ ===== ==== Комментарии ==== === Комментарии в теле программы следует писать на русском языке и по существу так, чтобы программист, не участвовавший в разработке программы (но имеющий опыт работы на языке Turbo Pascal), мог без особого труда разобраться в логике программы, и, при необходимости, сопровождать данный программный продукт === === Рекомендуется комментарии программы писать внутри символов { и }, а (* и *) использовать при отладке программы как "заглушки" участков программного кода === ==== Спецификация подпрограммы ==== === Для каждой пользовательской подпрограммы (процедуры или функции) должна быть описана в виде комментария спецификация, содержащая следующую информацию: === * назначение подпрограммы; * описание семантики параметров-значений (параметров, передаваемых по значению), если она неочевидна; * описание семантики параметров-переменных (параметров, передаваемых по ссылке), если она неочевидна. * для функции: описание семантики возвращаемого значения, если она неочевидна. == Например: == 1) семантика параметров и возвращаемого значения очевидна function IsLeapYear(Y: Word): Boolean; { возвращает True, если год Y -- високосный } 2) семантика параметров очевидна, семантика возвращаемого значения неочевидна function DayOfWeek(D, M, Y: Word): Byte; { Возвращает день недели даты D/M/Y; год Y должен быть в отрезке 1582..4902; результат: ВСК = 0, ПНД = 1, ВТР = 2, ... СБТ = 6 } 3) семантика параметров и возвращаемого значения неочевидна const MaxN = 10; type Matrix = array [1..MaxN, 1..MaxN] of Real; Vector = array [1..MaxN] of Real; procedure Gauss(A: Matrix; B: Vector; Eps: Real; var X: Vector; var HasSolution: Boolean; var NumOfRoots: Integer; var Det: Real; var AForReverse: Matrix; var BForReverse: Vector); { Решение системы линейных алгебраических уравнений методом Гаусса. Входные данные: A -- матрица коэффициентов системы; B -- столбец свободных членов системы; Eps -- точность вычислений. Выходные данные: X -- вектор решения; HasSolution -- флаг, устанавливаемый в True, если решение системы существует, и в False во всех остальных случаях; NumOfRoots -- число корней в решении системы, может принимать значения: 0 -- если решение системы не существует, MaxN -- если решение системы существует и единственно, MaxInt -- если существует бесконечное множество решений; Det -- значение определителя матрицы A; AForReverse -- нижняя треугольная матрица, полученная из A в в результате выполнения прямого хода алгоритма Гаусса; BForReverse -- столбец свободных членов, полученный из B в в результате выполнения прямого хода алгоритма Гаусса. } == Замечание: == Если процедура (функция) реализует какой-либо вычислительный метод (например: нахождение площади фигуры методом трапеций, поиск минимума функции методом Ньютона и т.п.), рекомендуется в теле процедуры (функции) поместить комментарий с кратким описанием метода, либо ссылку на источник, где описан метод. ==== Спецификация программного файла или модуля ==== Программный файл или модуль (unit) должен начинаться со спецификации в виде комментария, содержащего следующую информацию: * идентификация (имя) файла; * фамилия и копирайт автора; * дата написания файла; * версия языка программирования и замечания по компиляции программы (модуля) в других версиях языка (если требуется); * назначение программы (модуля); == Например: == 1) { PRIMES.PAS -------------------------- (c)оздал: Иванов И.И. дата : 01/09/93 для : Turbo Pascal 6.0 ------------------------------------------------------- Подсчет количества простых чисел в промежутке [1..200]. } 2) { MYMENU.PAS -------------------------- (c)оздал: Иванов И.И. дата : 01/09/93 для : Turbo Pascal 6.0 ------------------------------------------------------- Модуль экспортирует процедуры и функции, поддерживающие горизонтальные и вертикальные меню. } == Замечание: == В программном файле после заголовка Program <имя программы>; (в файле с пользовательским модулем -- после заголовка unit <имя модуля>;) рекомендуется поместить комментарий с указаниями по запуску программы и работе с ней (указаниями по использованию модуля другими программистами) или ссылку на источник, который использован при составлении программы (модуля). ===== Соглашения по читаемости программ ===== ==== Лесенка ==== === "Лесенка" должна отражать структурную вложенность языковых конструкций. Рекомендуется отступ не менее 2-х и не более 8-и пробелов. Принятого отступа нужно придерживаться во всем тексте программы. Правила написания конструкции begin ... end и других === а1) if <условие> then begin <операторы> end; а2) if <условие> then <оператор>; а3) if <условие> then begin <операторы> end else begin <операторы> end; б1) while <условие> do begin <операторы> end; б2) while <условие> do <оператор>; в1) for <счетчик> := <начальное значение> to <конечное значение> do begin <операторы> end; в2) for <счетчик> := <нач/знач> to <кон/знач> do <оператор>; г1) case <выражение> of <выражение>: <оператор>; ....... end; г2) case <выражение> of <выражение>: <оператор>; ....... else <оператор>; end; г3) case <выражение> of <выражение>: begin <операторы> end; ....... end; == Например: == 1) function Sign(X: Real): Integer; { выдает знак числа X } begin if X > 0 then Sign := 1 else if X < 0 then Sign := -1 else Sign := 0; end; 2) procedure Equation(A, B, C: Real; var X1, X2: Real; var Num: Byte); { нахождение действительных корней квадратного уравнения; A, B, C -- коэффициенты X1, X2 -- корни (если действительного решения нет, то полагаются равными 0); Num -- число корней (0, 1, или 2) } var D: Real; begin D := Sqr(B) - 4 * A * C; if D < 0 then begin Num := 0; X1 := 0; X2 := 0; end else begin X1 := (- B + Sqrt(D)) / (2 * A); X2 := (- B - Sqrt(D)) / (2 * A); if X1 = X2 then Num := 1 else Num := 2; end; end; ==== Длина строк программного текста ==== === Длина строк программы не должна превышать ширины экрана (80 символов) === ==== Прочие рекомендации ==== === Рекомендуется операнды бинарных операций (+, := и т.п.) отделять от знака операции одним пробелом === == Например: == Sum := A + B; === Рекомендуется при перечислении идентификаторов после запятой "," ставить один пробел " " === == Например: == 1) WriteLn('Сумма: ', A + B, ';', 'Разность: ', A - B, '.'); 2) var Day, Month, Year: Word; i, j, k, l, m, n: Integer; === Рекомендуется всегда писать символ-разделитель операторов ";" (непосредственно после оператора) === == Например: == 1) case Num of 1: WriteLn('один...'); 2: WriteLn('два...'); 3: WriteLn('три...'); { <-- здесь } else WriteLn('много!'); { <-- и здесь } end; 2) if N < 0 then begin WriteLn('Введено неверное значение N, прерываем работу!'); Halt; { <-- здесь } end; === Рекомендуется после символа-спецификатора типа ":" ставить один пробел " " === == Например: == 1) var i, j, k: Integer; 2) function SizeOfFile(FName : String) : LongInt; { выдает размер файла с именем FName в байтах; если файл не найден, возвращает -1 } === Рекомендуется 16-ричные числа писать большими буквами === == Например: == 1) const BadDate = $FFFF; kbEnter = $1D; { код клавиши } === Рекомендуется директивы компилятора писать большими буквами, а условные определения -- так же, как идентификаторы (см. 1. Соглашения по идентификаторам) === == Например: == 1) type {$IFOPT N+} RealType = Extended; {$ELSE} RealType = Real; {$END} 2) {$DEFINE Protect} .... {$IFDEF Protect} WriteLn('Программа защищена от копирования!'); {$ENDIF} ---- Оригинальная ссылка: [[http://mzym.susu.ru/papers/coderule.html|Требования к оформлению программ на языке Turbo Pascal]] (c) М.Л. Цымблер