Pascal / Free Pascal — типовые программы

Приветствую! Здесь вы наверняка найдете, что ищете. Примеры в лаборатории рассчитаны на то, что мы разбираем что-то конкретное.

Текущая статья посвящена примерам: Pascal и Free Pascal с разбором каждой строки.

Поэтому за теорией по текущей теме вам — в энциклопедию. Если ещё не погружались, то маршрут прост:

  1. Основы
  2. Система и сеть
  3. Данные и разметка
  4. Код и разработка
  5. Языки
  6. Искусственный интеллект
  7. Проект
  8. Инфраструктура и безопасность
  9. Спин-офф

Обязательно пройдитесь.

А теперь приступим к нашему предмету.

Теория и соседние материалы

Учебный курс — Pascal — о разделе, установка и первая программа — глава 7, синтаксис по диалектам — справочник.

Школьная среда Windows — PascalABC.NET.

Те же алгоритмы на Python — ЕГЭ и олимпиадка, на C++ — олимпиадные шаблоны.


Навигация по запросам

Типичный запрос Куда на странице
pascal hello world, program begin end Обязательный каркас
pascal readln пример, read readln разница Read и ReadLn
pascal сумма двух чисел Сумма двух чисел
сумма элементов массива pascal, pascal массив readln Шаблон B
найти максимум в массиве pascal Максимум в массиве
fizzbuzz pascal FizzBuzz
факториал pascal, factorial pascal Факториал
fibonacci pascal, числа фибоначчи pascal Фибоначчи
сортировка пузырьком pascal, bubble sort pascal Пузырёк
палиндром pascal, строка палиндром pascal Палиндром
НОД pascal, алгоритм евклида pascal НОД
простое число pascal, решето эратосфена pascal Решето
файл text pascal, readln из файла pascal Файлы
procedure function pascal пример Процедуры и функции
pascal ошибка end, end. или end; Частые ошибки
количество цифр в числе pascal Количество цифр
линейный поиск pascal, найти элемент в массиве Линейный поиск

Навигация по примерам

Раздел Тема
Read и ReadLn разница, типичная ловушка
Каркас программы program begin end, writeln pascal
Шаблоны ввода-вывода readln pascal, массив из n чисел
Стартовые задачи сумма, максимум, FizzBuzz, факториал
1. Массивы array of integer, SetLength
2. Процедуры и функции procedure, function, var параметр
3. Сортировка и поиск пузырёк, линейный и бинарный поиск
4. Строки Length, Copy, Pos, палиндром
5. Числа НОД, простое число, числа Фибоначчи
6. Записи и множества record, set of
7. Файлы text, Assign, Reset, Rewrite
8. Меню и цикл программы repeat until, case
9. Шпаргалка формат вывода, несколько тестов
10. Популярные запросы сумма массива, цифры, поиск, min
Частые ошибки end. vs end;, типы в readln

Основы решения задач на Pascal

На контрольной, ЕГЭ и олимпиаде программа почти всегда устроена одинаково:

  1. Объявить переменные в разделе var (и при необходимости const, type).
  2. Прочитать вход через Read, ReadLn или из файла.
  3. Посчитать ответ — цикл, массив, процедура, сортировка.
  4. Вывести ровно то, что просят — через Write / WriteLn, без лишних подписей.

Стандартной библиотеки FPC достаточно для большинства школьных задач: массивы, строки, text, Math (корень, тригонометрия).

Четыре шага любой задачи на контрольной:

Шаг Что делаете Типичный код
1 Объявляете переменные var n, i: integer;
2 Читаете вход ReadLn(n);
3 Считаете ответ for, if, массив, функция
4 Печатаете только ответ WriteLn(sum); — без «Ответ:»

Read и ReadLn — главная ловушка новичка

В Pascal два способа читать с клавиатуры. Путаница между ними — самая частая причина «программа читает не то».

Read(x) / Read(a, b) ReadLn(x)
Читает Число (или несколько через пробел) То же
Перевод строки после числа Оставляет в буфере Съедает до конца строки
Когда брать Несколько чисел подряд в одной строке Одно число, или строка текста
После цикла Read Нужен ReadLn; «вхолостую» Не нужен

Пример ловушки — программа «прочитала 0» или «зависла»:

var
  n: integer;
  s: string;
begin
  Read(n);      { прочитали 5, но Enter остался в буфере }
  ReadLn(s);    { сразу читает ПУСТУЮ строку — s = '' }
end.

Исправление: после Read(n) добавить ReadLn; или сразу писать ReadLn(n).

Правило для ЕГЭ

Если в условии «первая строка — n, вторая — n чисел», схема почти всегда такая: ReadLn(n) → цикл Read(a[i])ReadLn; в конце. Так вы не «проглотите» начало следующего блока ввода.


Обязательный каркас

Любая консольная программа на Free Pascal — это заголовок, объявления и тело. Точка после финального end обязательна: без неё компилятор ждёт продолжение файла.

Анатомия файла:

program Имя;     ← имя программы (в Lazarus = имя проекта)
const ..        ← необязательно: MAXN = 100000
type ..         ← необязательно: record, массивы-типы
var ..          ← переменные — ОБЯЗАТЕЛЬНО до begin
procedure ..    ← необязательно: подпрограммы
function ..
begin            ← с этого места идут команды
  ..
end.             ← точка! не точка с запятой
program Task;

var
  n: integer;

begin
  ReadLn(n);
  WriteLn(n * 2);
end.

Разбор построчно:

Строка Смысл
program Task; Объявляет имя программы. В Lazarus должно совпадать с именем .lpr/проекта.
var Начало раздела переменных. В Pascal нельзя писать var n: integer внутри begin — только здесь.
n: integer Целое 32 бита (−2·10⁹ … 2·10⁹). Для больших сумм берите int64.
begin Старт исполняемых команд.
ReadLn(n) Ждёт ввод пользователя (или строку из input.txt при < input.txt), кладёт число в n.
WriteLn(n * 2) Печатает результат и перевод строки. Проверяющая система на ЕГЭ смотрит сюда.
end. Конец программы. end. — с точкой; end; — только у вложенных блоков (if, for).

Hello World — минимум для проверки среды:

program Hello;

begin
  WriteLn('Hello, Pascal!');
end.
Строка Что происходит
WriteLn('..') Вывод строки + перевод курсора на новую строку.
Write(..) Вывод без перевода строки — следующий Write продолжит ту же строку.
'Hello, Pascal!' Строковый литерал в одинарных кавычках.
'' внутри строки Два апострофа подряд = один символ '. Пример: 'it''s ok'.

Пример:

Запуск: hello.exe
Выход: Hello, Pascal!

Присваивание в Pascal — :=, не =:

Символ Где
:= Присвоить значение переменной: sum := sum + x
= Сравнение в if: if x = 0 then

Шаблоны ввода-вывода

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

Формат входа в условии Шаблон
Одно число A
Сначала n, потом n чисел (часто на второй строке) B
Числа в одной строке через пробел, без n E
n неизвестно заранее / очень большой массив C
В начале t — число тестов D

Шаблон A — одно число

Задача: pascal readln integer, удвоить число pascal.

Формулировка из учебника: «Дано целое n. Выведите удвоенное значение».

program DoubleNumber;

var
  n: integer;

begin
  ReadLn(n);
  WriteLn(n * 2);
end.

Пример:

Вход:  7
Выход: 14

Разбор построчно:

Строка Смысл
ReadLn(n) Читает целое и перевод строки после него. Безопасно, если дальше читаете строку текста.
WriteLn(n * 2) Одна строка ответа — ровно то, что ждёт автопроверка.

Смысл шаблона: «прочитал → посчитал → вывел». Основа для «квадрат числа», «чётное или нечётное одного числа», «факториал одного n».


Шаблон B — массив из n чисел

Запрос: сумма элементов массива pascal, pascal readln массив, массив из n элементов pascal.

Формулировка: «Первая строка — n. Вторая — n целых чисел. Выведите сумму».

Строка Зачем
const MAXN = 100000 В Pascal размер array[1.MAXN] задаётся константой при компиляции. Берите с запасом из условия (n ≤ 10⁵).
a: array[1.MAXN] of integer Статический массив; индексы с 1 — привычно в школьных задачах.
Второй цикл for i := 1 to n Отдельно читаем, отдельно считаем — так проще отлаживать на лабораторной.

Шаблон C — динамический массив (SetLength)

Когда n заранее неизвестно или больше константы MAXN:

Разбор:

Конструкция Смысл
array of integer Динамический массив — длина не фиксирована в var.
SetLength(a, n) Выделяет память под n элементов перед использованием.
for i := 0 to n - 1 В FPC динамические массивы по умолчанию с индекса 0.

В школьных задачах чаще проще array[1.MAXN] и цикл 1.n — меньше путаницы с нулём.


Шаблон D — несколько тестов (t в условии)

program ManyTests;

var
  t, n, i, caseNum: integer;

begin
  ReadLn(t);
  for caseNum := 1 to t do
  begin
    ReadLn(n);
    WriteLn('Case ', caseNum, ': ', n * 2);
  end;
end.

На ЕГЭ формат с t тестов редок; на Codeforces, informatics — частый.


Шаблон E — числа в одной строке без n

Запрос: pascal максимум в строке, найти max из чисел в строке pascal.

Формулировка: «В одной строке через пробел записаны целые числа. Выведите максимум» (количество заранее неизвестно — читаем до конца строки).

Пример:

Вход: 3 1 4 1 5
Выход: 5

Разбор:

Строка Смысл
while not Eof do Eof без параметра — конец стандартного ввода (строки). Пока есть числа — читаем.
first Первое число сразу становится maxVal — не с чем сравнивать.
ReadLn; Завершить строку ввода.

Альтернатива проще: если в условии всё же есть n — всегда берите шаблон B.


Стартовые задачи

Короткие программы из первых лабораторных — каждая с формулировкой, примером ввода-вывода и разбором.

Сумма двух чисел

Запрос: pascal сумма двух чисел, readln a b pascal.

Формулировка: «Даны два целых. Выведите их сумму».

program SumTwo;

var
  a, b: integer;

begin
  ReadLn(a, b);
  WriteLn(a + b);
end.

Пример:

Вход: 10 25
Выход: 35
Строка Смысл
ReadLn(a, b) Читает два числа подряд — через пробел или с новой строки.
WriteLn(a + b) Сумма — без текста «Сумма =».

Максимум в массиве

Запрос: найти максимум в массиве pascal, max array pascal.

Формулировка: «Первая строка — n. Вторая — n чисел. Выведите максимальный элемент».

Пример:

Вход:
4
3 9 1 5

Выход:
9

Разбор алгоритма:

  1. Первое число сразу кладём в maxVal — это «текущий лидер».
  2. Цикл с i := 2 — оставшиеся n−1 чисел сравниваем с лидером.
  3. if x > maxVal then maxVal := x — обновляем максимум, если нашли больше.

Почему не maxVal := 0? Если все числа отрицательные, ноль даст неверный ответ. Первый элемент массива — надёжная инициализация.


Чётные числа от 1 до n

Запрос: вывести четные числа pascal, pascal mod 2.

Формулировка: «Дано n. Выведите все чётные от 2 до n через пробел».

program Evens;

var
  n, i: integer;

begin
  ReadLn(n);
  for i := 2 to n do
    if i mod 2 = 0 then
      Write(i, ' ');
  WriteLn;
end.

Пример:

Вход: 10
Выход: 2 4 6 8 10
Строка Смысл
for i := 2 to n Сразу стартуем с 2 — не проверяем 1.
i mod 2 = 0 mod — остаток от деления; чётное = делится на 2 без остатка.
Write(i, ' ') Пробел между числами; WriteLn в конце — перевод строки после последнего.

FizzBuzz до n

Запрос: fizzbuzz pascal, fizz buzz программа pascal.

Формулировка: «Для каждого числа от 1 до n: если делится на 15 — FizzBuzz, на 3 — Fizz, на 5 — Buzz, иначе само число».

Пример (фрагмент):

Вход: 15
Выход:
1
2
Fizz
..
FizzBuzz

Почему порядок if важен: число 15 делится и на 3, и на 5. Проверка mod 15 первая — иначе сработает только «Fizz» или только «Buzz».


Факториал

Запрос: факториал pascal, factorial pascal program.

Формулировка: «Дано неотрицательное n. Выведите n!».

program Factorial;

var
  n, i: integer;
  fact: int64;

begin
  ReadLn(n);
  fact := 1;
  for i := 2 to n do
    fact := fact * i;
  WriteLn(fact);
end.

Пример:

Вход: 5
Выход: 120
Шаг fact i
старт 1
i=2 2 2
i=3 6 3
i=4 24 4
i=5 120 5

Граничный случай: n = 0 → цикл не выполняется, fact остаётся 1 (по определению 0! = 1).

Для n > 20 результат не помещается в int64 — в условии обычно маленькие n или просят остаток по модулю.


Числа Фибоначчи

Запрос: fibonacci pascal, n-ое число фибоначчи pascal.

Формулировка (вариант A): «Дано n (n ≥ 1). Выведите n-е число Фибоначчи: 1, 1, 2, 3, 5, …».

Пример:

Вход: 7
Выход: 13

Таблица итераций (F(1)=1, F(2)=1, …):

i a b c = a+b → новое b
3 1 1 2
4 1 2 3
5 2 3 5
6 3 5 8
7 5 8 13 ← ответ

Смысл: два переменных хранят «два последних» числа — без рекурсии (рекурсия на больших n медленная и может переполнить стек).

Формулировка (вариант B): «Выведите первые n чисел через пробел» — см. первые n чисел Фибоначчи.


Типовые программы по темам

1. Массивы

1.1. Подсчёт положительных элементов

Запрос: подсчитать положительные элементы массива pascal.

Пример:

Вход:
5
-1 0 3 4 -2

Выход:
2
Строка Смысл
cnt := 0 Счётчик до цикла — классический паттерн «накопитель».
if x > 0 Ноль не положительный; если в условии «неотрицательные» — x >= 0.

1.2. Разворот массива

Запрос: развернуть массив pascal, reverse array pascal.

Пример:

Вход:
4
10 20 30 40

Выход:
40 30 20 10

Как работает обмен:

i=1: меняем a[1] и a[4]
i=2: меняем a[2] и a[3]
(n div 2 = 2 — до середины, иначе перевернём дважды)
Выражение Смысл
n div 2 Целочисленное деление — «половина длины» без дроби.
a[n - i + 1] Симметричный элемент с конца: при i=1 это a[n].
tmp Третья «коробка» — без неё потеряете значение при обмене.

1.3. Префиксные суммы

Запрос: префиксные суммы pascal, сумма на отрезке массива pascal.

Формулировка: «Дан массив. Постройте префиксы. На каждый запрос [l, r] выведите сумму a[l]+…+a[r] за O(1)».

Пример:

Вход:
5
2 4 1 3 5
2
1 3
2 5

Выход:
7
9

Идея: pref[i] = сумма первых i элементов. Тогда сумма на [l, r] = pref[r] - pref[l-1] (для l=1 просто pref[r]).

Строка Смысл
pref[1] := a[1] База рекурренции.
pref[i] := pref[i-1] + a[i] К каждому префиксу прибавляем следующий элемент.
pref[r] - pref[l-1] «Вся сумма до r» минус «сумма до l−1» = отрезок [l, r].

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

Процедуры объявляют перед begin основной программы (или в отдельном unit).

2.1. Функция — простое ли число

Запрос: проверить простое число pascal, is prime pascal.

Пример:

Вход: 17
Выход: YES

Вход: 18
Выход: NO
Элемент Смысл
function .. : boolean Функция возвращает true / false.
IsPrime := .. Результат функции — как return в Python/Java.
exit Досрочный выход — не проверяем делители дальше.
trunc(sqrt(x)) Достаточно делителей до √x — если есть больший, есть и меньший.
x mod d = 0 Делится без остатка → составное.

Граничные тесты: n = 0, 1 → NO; n = 2 → YES.


2.2. Процедура с параметром var (обмен значений)

var перед параметром — передача по ссылке; процедура меняет переменные вызывающего кода.


2.3. Рекурсия — факториал

На больших n рекурсия может переполнить стек — на олимпиадах предпочитают цикл.


3. Сортировка и поиск

3.1. Сортировка пузырьком

Запрос: сортировка пузырьком pascal, bubble sort pascal, sort array pascal.

Пример:

Вход:
5
5 1 4 2 3

Выход:
1 2 3 4 5

Идея алгоритма: внешний цикл i — «сколько элементов уже встало на своё место с конца». Внутренний j сравнивает соседей; больший «всплывает» вправо как пузырь.

Один проход при n=5 (упрощённо):

j сравниваем меняем? массив
1 5 и 1 да 1 5 4 2 3
2 5 и 4 да 1 4 5 2 3
Строка Смысл
for j := 1 to n - i С каждым i последний элемент уже на месте — сравниваем на один пар меньше.
if a[j] > a[j + 1] Порядок возрастания; для убывания — <.

Для n > 10⁴ на контесте пузырёк получит TLE — там нужна быстрая сортировка; для лабораторной и понимания логики — идеален.


3.2. Бинарный поиск в отсортированном массиве


4. Строки

В FPC тип string — длинная строка (аналог Delphi AnsiString / UnicodeString в зависимости от режима).

4.1. Палиндром

Запрос: палиндром pascal, проверить палиндром строка pascal, string palindrome pascal.

Формулировка: «Дана строка. YES, если читается одинаково слева направо и справа налево».

Пример:

Вход: radar
Выход: YES

Вход: hello
Выход: NO

Разбор:

Строка Смысл
Length(s) Длина строки; индексы с 1, не с 0 — важно для Pascal.
s[i] i-й символ; <> — «не равно».
n div 2 Сравниваем только до середины — вторую половину не дублируем.
ok := false Достаточно одного несовпадения — можно было бы break, но для коротких строк цикл и так быстрый.

4.2. Подсчёт слов (упрощённо — по пробелам)


4.3. Поиск подстроки (Pos)

program FindSub;

var
  text, sub: string;
  p: integer;

begin
  ReadLn(text);
  ReadLn(sub);
  p := Pos(sub, text);
  WriteLn(p);
end.

Pos возвращает 1-based индекс первого вхождения или 0, если подстроки нет.


5. Числа

5.1. НОД (алгоритм Евклида)

Запрос: НОД pascal, gcd pascal, алгоритм евклида pascal.

Формулировка: «Даны два натуральных числа. Выведите их наибольший общий делитель».

Пример:

Вход: 48 18
Выход: 6

Таблица шагов для 48 и 18:

шаг a b t = a mod b
1 48 18 12
2 18 12 6
3 12 6 0
4 6 0 — → ответ a = 6
Строка Смысл
while b <> 0 Пока делитель не ноль — продолжаем.
Gcd := a Когда b = 0, НОД — текущее a.

5.2. Решето Эратосфена (простые до n)


5.3. Быстрое возведение в степень по модулю


6. Записи и множества

6.1. Запись — ученик

:0:2 — формат вещественного: 0 минимальной ширины, 2 знака после запятой.


6.2. Множество символов — гласные


7. Файлы

7.1. Чтение чисел из текстового файла

Запрос: pascal чтение из файла, assign reset pascal, read file text pascal.

Файл input.txt:

10 20 30

Выход программы: 60

Операция Смысл
Assign(f, 'имя') Связать переменную f с файлом на диске.
Reset(f) Открыть для чтения (файл должен существовать).
Rewrite(f) Создать новый или перезаписать с нуля.
Read(f, x) Прочитать следующее число из файла — как Read, но из f.
Eof(f) true, если достигнут конец файла.
Close(f) Закрыть — иначе файл может остаться «занятым».

Файл кладут в папку с .exe (в Lazarus: Run → Run Parameters → Working directory или скопировать input.txt в project1.exe).


7.2. Запись таблицы в файл


8. Интерактивное меню

repeat .. until — тело выполняется минимум один раз, в отличие от while.


9. Полезные приёмы

Форматированный вывод

WriteLn(x:5);       { целое, ширина поля 5 }
WriteLn(pi:8:4);    { вещественное, 4 знака после запятой }
WriteLn('x=', x);   { смешанный вывод }

Константа для размера массива

const
  MAXN = 100000;
var
  a: array[1.MAXN] of integer;

На олимпиаде MAXN берут с запасом из ограничения n в условии.


Подключение модуля Math

uses Math;

var
  x: double;
begin
  x := Sqrt(2);
  WriteLn(x);
end.

Sqrt, Sin, Cos, Power — из Math.


Полный каркас для контрольной (копировать в начало)


Дополнительные задачи

Дополнительные формулировки, по которым часто приходят на эту страницу — с тем же стилем разбора, что в Java — консольные задачи.

10.1. Линейный поиск в массиве

Запрос: найти элемент в массиве pascal, linear search pascal, index of element array pascal.

Формулировка: «Даны n, массив и число key. Выведите индекс первого вхождения key (с 1) или −1, если нет».

Пример:

Вход:
6
3 1 4 1 5 9
4

Выход:
3
Строка Смысл
index := -1 Договорённость «не найдено» — часто в условии олимпиады.
(index = -1) and .. Берём первое совпадение; без этого найдём последнее.
Сложность O(n) — один проход. На отсортированном массиве быстрее бинарный поиск.

10.2. Первые n чисел Фибоначчи

Запрос: вывести fibonacci pascal, последовательность фибоначчи pascal.

Формулировка: «Дано n. Выведите первые n чисел Фибоначчи через пробел: 1 1 2 3 5 …».

Пример:

Вход: 7
Выход: 1 1 2 3 5 8 13

Смысл: на каждом шаге печатаем текущее число и сдвигаем пару (a, b) — без хранения всего массива.


10.3. Количество цифр в числе

Запрос: количество цифр в числе pascal, count digits pascal.

Формулировка: «Дано неотрицательное целое. Сколько в нём цифр?»

Пример:

Вход: 12045
Выход: 5
Строка Смысл
n = 0 → 1 У нуля одна цифра — частый граничный тест.
n div 10 Отбрасываем последнюю цифру (12045 → 1204 → …).
while n > 0 Пока есть цифры — увеличиваем счётчик.

Альтернатива одной строкой: WriteLn(Length(IntToStr(n))); — короче, но на контрольной часто требуют цикл.


10.4. Сумма элементов массива (явное хранение)

Запрос: сумма элементов массива pascal — самый частый запрос по Pascal в учебниках.

Тот же код, что шаблон B, но с массивом — когда в следующей части задачи элементы нужны снова:

Когда копировать этот вариант: после суммы нужна сортировка, поиск или вывод только чётных a[i].


10.5. Минимум в массиве

Запрос: найти минимум в массиве pascal, min array pascal.

Логика зеркальна максимуму: первый элемент — в minVal, цикл с i := 2, условие if x < minVal.


Частые ошибки новичков

Ошибка Что происходит Как исправить
Забыли точку в end. Syntax error, компилятор ждёт продолжение Последний end программы — end.
Путаница end; и end. ; после вложенных блоков, . только в конце файла Внутри — end;, в конце — end.
Read без ReadLn после цикла Следующий ReadLn читает пустую строку После серии ReadReadLn; (подробнее)
Переполнение integer Верный алгоритм, неверный ответ int64 для сумм, факториалов, Фибоначчи
Индекс с 1 и с 0 Range check error Статический массив — цикл 1.n; динамический FPC — часто 0.n-1
Лишний текст в выводе Автопроверка: 0 баллов Только число/строка из условия — без «Ответ:»
Файл не найден Runtime error 2 input.txt рядом с .exe или полный путь в Assign

Неправильно vs правильно — end:

{ ОШИБКА — нет точки }
begin
  WriteLn(1);
end

{ ВЕРНО }
begin
  WriteLn(1);
end.

Неправильно vs правильно — вывод на ЕГЭ:

Условие: вывести сумму → 14

Плохо:  Сумма = 14
Плохо:  «14 » с пробелом в конце строки
Хорошо: 14
ЕГЭ и олимпиада

Формат вывода должен буквально совпадать с условием — пробелы, переводы строк, регистр YES/NO. На ЕГЭ проверяют автоматически. Перед сдачей прогоните примеры из условия и граничные случаи: n = 0, n = 1, отрицательные числа (если допустимы).


Pascal или Python?

На большинстве экзаменов и олимпиад сегодня удобнее Python или C++ — меньше возни с типами и форматом.

Pascal остаётся актуален там, где его требует программа школы, в legacy на Delphi/FPC и для дисциплины строгой типизации.

Сравнение диалектов — в справочнике.