Правила программирования


Поздеев Василий

правильная стилистика программированияВсе мы люди и нам свойственно ошибаться. И даже компьютеры ошибаются, если программа, за счет которой они работают, была написана с ошибкой. Чтобы помочь Вам избежать некоторых ошибок при написании программ на любом языке программирования я расскажу о некоторых правилах используемых при написании программ и о методах программирования. Соблюдение ниже описанных методов поможет не только избежать некоторых ошибок, но также предупредит их появление и упростит отладку Вашей программы. Все ниже приведенные примеры и код программ написаны на языке Visual Basic 6.0. Вы можете использовать материал данной статьи и для других языков программирования. Статья не привязывает Вас к какому-либо конкретному языку и является универсальной.

Метод проектирования программных средств

Для решения задач программирования используется "Метод проектирования программных средств". Этот метод состоит из нескольких этапов:

1. Определение условий задачи.
2. Анализ задачи.
3. Создание алгоритма решения задачи.
4. Реализация алгоритма.
5. Тестирование и отладка готовой программы.
6. Поддержка и обновление готовой программы.

На первом этапе определяются условия задачи и необходимо ясно понять, что требуется для её решения. Основная цель в данном случае - отсеять второстепенные аспекты от основной сути задачи.

На втором этапе определяются входные данные, выходные, промежуточные и какие дополнительные трудности могут возникнуть при решении поставленной задачи.

На третьем этапе создается алгоритм - запись пошаговых процедур, а затем обеспечение таких условий, чтобы этот алгоритм решал задачу должным образом. Алгоритм может быть написан и в виде блок-схем.

Наверное, всем кто изучал программирование или информатику в учебных заведениях рассказывали, как нужно чертить блок-схемы. И наверняка большинство не любит их чертить. Ваш покорный слуга также относится к их числу. Но не стоит думать, что блок-схемы абсолютно бесполезны в программировании. Лично я никогда не черчу блок-схемы при разработке программ, но я умею хорошо это делать. И настоятельно советую Вам, научится чертить их лучше всех. Если Вы не научитесь самостоятельно и правильно чертить блок-схемы, Вы не сможете осознать суть того, как работает программа! Именно блок-схема позволяет наглядно и понятно (схематически) показать, как пошагово (построчно) выполняется программа. Ведь блок-схема это и есть алгоритм выполнения самой программы. А что такое алгоритм?

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

Когда перед Вами стоит решение очень сложной задачи, можно (и нужно) применить метод "декомпозиции". Суть метода заключается в разбиении одной сложной задачи на множество взаимосвязанных, маленьких и простых подзадач, решив которые в отдельности Вы получите необходимый результат. Здесь можно привести аналогию с веником. Весь веник целиком сломать очень трудно, но если его ломать по одному прутику, то все получится.

Четвертый этап метода проектирования программных сред заключается в записи созданного алгоритма в виде программы на определенно языке программирования.

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

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

Некоторые ситуации и ошибки невозможно выявить даже на основе "эталонного решения". Такие ошибки проявляются только в процессе длительного использования программы с множеством входных данных. Именно на шестом этапе и производится их исправление, а также изменение программы в соответствие изменившимся государственным нормам или политике компании.

При написании программ также необходимо соблюдать и другие правила, речь о которых пойдет ниже.

Переменные

Имена переменных

Почти во всех программах нам приходится использовать переменные, порой даже очень много переменных. Главное чтобы в последствии не запутаться какая переменная, какие данные хранит. Для этого необходимо давать именам переменных содержательные имена. Исключением могут быть только переменные, используемые в циклах, но не участвующие многократно в вычислениях.

For i = 1 to 10 Step 1
For j = 1 to 10 Step 1
dmsTable(i, j) = i * j
Next j
Next i

Если нам нужно сохранить в переменную чей-то год рождения. Назовите переменную "vblYearsBorn", а не "A". Старайтесь чтобы имя переменной отражало суть тех данных для хранения которых она предназначена, чтобы оно было интуитивно понятно. Пусть от этого имя переменной будет немного длинным, но зато это не даст вам запутаться и исключит повторное использования данной переменной в других вычислениях, для которых она не предназначена. Имя переменной желательно обязательно начинать с прописных букв vbl, от английского variable (переменная). Это особенно актуально в Объектно-Ориентированном Программировании (далее ООП). Так как имя переменной можно спутать с названием, какого либо объекта на форме (об этом пойдет речь ниже).

Давайте для понятности назовем эти три начальные буквы - "Идентификатором объекта", так как дальше я буду упоминать о них не однократно.

После идентификатора, без пробелов, следует писать имя переменной. Его нужно начинать с большой буквы, чтобы при просмотре листинга программы Вы видели, что это переменная, или какой-то другой объект, чтобы буквы выделялись, а не сливались в одну строку.

vblFirstName

Объявление переменных

Некоторые языки программирования (например, Visual Basic) позволяют работать с переменными не объявляя их в коде программы. Я считаю это большой ошибкой и не солидностью языка программирования (но это не значит что этот язык программирования плох)!

Объявление переменной это определение ее типа и имени.

Dim vblFirstName as String (Visual Basic)
Var vblFirstName: String; (Turbo Pascal)
Char vblFirstName; (C++)

Т.е. мы как бы указываем программе, что будем использовать переменную с именем vblFirstName и тип данных этой переменной String (текстовый/литеральный).

Почему это важно (это касается только тех языков программирования, которые разрешают так делать. Например, если Вы не объявите переменную в С++ или Turbo Pascal-е, при компиляции будет сгенерирована ошибка, что используемая переменная не объявлена)? Все очень просто. Если мы не объявим переменную ей автоматически будет присвоен тип Variant, это значит что в переменную можно будет сохранять данные почти любого типа. Во-первых, мы сможем записать в переменную, которая хранит фамилию числовые данные или наоборот. ЭТО НЕПРАВИЛЬНО! Так как фамилия не может содержать цифры. Мы заведомо делаем в программе брешь, возможность для совершения ошибки. Вот такими ошибками и пользуются хакеры для взлома систем и прочее. Во-вторых, тип, присваиваемый автоматически, очень "много" занимает места в оперативной памяти. А хорошая программа должна как можно меньше весить. И не важно, сколько гигабайт оперативки у Вас на компьютере. В-третьих, явное объявление переменных позволит назначить им тот тип данных, который Вам необходим. И Вам будет намного легче узнать, какие переменные уже используются в программе. Достаточно будет посмотреть в начале программного кода или модуля, какие переменные уже заданы, а не перелопачивать весь код программы. Вы никогда не сможете повторно объявить уже объявленную переменную в одном и том же модуле, или перепутать их имена, а значить не используете переменную в тех вычислениях, для которых она не предназначена.

В ООП разрешается многократно объявлять переменные с одинаковыми именами, притом условии, что эти переменные локальны и используются только в разных модулях. О видимости переменных пойдет речь чуть ниже.

Инициализация переменных

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

Если это переменная числового типа и используется в накоплении суммы, то достаточно её просто обнулить.

vblSum = 0
For I = 1 to 10 Step 1
vblSum = vblSum + i
Next i

Или присвойте ей единицу, если переменная используется, как множитель или делитель.

vblSum = 1
For I = 1 to 10 Step 1
vblSum = vblSum * i
Next i

Если это строковая переменная просто отчистите ее.

vblFirstName = ""

Лично я всегда инициализирую переменные, даже если в следующей строке присвою ей другое значение.

Глобальные и локальные переменные

Все переменные имеют свою область видимости в зависимости от того, как Вы их объявили. Переменные могут быть локальными и глобальными.

Локальные переменные - это переменные объявленные внутри какой-либо функции (подпрограммы). Они видимы только в пределах данной функции и не могут быть непосредственно вызваны из основного текста программы. Когда выполнение программы возвращается из функции к основному коду программы или другой функции, локальные переменные удаляются из памяти.

Глобальные переменные - это переменные, определенные вне тела какой-либо функции (для ООП, переменные объявленные в модулях проекта). Эти переменные имеют глобальную область видимости и доступны из любой процедуры, функции в подпрограмме.

Очень часто возникают ошибки при использовании глобальных переменных.

В некоторых языках программирования глобальная переменная имя, которой совпадает с именем локальной переменной, могут изменить значения друг друга.

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

Используйте глобальные переменные только при крайней необходимости, когда невозможно или проблематично обойтись другими методами.

Константы

О константах буквально в двух словах. С их использованием в программе также необходимо быть внимательным (как и вообще занимаясь программированием). Имена констант лучше всего начинать с трех буков con, от английского constant (константа).

Const conPi = 3.14159265

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

Структурное программирование

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

Операторы начала и конца цикла пишутся строго друг под другом, а все операторы внутри цикла чуть правее. Все отступы делаются с помощью табуляции (клавиша Tab). Точно также пишутся логические схемы. Благодаря такому написанию ваша программа становится более читабельной и легкой для восприятия. Также облегчается отладка программы. Вы можете сами сравнить приведенный ниже пример, написания кода по принципу структурированного программирования и без него. Пример приведен на языке Turbo Pascal (часть кода сортировки массива).

Пример "Структурированный код":

For i:=1 to 9 do
begin
   vblMin:=A[i];
   k:=i;
   For j:=1+i to 10 do
   begin
      If (vblMin>A[j]) Then
      begin
         vblMin:=A[j];
         k:=j;
      end;
   end;
   vblStuf:=A[i];
   A[i]:=vblMin;
   A[k]:=vblStuf;
end;

Пример "Обычный код":

For i:=1 to 9 do
begin
vblMin:=A[i];
k:=i;
For j:=1+i to 10 do
begin
If (vblMin>A[j]) Then
begin
vblMin:=A[j];
k:=j;
end;
end;
stuf:=A[i];
A[i]:=vblMin;
A[k]:=vblStuf;
end;

Какой вариант более читабелен и понятен? Несомненно, первый.

Вы должны приучить себя соблюдать все вышеописанные нюансы. Конечно, несоблюдение не критично, но использование этих методов намного упростит Вам написание программ и в будущем их сопровождение.

Ошибки

Программы очень редко работают правильно с первого раза. Закон Мерфи гласящий "Если что-то плохое может случиться, оно непременно случиться", похоже, был написан как раз применительно к компьютерным программам.

Ошибки, возникающие в процессе работы программы можно разделить на несколько типов:

1. Синтаксические ошибки
2. Ошибки времени выполнения
3. Логические ошибки

Синтаксические ошибки имеют место, когда исходный код программы записан с нарушением одного из правил грамматики того языка программирования, на котором Вы пишите программу. Обнаруживается это нарушение при попытке откомпилировать программу.

Ошибки времени выполнения выявляются компьютером во время выполнения программы. Подобные ошибки имеют место, когда программа дает компьютеру указание выполнить неверную операцию (например, деление на ноль или манипулировать неописанными или неверными данными).

Ошибки ввода данных - также являются ошибками времени выполнения. Причиной таких ошибок является попытка ввести данные неверного типа (например, переменной целочисленного типа присваивается строковый параметр или число вещественного типа).

Логические ошибки имеют место, когда программа выполняет неверный алгоритм. Данные ошибки являются самыми коварными, их очень сложно выявить, потому что они не фиксируются при компиляции. Данные ошибки проявляются при выводе неверных результатов программой. Единственно возможные способы выявления таких ошибок это использование методов: "эталонного решения" и "ручной отладки".

Умелое использование всех этих методов и правил: метод декомпозиции, структурное программирование, метод проектирования программных средств, эталонное решение и другие, говорят о профессионализме.

17.02.06