Принципы структурного программирования
Структурное программирование
теорема Бёма — Якопини
Ключевые технологические принципы
Преимущества структуризации
Блоки
Архитектурные блоки (Структура исходного кода)
Логические блоки (Управляющие структуры алгоритма)
Логические блоки (Управляющие структуры алгоритма)
Логические блоки (Управляющие структуры алгоритма)
Блоки программы – подпрограммы (процедуры и функции)
Подпрограмма
Пример подпрограммы
Назначение подпрограмм
Процедуры и функции
Подпрограммы (п/п) по своей структуре представляют собой мини-программы и имеют ту же структуру, что и программа:
Основное назначение подпрограмм – структуризация программы!!
Процедуру сортировки тоже можно структурировать:
Задача
Функция создания массива
Обмен данными между п/п
Передача данных по значению
Передача данных по значению
Передача данных по ссылке
Передача данных по ссылке
Принципы структурного программирования
Перегрузка имен подпрограмм
Перегрузка имен подпрограмм
Параметры процедурного типа используют, когда нужно передать в подпрограмму имена процедур и функций.
Переменное число параметров
Параметр по умолчанию
146.00K
Категория: ПрограммированиеПрограммирование

Лекция_№8_Принципы структурного программирования_2026

1. Принципы структурного программирования

Лекция №8

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

Структурное программирование — это парадигма
разработки ПО, основанная на представлении
программы в виде иерархической структуры
логических блоков с целью улучшения читаемости,
надежности и упрощения тестирования. Парадигма
была предложена в 1960-х годах Эдсгером
Дейкстрой как решение «кризиса
программирования» и сложной запутанной логики
(«спагетти-кода»)

3. теорема Бёма — Якопини

Фундаментом парадигмы служит математическая теорема
Бёма — Якопини (1966 г.).
Она гласит: любой сколь угодно сложный алгоритм можно
реализовать с помощью всего трех базовых управляющих
структур:
1. Следование (Последовательность): Выполнение команд
строго одна за другой.
2. Ветвление (Выбор): Выполнение той или иной ветки кода
в зависимости от истинности логического условия
(конструкции if-else или switch-case).
3. Повторение (Цикл): Многократное выполнение
фрагмента кода, пока условие истинно (циклы while,
for, repeat-until).

4. Ключевые технологические принципы

• Принцип одного входа и одного выхода: Каждый
логический блок (алгоритмическая структура, функция,
подпрограмма) должен иметь строго один вход и один
выход. Не допускаются неконтролируемые прыжки внутрь
структуры.
• Отказ от оператора безусловного перехода (goto):
Использование goto нарушает линейное восприятие
программы сверху вниз и порождает запутанную структуру.
В структурном коде передача управления идет только
вперед.
• Нисходящее проектирование (Метод пошаговой
детализации): Подход «сверху вниз». Сложная задача
сначала описывается укрупненно, а затем декомпозируется
(разбивается) на более простые, независимые подзадачи.
• Модульность: Текст программы делится на логически
завершенные, независимые компоненты — модули
(функции/процедуры). Каждый модуль решает строго одну
задачу и оптимально содержит не более 50–100 строк кода.

5. Преимущества структуризации

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

6. Блоки

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

7. Архитектурные блоки (Структура исходного кода)

С точки зрения декомпозиции и модульности, программа делится на
крупные независимые блоки. В языке Pascal это разделение
выражено наиболее строго:
• Заголовок программы (program): Имя программы и подключение
внешних библиотек/модулей (uses).
• Блок описаний (Декларации): Блок, где компилятору сообщается
обо всех используемых элементах. Сюда входят:
• Константы (const).
• Типы данных (type).
• Переменные (var).
• Блоки подпрограмм (Процедуры и Функции): Изолированные
именованные блоки кода. Они принимают параметры, выполняют
конкретную задачу внутри себя и могут возвращать результат. Это
основа модульности.
• Основной блок программы (begin ... end.): Главная точка входа.
Отсюда начинается выполнение программы. В хорошем структурном
коде этот блок минимален и просто поочередно вызывает крупные
блоки подпрограмм.

8. Логические блоки (Управляющие структуры алгоритма)

Внутри любой функции или процедуры код состоит из динамических
блоков управления. Согласно теореме Бёма — Якопини, этих блоков всего
три, и каждый из них обязан соблюдать правило: «один вход, один
выход».
• Линейный блок (Следование): Набор команд, которые выполняются
строго друг за другом. У такого блока нет развилок. Если управление
вошло в первую строчку, оно гарантированно дойдет до последней.
• Условный блок (Ветвление): Блок, разделяющий поток выполнения. В
зависимости от условия выполняется либо один подблок кода, либо
другой. Важно: после выполнения выбранной ветки потоки снова
соединяются в одну общую точку выхода.
• Циклический блок (Повторение): Блок, который возвращает поток
управления к своему началу, пока выполняется условие. Выход из него
происходит строго в одной точке — когда условие становится ложным.

9. Логические блоки (Управляющие структуры алгоритма)

Как блоки связываются между собой?

10. Логические блоки (Управляющие структуры алгоритма)

Главный принцип структурного программирования —
вложенность. Вы можете вставить блок «Ветвление»
внутрь блока «Цикл», а внутрь ветвления —
«Линейный блок». Но вы не имеете права
перекрещивать их границы (что происходило при
использовании goto). Они входят друг в друга как
матрешки, сохраняя строгую иерархию.

11. Блоки программы – подпрограммы (процедуры и функции)

12. Подпрограмма

Подпрограмма (процедура) (англ. subroutine) —
поименованная
или
иным
образом
идентифицированная часть программы, содержащая
описание определённого набора действий.
Подпрограмма может быть многократно вызвана из
разных частей программы.

13. Пример подпрограммы

Type Mass=array of integer;
Var M:mass;
//подпрограмма перестановки эл-ов массива
Procedure Swap(var A:Mass; i,j:integer);
Var buf:integer;
Begin
Buf:=A[i];
A[i]:=A[j];
A[j]:=buf;
End;
…
Begin
…
Swap(M,0,1);
if maxpos<>high(M) then Swap(M,maxpos,n)
End.

14. Назначение подпрограмм

Подпрограммы изначально появились как средство
оптимизации программ по объёму занимаемой памяти —
они позволили не повторять в программе идентичные
блоки кода, а описывать их однократно и вызывать по
мере необходимости. К настоящему времени данная
функция подпрограмм стала вспомогательной, главное
их назначение — структуризация программы с целью
удобства её понимания и сопровождения.

15. Процедуры и функции

Стандартные:
Sin(),
PROGRAM
<имя программы>;
USES <Список модулей>;
TYPE <Описание
типов данных>;
Round(),
CONST
<Описание констант>;
Sqrt(),
VAR
<Описание переменных>;
Length(),
Procedure …;
Function …:
High()
Readln(),
Writeln(),
;
BEGIN
<Последовательность операторов
алгоритма>
END.
Пользовательские (описываются программистом
в разделе описания процедур)

16. Подпрограммы (п/п) по своей структуре представляют собой мини-программы и имеют ту же структуру, что и программа:

Структура подпрограммы (п/п)
Подпрограммы (п/п) по своей структуре
представляют собой мини-программы и имеют ту
же структуру, что и программа:
USES <Список модулей>;
TYPE <Описание типов данных>;
CONST <Описание констант п/п>;
VAR
<Описание переменных>;
<Описание вложенных
процедур/функций>;
BEGIN
<Последовательность вызовов п/п>
END;
Procedure Summa(var A:Mass);
Var S:integer; i:byte;
Begin
S:=0;
for i:=0 to high(A) do
S:=S+A[i];
End;
Function Summa (var A:Mass): integer;
Var
i:byte;
Begin
result:=0;
for i:=0 to high(A) do
result+=A[i];
End;

17. Основное назначение подпрограмм – структуризация программы!!

Задача 1. Разработать программу упорядочивания
массива целых чисел А(n), где n 20 методом
сортировки простым выбором по неубыванию.
Разобьем задачу на подзадачи:
1 шаг. Заполнение, вывод массива.
2 шаг. Упорядочивание элементов по возрастанию.
3 шаг. Вывод отсортированного массива.
Каждый шаг оформим в виде п/п.

18.

Type Mass=array of integer;
Var A:Mass;
Begin
A:=Input(N);
Out(A);
Sort(A);
Out(A);
End.

19.

Type Mass=array of integer;
Var A:mass; i,j,n:byte;
function Input(N:integer):Mass;
Begin
setlength(result,n);
for i:=0 to n-1 do
result[i]:=random(-100,100);
End;
Procedure Out(A:Mass);
Begin
for i:=0 to high(A) do
Write(A[i]:5);
writeln;
End;
Procedure Sort(A:mass);
Begin
…
end;
//основной блок программы
Begin
n:=1000;
A:=Input(n);
Out(A);
Sort(A);
Out(A);
End.

20. Процедуру сортировки тоже можно структурировать:

Procedure Sort(var A:Mass);
Var i,pos:integer;
Function Poisk_max(n:integer) :integer;
Var max:integer;
begin
max:=a[0]; result:=0;
for j:=1 to n do
if A[j]>max then
begin
max:=A[j];
result:=j;
end;
end;
Begin
for dl:=high(A) downto 1 do
begin
pos:=Poisk_max(dl);
if ind<>dl then swap(A[dl],A[pos]);
end;
End;

21. Задача

Даны три массива А(n), B(m), C(n+m).
Решить квадратное уравнение ax2+bx+c=0,
где a, b, c - среднее арифметическое значение
соответствующих массивов.

22.

Program Uravn_;
Type Massiv=array of integer;
Var S,a,b,c:real;
MA,MB,MC:Massiv;
Procedure Creat;
Var i:byte;
begin
setlength(MA,n);
for i:=0 to n-1 do
МА[i]:=random(100);
end;
BEGIN
Creat;
Чтобы процедура работала
с массивом любого размера
необходимо ее
параметризовать
Процедура
работает только с
массивом MA из n
элементов.
Чтобы процедура работала
с любым массивом любого
размера необходимо ее
параметризовать

23.

Const n=5; m=10;
Type Massiv=array of integer;
Var
S,a,b,c:real;
MA,MB,MC:Massiv;
Формальные
параметры
Procedure Creat (var M:Mass; n:integer);
begin
setlength(M,n);
For var i:=0 to n-1 do
M[i]:=random(100);
end;
BEGIN
Creat(MA,n);
Creat(MB,m);
Creat(MC,n+m);
Фактические
параметры
При передаче фактических
параметров необходимо
соблюдать:
▪ Количество
▪ порядок
▪ совпадение типов
соответствующих фактических и
формальных параметров.

24. Функция создания массива

Const n=5; m=10;
Type Massiv=array of integer;
Var S,a,b,c:real;
MA,MB,MC:Massiv;
function Creat (n:integer):Mass;
begin
setlength(result,n);
For var i:=0 to n-1 do
result[i]:=random(100);
end;
BEGIN
MA:=Creat(n);
MB:=Creat(m);
MC:=Creat(n+m);
Фактические
параметры
Формальные
параметры

25. Обмен данными между п/п

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

26.

ПЕРЕДАЧА ДАННЫХ ПО ССЫЛКЕ И ПО ЗНАЧЕНИЮ
Передача по
значению
Передача по
ссылке
Var a,m,k:integer;
Procedure krat(x:integer; var y:integer);
Begin
X:=2*x;
Y:=x*y;
При компиляции программы для формальных
End;
параметров память не выделяется.
Begin
k:=5; m:=2;
При вызове процедуры в программе
krat(k,m);
передаваемые через фактические параметры
данные записываются в отдельную область
памяти, называемую стеком.
Параметры, передаваемые по значению и
параметры, передаваемые по ссылке
записываются в стек различными способами.

27. Передача данных по значению

ПЕРЕДАЧА ДАННЫХ ПО
ЗНАЧЕНИЮ
При передаче по значению в стек копируются
данные фактического параметра.
Например, при вызове Procedure
krat(x:integer; var y:integer);
в стеке отводится память под переменную x,
равная 4 байтам.

28. Передача данных по значению

ПЕРЕДАЧА ДАННЫХ ПО ЗНАЧЕНИЮ
Var
x,y:integer;
Передача по
значению
Procedure Swap (a,b:integer);
begin
var buf:=a;
a:=b;
b:=buf;
end;
BEGIN
(x,y):=(12,8);
Swap(x,y);
Print(x,y);
// 12 8
При передаче по значению в стек
копируются данные фактического
параметра.
В этом случае, в стеке находится копия
переменной, являющейся фактическим
параметром.

29. Передача данных по ссылке

ПЕРЕДАЧА ДАННЫХ ПО ССЫЛКЕ
Var
x,y:integer;
Передача по
ссылке
Procedure Swap (var a,b:integer);
begin
var buf:=a;
a:=b;
b:=buf;
end;
BEGIN
(x,y):=(12,8);
Swap(x,y);
Print(x,y);
// 8 12
При передаче по ссылке в стек
копируются ссылки фактических
параметроы.

30. Передача данных по ссылке

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

31.

Type Mass=array of integer;
Var A:Mass; B:Mass:=|12,7,5,19,3,15,9,24|;
function Find (key:integer; a:Mass):integer;
Begin
result:=-1;
var i:integer:=0;
while (i<length(a)) and (a[i]<>key) do
i+=1;
if i=length(a) then result:=-1 else result:=i;
End;
procedure Delete(key:integer; var a:Mass);
begin
var pos:=find(key,a);
for var i:=pos to high(a)-1 do
Передача по
a[i]:=a[i+1];
ссылке
setlength(a,length(a)-1);
end;
//исполнительная часть программы
Begin
A:=Inp_Mas(10,-50,50);
a.println;
var key:=readlninteger(‘введите число ’);
delete(key,a);
a.println;

32. Принципы структурного программирования

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

33.

Глобальные и локальные
переменные
Принцип закрытой
информации

34.

Type Mass=array of integer;
Var A:Mass; key:integer;
Локальные
переменные
procedure Delete(key:integer;var a:Mass);
Глобальные begin
var pos:=find(key,a);
переменные
for var i:=pos to high(a)-1 do
a[i]:=a[i+1];
setlength(a,length(a)-1);
end;
Begin
A:=Inp_Mas(10,-50,50);
a.println;
key:=readlninteger();
delete(key,a);
a.println;
End.
Память под локальные
переменные выделяется
только при вызове
подпрограммы,
следовательно, существуют
они только пока выполняется
подпрограмма.
Передача по
ссылке
Недоступность локальных
переменных в программе и в других
подпрограммах обеспечивает так
называемый принцип «закрытой
информации» подпрограмм от
влияния извне. То есть в других
подпрограммах и в программе
можно использовать идентичные
идентификаторы, и они будут
считаться различными
идентификаторами.

35. Перегрузка имен подпрограмм

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

36. Перегрузка имен подпрограмм

function NOD(a,b:integer):integer;
begin
while (a<>0) and (b<>0) do
if a>b then a:=a mod b
else b:=b mod a;
result:=a+b
end;
function NOD(a,b,c:integer):integer;
begin
result:=Nod(Nod(a,b),c);
end;
begin
println(Nod(14,56));
print(Nod(8, 56,128));
end.

37.

Перегрузка имен подпрограмм
function Sred(a,b:integer):real;
begin
result:=(a+b)/2
end;
function Sred(a,b:real):real;
begin
result:=(a+b)/2
end;
function Sred(a,b,c:integer):real;
begin
result:=(a+b+c)/3;
end;
begin
println(Sred(0.14,5.6));
print(Sred(8, 56,128));
end.

38. Параметры процедурного типа используют, когда нужно передать в подпрограмму имена процедур и функций.

Параметры процедурного типа
Параметры процедурного типа используют, когда нужно передать в
подпрограмму имена процедур и функций.
type funct=function(x:integer):boolean;
function krat3(x:integer):boolean;
begin
result:= x mod 3=0;
end;
function filtr(a:array of integer; priznak :funct):array of
integer;
var k:integer;
begin
setlength(result,length(a));
k:=0;
for var i:=0 to high(a) do
if priznak(a[i])
then begin
begin
result[k]:=a[i];
var a:=|13, 3, 45,8,38|;
k+=1
print(filtr(a,krat));
end;
end.
setlength(result,k);
end;

39. Переменное число параметров

function Sum(params a: array of integer): integer;
begin
Result := 0;
for i: integer := 0 to Length(a)-1 do
Result+=a[i];
end;
begin
var s: integer := Sum(1,2,3,4,5);
s := s + Sum(6,7);
writeln(s);
end.

40. Параметр по умолчанию

Type Mass=array of integer;
Var A:Mass; key:integer;
procedure Delete(var a:Mass;pos:integer:=0);
begin
for var i:=pos to high(a)-1 do
a[i]:=a[i+1];
setlength(a,length(a)-1);
end;
Begin
A:=|-17,64,-2,12,54|;
a.println;
delete(a);
a.println; //[64,-2,12,54]
delete(a,2);
a.println; //[64,-2,54]
End.
English     Русский Правила