Целые типы данных в Pascal

Создано: 15.04.2026

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

{$mode objfpc}

begin
    writeln(sizeof(shortint));  // 1
    writeln(sizeof(smallint));  // 2
    writeln(sizeof(integer));   // 4 (2, если без директивы)
    writeln(sizeof(longint));   // 4 
    writeln(sizeof(int64));     // 8

    writeln(sizeof(byte));      // 1
    writeln(sizeof(word));      // 2
    writeln(sizeof(longword));  // 4
    writeln(sizeof(cardinal));  // 4
    writeln(sizeof(qword));     // 8
end.

Поскольку до этого мы использовали компилятор fpc без включения совместимости c диалектом Object Pascal, то так и продолжим. Поэтому для нас тип integer будет размером в 2 байта, а smallint окажется его синонимом, который можно не учитывать. Также, несмотря на то, что longword и cardinal имеют некоторые различия в своем назначении, оставим в рассмотрении только longword.

На что влияет размер памяти, который отводится под переменную того или иного типа? Чем больше памяти выделяется, тем больший диапазон значений может принимать переменная данного типа. Ведь если дается только один байт (8 битов), то в нем в двоичном представлении можно закодировать только 256 разных десятичных значений. Другими словами, разных комбинаций нулей и единиц может быть только 256, и каждая из этих комбинаций сопоставляется своему десятичному числу. Хотя всего значений 256, максимальное из них будет 255, так как 256-е отводится на представление нуля. Число 256 получается, если 2 возвести в степень 8. это Здесь 2 — это основание двоичной системы счисления, а 8 — число битов. 28дает количество возможных комбинаций.

Следуя этой логике, если под переменную дается уже 2 байта (16 битов), то возможных десятичных значений будет 216 = 65536.

Если под переменную отводится 4 байта (32 бита), то возможных десятичных значений будет 232 = 4 294 967 296.

Если под переменную отводится 8 байт (64 бита), то возможных десятичных значений будет 264 = 18 446 744 073 709 551 616.

Теперь вспомним, что числа бывают не только положительные, но и отрицательные. Половину комбинаций нулей и единиц приходится отдавать под отрицательные значения, а значит максимальное десятичное из положительных будет в случае integer уже не 65536-1 (минус единица, так как одна комбинация отводится на 0), а в два раза меньше.

В коде выше обратим внимание, что во второй его половине, несмотря на другие названия типов данных, объем выделяемой под них памяти такой же как в первой половине. По 1 байту выделяется под shortint и byte, по 2 байта — под integer и word, по 4 — под longint и longword. Дело в том, что в Паскале есть беззнаковые типы данных, которые могут содержать только положительные числа и ноль. Это позволяет, если отрицательные числа не нужны, увеличить диапазон положительных значений при том же объеме выделяемой памяти.

Наиболее используемые целые типы в Pascal

Тип Диапазон допустимых значений Отводимая память, в байтах
shortint -128 ... 127 1
byte    0 ... 255 1
integer -32 768 ... 32 767 2
word       0 ... 65 535 2
longint -2 147 483 648 ... 2 147 483 647 4
longword              0 ... 4 294 967 295 4

Минимально и максимально допустимые для данного типа значения можно посмотреть с помощью программного кода. Для этого надо передать переменную определенного типа или название типа в стандартные функции low и high:

var
    a: int64;

begin
    writeln(low(a));  // -9223372036854775808
    writeln(high(a)); // 9223372036854775807
end.

Проверьте границы диапазонов нескольких других типов.

Кроме того, в Паскале есть специальные встроенные переменные, хранящие максимальные значения типа. Так для integer это переменная maxint.

Выведете на экран значение переменной maxint.

Что будет, если присвоить переменной значение, выходящее за границы ее диапазона? Ответ на этот вопрос зависит от настроек компилятора. Если добавить директиву {$R+}, то он будет выдавать ошибку, а без нее — только предупреждение. При этом не помещающиеся в память старшие разряды числа в его двоичном представлении будут просто выброшены. В результате вы увидите другое число. Для нас оно получится такое, как если бы мы "ходили" по кругу чисел:

var
    a: byte;
begin
    a := 258;
    writeln(a);  // 2
end.

В примере на экран будет выведено число 2, потому что предел для типа byte — значение 255. Прибавляя единицу, получаем ноль (представьте, что числа расположены на окружности), прибавляя еще единицу, получаем 1, еще одна дает в результате 2. Таким образом, 255 + 3 дает не 258, а 2.

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

Рассмотрим такой код:

var
    a, b, c: byte;
begin
    readln(a, b);    // 100 200
    writeln(a + b);  // 300
    c := a + b;
    writeln(c);      // 44
end.

Помним, что byte — это значения от 0 до 255 включительно. Пусть мы вводим допустимые для типа числа: 100 и 200. Только вот их сумма уже превысит предел типа и при присваивании переменной того же типа произойдет отбрасывание старших разрядов. Это видно по значению c. Однако почему сумма, которая не присваивается переменной, а сразу выводится на экран, верна? Дело в том, что сами вычисления выполняются в процессоре. Он помещает исходные числа в свои 32-битные или 64-битные регистры. В регистры такого же размера он помещает результат. Поскольку нет команды на запись числа в переменную, то оно не уходит в оперативную память, а как бы сразу отправляется на экран. То есть старшие биты не "обрезаются".

Убедитесь, что если указать директиву {$R+}, программа выше при переполнении будет выдавать ошибку времени выполнения. Как доказать, что ошибка возникает на этапе присвоения переменной c, а не вывода суммы как есть?

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

Стандартные функции и процедуры Pascal, применимые к аргументам целых типов

Функция Тип результата Результат выполнения
abs(x) Целый Модуль x (абсолютная величина x)
odd(x) Логический Значение true, если x — нечетное число; false — если четное.
succ(x) Целый Следующее значение x (x+1)
pred(x) Целый Предыдущее значение x (x-1)
sqr(x) Целый Квадрат x
sqrt(x) Вещественный Квадратный корень из x
sin(x) Вещественный Синус x (угол в радианах)
cos(x) Вещественный Косинус x (угол в радианах)
arctan(x) Вещественный Арктангенс x (угол в радианах)
ln(x) Вещественный Натуральный логарифм x
exp(x) Вещественный Экспонента x
random(x) Целый Случайное целое число из интервала 0..x-1.

Также в Pascal есть процедуры inc и dec, которым передается один или два параметра целого типа (первый параметр всегда должен быть переменной, то есть число должно передаваться через переменную). Если параметров два, то значение первого увеличивается (для inc) или уменьшается (для dec) на величину, равную значению второго параметра. Например, inc(x, 2) равнозначно x + 2. Если параметр один, то его значение увеличивается (для inc) или уменьшается (для dec) на единицу. Например, dec(x) равнозначно x-1.

Процедуры inc и dec изменяют значение переданной в них переменной, они ничего не возвращают в программу. Это их важное отличие от функций succ и pred.

var a, b, c: byte;
begin
    a := 100; b := 100;

    inc(a);  // изменяет переменную-параметр
    b := succ(b); {* возвращает новое значение,
                 которое можно присвоить любой переменной *}  
    writeln('a = ', a, ', b = ', b);

    dec(a);
    c := pred(b);
    writeln('a = ', a, ', b = ', b, ', c = ', c);

    inc(a, 3);
    writeln('a = ', a);
end.
a = 101, b = 101
a = 100, b = 101, c = 100
a = 103

Задания для дополнительной или самостоятельной работы:

  1. Подумайте, зачем в языках программирования (хотя и не всех) существует несколько типов для целочисленных данных, а также для вещественных?
  2. Напишите программу с циклом while, в котором вместо изменения переменной–счетчика с помощью сложения/вычитания используется процедура inc или dec.