l

Числовые типы данных, переменные и арифметические действия

28.09.2018 4082 Программируем на Паскале Ваш комментарий

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

Любая программа так или иначе обрабатывает какие-то данные, их необходимо где-то хранить.

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

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

Для хранения данных того или иного типа требуется разное количество ячеек памяти — разное количество байт. Вместо того, чтобы запоминать адрес каждой такой ячейки (вообще говоря, они могут располагаться очень далеко друг от друга), мы объявляем переменную — придумываем удобное имя, с помощью которого сможем обращаться к хранимым данным. Это то, что роднит высокоуровневые языки программирования. Но сам механизм переменных реализовывают очень по-разному.

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

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

Числовые типы данных Паскаля можно было бы поделить на два основных вида: целочисленные и работающие с дробными значениями. Разумеется, в каждом из них жёстко прописано — сколько отводится байт для хранения данных каждого типа. Этим же обусловлено, в каких диапазонах могут меняться значения переменных, а также точность представления действительных чисел. Обо всём по порядку. Приведу таблицу с характеристиками целочисленных типов данных. Да, их несколько.

Таблица 1. Целые типы данных
Название типа Байты Диапазоны значений
Integer 2 -32 768 .. +32 767
Word 2 0 .. 65 535
Byte 1 0 .. 255
Shortint 1 -128 .. +127
Longint 4 -2 147 483 648 .. +2 147 483 647

Самым часто используемым является — Integer, на хранение данных такого типа отводятся два байта и диапазон значений чисел этого типа лежит от −32 768 до 32 767 со знаком плюс. Для большинства типовых учебных задач его хватает. Однако бывает так, что нам не нужны, например, отрицательные числа или не требуется такого разброса значений. А бывает и наоборот, обычного интеджера становится недостаточно и тогда используют Longint. Какой тип данных использовать, следует решать в каждой конкретной задаче.

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

имя_переменной: Тип_данных;

На имена переменных налагаются те же ограничения, что и на прочие идентификаторы языка — русские буквы и пробелы исключены. Имя не может начинаться с цифры. После имени переменной необходимо поставить двоеточие «:» и затем указать тип данных, например, Integer. Закончить объявление переменной надо точкой с запятой «;» как и любой оператор. Если нам нужны несколько переменных одного типа, их имена можно указать через запятую.

Я очень не люблю давать переменным короткие, ничего не значащие имена, вроде букв латинского алфавита. Да, такие имена переменных исторически появились первыми, да, они обусловлены малым количеством оперативки в компьютерах — не будем забывать, Паскалю уже более 50 лет, но сегодня подобные имена — неразумная экономия. Гораздо удобнее, когда уже из самого имени переменной вам станет ясно, какие данные в ней задумал хранить автор программы.

Однако на этом уроке и исключительно для краткости изложения, я буду называть переменные коротко, ровно так, как обычно не поступаю. Итак, запускаем PascalABC и в окне пишем такую программу:

Листинг 1.

program TypesVariablesOperations;

var
  a, b: Integer;

BEGIN
  a := 5;
  b := 2;

  writeln( a + b );
  readln;
END.

Имя программе задано произвольно и из него ясно, что мы сегодня говорим о типах данных, переменных и операциях (имеются в виду арифметические операции над числами). Итак, перед главным бегином программы я разместил раздел с переменными, которые для краткости обозвал «a» и «b». Это переменные целого типа Integer.

Обычно имена переменных я начинаю со строчных букв, а названия типов данных записываю с прописной.

Далее в самой программе расположены два оператора присваивания — знак «:=» – двоеточие, равно без пробелов между ними. С его помощью в переменную a я поместил целое число пять, а в b — двойку. Каждый оператор, само собой, заканчивается точкой с запятой. С процедурой writeln вы уже знакомы. С её помощью мы выведем на экран сумму чисел, которые сохранили в переменных. Запустите программу любым способом — (F9 или Ctrl + F9) и посмотрите на результат. Очевидно — семь.

Однако, покамест, мы лишь поместили в переменные по одному числу, а сумму и вовсе не сохраняя в переменную, просто вывели на экран. Механизм работы переменных и весь их смысл заключён в том, чтобы менять их значения по ходу программы. Давайте после первых двух строк запишем ещё одну:

a := a - b;

А в процедуру writeln передадим в качестве аргумента не сумму переменных, а только нашу переменную a. Если ещё не ясно, программа примет следующий вид:

Листинг 2.

program TypesVariablesOperations;

var
  a, b: Integer;

BEGIN
  a := 5;
  b := 2;
  a := a – b;

  writeln( a );
  readln;
END.

Запустите программу. Результат — три. Что же произошло? Как следует понимать третью строку программы? В правой части оператора написано a−b, исходя из помещённых в наши переменные значений, результат 5−2 действительно равен трём. А весь оператор следует понимать так: вычитаем значение переменной b из значения переменной a, и затем уже присваиваем новое значение в переменную a. Вообще, слева в операторе присваивания могла стоять любая целочисленная переменная, куда бы мог быть записан наш результат. Другое дело, что чаще всего используется тот же тип данных, что и в складываемых или вычитаемых переменных.

Очевидно, что кроме суммы «+» и разности «−», есть ещё умножение «*» и деление «/». Однако с делением не всё так гладко. Если мы скроем третью строчку программы — закомментируем её, а в процедуру writeln передадим в качестве аргумента «a / b», то процедура, положим, разберётся, что надо делать и выдаст нам результат, равный 2.5 — смотрите листинг 3.

Листинг 3.

program TypesVariablesOperations;

var
  a, b: Integer;

BEGIN
  a := 5;
  b := 2;
  //a := a – b;

  writeln( a / b );
  readln;
END.
В Паскале, как и в большинстве других языков программирования, разделителем целой и дробной части чисел служит точка, а не запятая. Просто запомните этот факт.

Если же мы раскомментируем третью строку и попробуем в переменную a поместить результат деления a на b, то мы получим ошибку при выполнении нашей программы. Почему? — Правильно, нельзя дробное число поместить в переменную целого типа. И даже если бы мы с вами делили, скажем, четыре на два, то и тогда результат нужно было бы сохранять в переменную дробного типа. Почему? — Да потому что в общем случае результат деления — число дробное. Так мы плавно добрались до дробных типов данных в Паскале. Или, говоря более академично, до типов с плавающей запятой. Их тоже несколько, привожу таблицу.

Таблица 2. Типы данных с плавающей запятой
Название типа Байты Диапазоны значений
Real 6 2.9 x 10-39 .. 1.7 x 1038
Single 4 1.5 x 10-45 .. 3.4 x 1038
Double 8 5 x 10-324 .. 1.7 x 10308
Extended 10 3.4 x 10-4932 .. 1.1 x 104932

Диапазоны чисел в этой таблице просто космические. Вместе с тем, такое представление чисел не всегда точное. К выбору дробных типов данных (типов с плавающей запятой) следует подходить ещё более аккуратно, чем к целочисленным. Однако зачастую выбирают тип Real — действительные числа. Шести байт, выделяемых для хранения данных в этом типе с лихвой хватает для большинства задач.

Если мы теперь объявим переменную этого типа и результат деления a на b поместим в неё (листинг 4) Паскаль ругаться не станет.

Листинг 4.

program TypesVariablesOperations;

var
  a, b: Integer;
  r: Real;

BEGIN
  a := 5;
  b := 2;
  r := a / b;

  writeln( r );
  readln;
END.
Чаще остальных типов в программах на Паскале применяют Integer и Real. Их хватает для большинства типовых задач.

С результатом деления как с потенциально дробным числом, которое следует сохранять в дробных переменных, мы разобрались. Добавлю, однако, что в переменные типа Real можно запросто помещать и целые числа. К ошибке это не приведёт. Более того, умненький PascalABC даже не поставит в таком числе точку — разделитель целой и дробной части. Если вы сохраните в нашей переменной r число пять и выведете его на экран, то среда разработки выведет «5», а не «5.0», что с формальной точки зрения было бы правильнее. Мы к этому ещё вернёмся, когда будем говорить о приведении типов в Паскале.

Раз уж в нашем уроке речь идёт не только о числовых типах данных и переменных, но и об арифметических действиях, следует помнить об их приоритетах. Умножение и деление имеют больший приоритет, чем вычитание и сложение. В примере 2 + 2 * 2 результатом будет — шесть, так как сначала выполнится именно умножение. Если вам нужен иной результат — используйте скобки. Так, например: (2 + 2) * 2 — получится 8.

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

Нет, не всё, есть ещё видеоролик.

Репозиторий листингов программ.

Оставьте ваш отзыв: