Шаг 50.
Принципы и методы структурного программирования. Пошаговая детализация

    На этом шаге мы рассмотрим назначение и использование пошаговой детализации.

    Структурное программирование до сих пор было у нас представлено как свойство или оценка окончательного текста программы.

    Необходимо добавить еще один ключевой момент - методологию, или особенности мыслительного процесса, управляющего процессом получения структурной программы. Этот мыслительный процесс называется пошаговой детализацией и был первоначально предложен Э.Дейкстрой [1], а затем улучшен Н.Виртом [2].


    Причем на протяжении всего процесса логика выражается основными конструкциями структурного программирования.

    В методе пошаговой детализации можно выделить следующие существенные этапы [3].

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

       

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

       

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

       

  4. Разработка завершена: в модульном виде получено описание требуемой программы. Перевод этого описания в программу на конкретном языке программирования должен быть достаточно простой задачей.

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

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


    Концепцию псевдокода легче всего уяснить на примере. Пусть требуется определить наибольшее значение в некотором наборе данных и вывести эти данные, поделенные на наибольшее значение. Скажем, если данные представляют собой последовательность чисел:
    4., 2.51, 10, -5, 7.5	,
то вывод должен выглядеть следующим образом:
    0.4, 0.251, 1, -0.5, 0.75	.

    Уровень 1:

1) ввести данные;
2) найти максимум введенных данных;
3) вывести результаты.

    Детализация 1.1. Ввод данных можно детализировать на псевдокоде следующим образом:

1) определить количество чисел;
2) пока не все элементы введены, прочитать и запомнить значение элемента;
3) конец цикла.

    Это описание можно перевести на язык Turbo Pascal следующим образом:

    Write ('Укажите количество элементов: ');
    ReadLn(N);
    For i:=1 To Do
       ReadLn(A[i]);

    Детализация 1.2. Отыскание максимума можно детализировать следующим образом:

1) выбрать в качестве максимума первый элемент данных;
2) пробежать все введенные значения, заменяя текущий максимум 
   на очередное значение, если оно не превысило его.

    Детализация 1.3. Вывод результатов можно детализировать следующим образом:

1) пока не все результаты выведены;
2) вывод  значения очередного элемента, поделенное на максимум;
3) конец цикла.

    Это описание можно немедленно перевести на Turbo Pascal следующим образом:

    For i:=1 To N Do
      WriteLn(A[i]/M);             .

    Уровень 2. Он включает в себя три детализованные выше части, из которых только детализация 1.2 требует дополнительного внимания. Ее можно детализировать на псевдокоде следующим образом:

1) положить М, равное первому элементу данных;
2) пока не все элементы просмотрены;
3) если М<текущий элемент, то M = текущий элемент;
4) конец цикла.

    Это описание можно перевести на Turbo Pascal следующим образом:

    M:=A[1];
    For i:=1 TO N Do
      If  M<A[i] Then M:=A[i];

    Так как приведенные выше модули используются только по одному разу и очень просты, то можно не делать из них подпрограммы, а объединить их вместе в одну программу:

{Программа, полученная из псевдокода.}
Program Primer;
Var
A: Array [1..20] Of Real;
M: Real;
N, i: Byte;
Begin
  {Первый уровень.}
  Write('Укажите количество элементов: ');
  ReadLn(N);
  For i:=1 To N Do
    ReadLn(A[i]);      
  {Второй уровень.}
  M:=A[1];
  For i:=1 TO N Do
    If  M<A[i] Then M:=A[i];
  {Третий уровень.}
  For i:=1 To N Do
    WriteLn(A[i]/M);
End.

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

   


(1) Dijkstra E.W. A Constructive Approach to the Problem of Program Correctness // BIT. 1968. 8(3). P.174-186.
(2) Wirth N. Program Development by Step-Wise Refinement // Communications of the ACM. 1971. 14(4). P.221-227.
(3) Уолш Б. Программирование на Бейсике. - М.: Радио и связь, 1988.

    На следующем шаге мы поговорим о трюках.




Предыдущий шаг Содержание Следующий шаг