Алгоритм — это точная последовательность шагов, которая по заданным входным данным приводит к результату за конечное число действий. В программировании алгоритм записывают на языке, понятном компьютеру. В статье разбираем три базовых типа алгоритмов и три классические задачи (факториал, НОД, НОК) на языке Pascal, с рабочим кодом и пошаговым прогоном вручную.
Содержание
Код проверен в Free Pascal Compiler (FPC) версии 3.2.x, дата проверки 19.09.2026. Тот же синтаксис (program, var, begin/end, for, while, if-then-else) без изменений выполняется и в PascalABC.NET — учебной среде, которая в российских школах и вузах распространена не меньше классического FPC.
Pascal сегодня — учебный язык
Важная оговорка сразу: в 2026 году Pascal почти не встречается в промышленной разработке — там доминируют Python, Java, C#, C++, JavaScript. Но как первый язык для изучения алгоритмов он остается востребован: строгая типизация и явная структура program-var-begin-end заставляют формулировать логику по шагам, а не угадывать синтаксис.
Поэтому если цель — разобраться именно с алгоритмическим мышлением (а не выучить язык для работы), Pascal подходит не хуже Python. Дальше в статье все примеры сохраняют эту цель: не просто код, а разбор того, почему он устроен именно так.
Три типа алгоритмов: таблица
| Тип | Что делает | Ключевая конструкция Pascal | Пример в статье |
|---|---|---|---|
| Линейный | Шаги выполняются один раз, по порядку, без ветвлений и повторов | Последовательность операторов через ; |
Объем и площадь куба |
| Разветвленный | Выбирает одну из веток в зависимости от условия | if ... then ... else |
Проверка числа на четность |
| Циклический | Повторяет блок кода заданное число раз или пока верно условие | for ... to ... do, while ... do |
Факториал, НОД и НОК |
Ниже — каждый тип с рабочим примером. Порядок совпадает с таблицей: от простого к сложному.
Линейный алгоритм: объем и площадь куба
Линейный алгоритм — самый простой: он не проверяет условий и не повторяет шагов, каждая команда выполняется ровно один раз. Пример: по длине ребра куба a нужно посчитать объем (a в кубе) и площадь поверхности (6 умножить на a в квадрате).
program CubeCalc;
var
a, volume, area: real;
begin
a := 5;
volume := a * a * a;
area := 6 * a * a;
writeln('Objem kuba: ', volume:0:2);
writeln('Ploshad poverkhnosti: ', area:0:2);
end.
При a = 5 программа выведет:
Objem kuba: 125.00
Ploshad poverkhnosti: 150.00
Здесь :0:2 — формат вывода вещественного числа с двумя знаками после запятой. Без него Free Pascal выведет число в экспоненциальной записи вида 1.2500000000E+002, что неудобно читать.
Разветвленный алгоритм: проверка числа на четность
Разветвленный алгоритм выбирает одну из двух (или больше) веток в зависимости от условия. Классический пример — определить четность числа через остаток от деления.
program EvenOdd;
var
n: integer;
begin
n := 7;
if n mod 2 = 0 then
writeln(n, ' - chetnoe chislo')
else
writeln(n, ' - nechetnoe chislo');
end.
Вывод для n = 7:
7 - nechetnoe chislo
mod — оператор остатка от деления. Если остаток от деления на 2 равен нулю, число четное, иначе нечетное. Эта же конструкция if-then-else лежит в основе любого ветвления: сравнения, поиск максимума, обработку граничных случаев строят по тому же принципу — одно условие, две ветки.
Циклический алгоритм: факториал числа
Факториал числа n (обозначается n!) — произведение всех натуральных чисел от 1 до n. По определению 0! = 1. Прежде чем писать код, полезно прогнать вычисление вручную для n = 5 и увидеть, как меняется накопленный результат на каждом шаге.
Шаг за шагом (result начинается с 1):
— i = 1: result = 1 * 1 = 1
— i = 2: result = 1 * 2 = 2
— i = 3: result = 2 * 3 = 6
— i = 4: result = 6 * 4 = 24
— i = 5: result = 24 * 5 = 120
Итог: 5! = 120. Цикл for просто повторяет один и тот же шаг (умножить накопленный результат на текущее i), меняя i от 1 до n.
program Factorial;
var
n, i: integer;
result: int64;
begin
n := 5;
result := 1;
for i := 1 to n do
result := result * i;
writeln(n, '! = ', result);
end.
Вывод:
5! = 120
Тип int64 взят не случайно: обычный integer в Free Pascal — это 4 байта (диапазон примерно до 2 млрд), а факториал растет очень быстро — уже 13! превышает этот диапазон. int64 (8 байт) выдерживает корректные значения до 20!, дальше переполняется и он.
Типичная ошибка: забыли начальное значение
Неверный вариант того же кода — без строки result := 1; перед циклом:
program FactorialBug;
var
n, i: integer;
result: int64;
begin
n := 5;
for i := 1 to n do
result := result * i;
writeln(n, '! = ', result);
end.
В Free Pascal глобальные переменные по умолчанию инициализируются нулем. Значит, на первой итерации выполнится result := 0 * 1, и result так и останется нулем на всех следующих шагах:
5! = 0
Исправление — одна строка: явно присвоить result := 1; до начала цикла (умножение начинают с нейтрального элемента, а для умножения это 1, а не 0). Правило простое: у любой накопительной переменной перед циклом должно быть явное начальное значение, не полагаться на умолчание среды.
НОД и НОК: алгоритм Евклида
Наибольший общий делитель (НОД) двух чисел — самое большое число, на которое оба числа делятся без остатка. Наименьшее общее кратное (НОК) — самое маленькое число, которое делится на оба без остатка. Их связывает формула: НОД(a, b) * НОК(a, b) = a * b.
Для НОД используем алгоритм Евклида: пока второе число не равно нулю, заменяем пару (a, b) на пару (b, a mod b). Прогон вручную для a = 48, b = 18:
- (48, 18): 48 mod 18 = 12, новая пара (18, 12)
- (18, 12): 18 mod 12 = 6, новая пара (12, 6)
- (12, 6): 12 mod 6 = 0, новая пара (6, 0)
- b = 0, значит НОД = 6
НОК считаем по формуле через уже найденный НОД: (48 * 18) / 6 = 144.
program GcdLcm;
var
a, b, x, y, temp, gcd, lcm: integer;
begin
a := 48;
b := 18;
x := a;
y := b;
while y <> 0 do
begin
temp := y;
y := x mod y;
x := temp;
end;
gcd := x;
lcm := (a * b) div gcd;
writeln('NOD(', a, ', ', b, ') = ', gcd);
writeln('NOK(', a, ', ', b, ') = ', lcm);
end.
Вывод:
NOD(48, 18) = 6
NOK(48, 18) = 144
Значения совпадают с ручным прогоном. Обратите внимание: формула (a * b) div gcd корректна только для integer-диапазона — при больших a и b произведение может переполниться раньше, чем произойдет деление; в таком случае сначала делят одно из чисел на НОД, а затем умножают на второе ((a div gcd) * b).
Выводы
- Три базовых типа алгоритма — линейный, разветвленный и циклический — различаются только тем, повторяются шаги или нет и есть ли выбор ветки.
- Факториал и НОД/НОК — учебные, но показательные примеры циклического алгоритма: накопление результата и итеративное сужение задачи (алгоритм Евклида).
- Забытое начальное значение накопительной переменной — частая ошибка новичка: в Free Pascal она молча даст ноль вместо явной ошибки компиляции.
- Тип переменной нужно выбирать под диапазон значений: integer переполняется на факториале уже при n = 13, для больших n нужен int64 или библиотека длинной арифметики.
- Pascal остается рабочим инструментом именно для изучения алгоритмов, а не для промышленной разработки в 2026 году.
Где применяется / связь с практикой
Разбор алгоритмов на Pascal — обычно первый шаг перед изучением структур данных, сложности алгоритмов и других языков программирования. Тот же алгоритм Евклида или та же логика ветвления один в один переносится на Python, C++ или Java — меняется только синтаксис.
Освойте тему на практике
Если хочется системно пройти путь от алгоритмов и структур данных до полноценной разработки, на курсе Алгоритмы и структуры данных разбирают эту базу на практике, с обратной связью от преподавателей.
Освойте тему на практике
Проверить формат обучения и позадавать вопросы можно на открытых уроках Otus: расписание открытых уроков.
Смежные темы: Циклы: особенности и определение, Основные синтаксические конструкции и ветвление if-else-then, Сортировка Хоара и другие способы сортировки массивов.
FAQ
Чем Free Pascal отличается от PascalABC.NET?
Free Pascal — классический компилятор с синтаксисом, близким к историческому Turbo Pascal и Delphi. PascalABC.NET — учебная среда на платформе .NET с более современными надстройками (например, встроенные множества и последовательности), но базовый синтаксис program-var-begin-end и операторы, показанные в статье, работают в обеих средах одинаково.
Можно ли посчитать факториал рекурсией вместо цикла?
Да, факториал классически реализуют и рекурсивной функцией, которая вызывает саму себя с уменьшенным аргументом до базового случая n = 0. Результат будет тот же, но у рекурсии есть ограничение по глубине стека вызовов, поэтому для больших n итеративный вариант через цикл надежнее.
Что будет, если в алгоритме Евклида передать b = 0 сразу?
Цикл while y <> 0 не выполнится ни разу, и gcd останется равным исходному x, то есть НОД(a, 0) = a. Это математически корректный частный случай, отдельная проверка не нужна.



