Модульное проектирование
Принцип модульности на самом деле самый простой для понимания и в то же время самый сложный для соблюдения. МОДУЛЬ - это логически завершенная часть программы (алгоритма). Принцип модульности предполагает, что программа строится из множества ограниченных по размеру, логически завершенных, универсальных частей - модулей. В языках программирования понятию модуля соответствует понятие ПРОЦЕДУРА, конкретно в Си - ФУНКЦИЯ. Перечислим основные свойства модуля :
-функция (модуль) должна реализовывать логически законченный, целостный алгоритм ;
-функция (модуль) должна быть ограничена в размерах, в противном случае ее необходимо разбить на логически завершенные части - модули, вызывающие друг друга ;
-функция (модуль) не должна содержать ввода и вывода результатов во внешние потоки - результаты должны быть размещены в структурах данных ;
-функция (модуль) должна быть универсальна, параметры процесса обработки и самих данных должны передаваться извне (через формальные параметры), а не должны подразумеваться, устанавливаться постоянными ;
-функция (модуль) должна иметь продуманный " программный интерфейс" - набор фактических параметров и результат функции, через который она " подключается" к другим частям программы (вызывается). Более конкретно, " программным интерфейсом" функции является ее заголовок.
Естественно, что принцип модульности должно соблюдать по духу, а не буквально. Это означает, что в процессе обдумывания программы необходимо сразу же выделять отдельные, логически завершенные части, которые следует оформлять в виде модулей, а не производить чисто механическое деление программы на части.
Замечание : если в процессе разработки алгоритма возникает непреодолимое желание повторить уже выполненную последовательность действий, возможны следующие варианты :
-выполнить goto к имеющемуся фрагменту (категорически не рекомендуется) ;
-повторить текст фрагмента в новом месте (не эффективно) ;
-оформить повторяющийся фрагмент в виде модуля (лучше всего) .
Есть и другая сторона принципа модульности. При попытке решения любой достаточно сложной задачи необходимо пытаться применить стандартные решения или алгоритмы. Это значит, что в первую очередь необходимо выделить части проблемы, которые реализуются уже известными алгоритмами и, соответственно, будут выполнены в виде отдельных модулей. Тогда оставшаяся часть задачи уже будет выглядеть значительно проще.
Пример: разместить в строке слова в порядке убывания. Стандартные решения - найти в строке слово максимальной длины, переписать его в выходную строку, заменяя во входной строке на пробелы, процесс повторять, пока во входной строке есть слова. Такой алгоритм называется сортировкой выбором.
Для начала необходимо определить интерфейс взаимодействия функции поиска слова и оставшейся части программы. Функция возвращает индекс первого символа слова максимальной длины из входного массива или -1, если слов нет.
int find(char c[]) {...}
После чего программа благополучно разделена на две части и их можно разрабатывать в любом порядке. Начнем с основной функции. Для начала необходимо определить ее заголовок и первоначальную формулировку алгоритма:
void copy(char out[], char in[])
{ Пока есть слово во входной строке - переписывать }
Учитывая, что факт наличия очередного слова опреляется функцией find, можно сразу же формализовать алгоритм в виде цикла l:
void copy(char out[], char in[])
{
Выходная строка пуста
while ((m=find(in)) !=-1)
{ Переписать слово, начиная с in[m] в выходную строку }
Завершить выходную строку
}
Для работы с выходной строкой необходимо ввести переменную - индекс текущего символа, после чего две словесные формулировки можно закодировать :
void copy(char out[], char in[])
{
int m,k=0;
while ((m=find(in)) !=-1)
{
Пока не кончилось слово, начиная с in[m],
переписывать символ в out[k++]
Добавить в конце слова пробел
}
out[k]=0;
}
Две последние формулировки также кодируются без проблем (их необходимо поместить в тело цикла уже написанной программы) :
for (;in[m]!=' ' && in[m]!=0; m++)
{ out[k++]=in[m]; in[m]=' '; }
out[k++]=' ';
Функция поиска слова максимальной длины - вариант стандартного алгоритма поиска максимума :
int find(char c[])
{
int maxi=-1,maxl=0,i=0;
while (c[i]!=0)
{
while(c[i]==' ')i++;
if (c[i]!=0)
{
int k;
for (k=0; c[i]!=' ' && c[i]!=0; i++,k++);
if (k > maxl) { maxl=k; maxi=i-k; }
}
}
return maxi;
}