#3 Типы данных в языке Pascal. Объявление переменных. Целые числа integer. Оператор присваивания. Инициализация в Паскаль

Примечание: далее мы начнём говорить о типах данных в Паскале. Выясним следующие:

  • все данные в паскале имеют в определённый момент времени выполнения программы какой-то тип (разные данные -разный);
  • узнаем какие конструкции обладают типом данных;
  • поговорим о первом типе данных, который служит для описания целых чисел и имеет название "integer". А о данный других типов поговорим уже в следующих уроках;

Деление данных на виды "по представление в коде программы" на языке Pascal

Рассмотрим три вида представления данных в коде программы на языке Паскаль ("виды представления данных"):

  1. В виде литералов -- т.е. быть явно записаны в программе, например, как числа или строки в кавычках.
  2. По именам переменных. Переменная -- это псевдоним (имя) для хранящихся в ней данных (например, числа или строки).

    Любая переменная похожа на звание чемпиона -- конкретный человек носящий это звание меняется, но само звание звучит одинаково (не меняется) для разных людей в разные годы.

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

    Например:

    champion := 'Vasya'; // присваиваем строковый литерал переменной (запоминаем в ней имя)
    champion := 'Petya';  //  теперь у той же переменной другое значение

    В отличие от литерала, переменная может сколько угодно раз в теле программы менять своё значение.

    Подробнее о переменных мы поговорим далее в этом уроке.

  3. Как результаты выражений, в которые входят переменные или литералы.

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

    Например:

    {выражение, например, арифметическое: }
    5 + 6 // арифметическая сумма (в виде двух целочисленных литералов)

    Подробнее о выражениях мы поговорим далее.

Таким образом, любые данные к коде программы на языке Паскаль можно отнести к одному из трёх видов:

  • или к переменным
  • или к литералам
  • или к результатам выражений

Сильная типизация

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

Типы данных в Pascal

В Паскале выделяют 5 типов данных (в списке сразу укажем ключевые слова, с помощью которых обозначаются эти типы в программном коде):

  1. integer -- целые числа.
  2. real -- вещественные числа.
  3. boolean -- логический тип данных (значения типа да/нет, истина/лож).
  4. char -- символьный тип.
  5. string -- строковый тип.

В этом уроке мы будем говорить об понятия общих для всех типов данных на примере конкретного типа данных -- integer (целые числа).

Чем отличаются "виды представления данных" от типов данных

Если виды представление данных - это просто различная форма записи обращения к какой либо информации в коде программы, то деление на типы данных - позволяет отнести к одной группе данные вне зависимости от их вида.

Как мы увидим позднее одного и того же типа могут быть и переменные и литералы и результаты выражений, а данные каждого типа в программе могу быть представлены в разных видах, в связи с чем, можно нарисовать такую диаграмму, иллюстрирующую соотношение между типами данных и видами представления данных:
Типы данных в Паскале и их представление в коде в виде литералов переменных или значений выражений

Объявление переменных

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

При объявлении переменной всегда указывают:

  1. Имя переменной.
  2. Тип переменной.

Объявление переменных происходит после ключевого слова var, до до тела программы.

В общем виде объявление переменной можно записать так (как схему):

var  // секция объявления переменных
   <имяПеременной> : <типПеременной>;
begin
  // тело программы
end;

Пример объявления переменных по одной:

var 
  a: integer;
  b: integer;

То есть сначала идёт имя переменной, потом двоеточие, а потом один из типов данных (integer, string или иной -- смотря какой требуется).

Объявление переменных списком

Также переменные можно объявлять списком (переменные одного типа можно просто перечислить через запятую, а потом после двоеточия указать типа):

var  // секция объявления переменных
   <имяПеременной1>, <имяПеременной2>,
    <имяПеременной3> : <типПеременной>;

Например:

var
 a,b: integer; // две переменные строкового типа списком
 с: integer;  // и ещё две по одной
 d: integer; 

-- в списке имена переменных разделяются запятой, переносы строк между элементами списка значения не имеют.

В этом уроке мы поговорим о типе integer и рассмотрим примеры работы с этим типом данных.

Объявление целочисленных переменных

Integer -- тип данных соответствующий целым числам.

Объявим переменную такого типа:

var a: integer; // объявляем переменную с имененм "a"

Можно объявить несколько переменных немного по-разному:

var a: integer; // число яблок
    
  // далее объявляем две переменные списком
   с, d: integer;

    myvar: integer; // имя переменой может быть любым словом

  // В комментариях можно сразу указывать для чего будет использоваться переменная:
  
  trees,  // число деревьев
  people,  // число людей
  cars : // число машин
      integer;  // в конце всегда точка с запятой

begin
  // тело программы
end;

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

Оператор присваивания

Определение:

Оператор -- это знак операции, например знак суммы это "$+$".

Оператор присваивания обозначается знаком (из двух символов):
$:=$
Этот оператор позволяет записывать значение в переменную ("запоминать это значение в переменной"), схема его работы такова:

<имяПеременной> := <литерал/или другая переменная/ или выражение>;

Или, опять же схематично:

<под каким именем запомнить> := <что запомнить>;

А теперь как это выглядит с конкрентыми именами переменных и значениями в коде (пример работы оператора присваивания):

var
  // тут надо объявить все переменные, прежде чем их использовать
begin
  a := 5; // запоминаем значение литерала
  b := 2; // запоминаем значение литерала
  b := b + 3; // запоминаем значение выражения -- суммы значения переменной и литерала
  myVar := a + b; // запоминаем значение выражения -- суммы двух переменных

Присваивание переменным литералов и вывод значений переменных на экран

Далее, в теле программы мы можем записывать в данную переменную значения, например:

a := 567; // запишем число 567 в переменную "а"

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

Целый тип также поддерживает ноль и отрицательные значения:

a := 0; 
a := -4456; // перезаписываем значение

Присваивание значений одних переменных другим переменным

Можно присваивать одним переменным значение других, например:

b := 34;
a := b;

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

Чтобы узнать чему стало равно значение переменной $a$ можно вывести её значение в консоль, передав как аргумент в стандартную процедуру writelen() или write(). Тогда наш код будет выглядеть так:

b := 34;
a := b;
writeln(a);

Что мы получим в консоли? Запустите код, объявив обе переменные и оформив тело программы (его содержимое это и есть последние 3 строчки).

Переменные тоже можно передавать во writeln() в любом количестве, разделяя запятой, например две шутки:

writeln(a, b); // выведет значения подряд

в том числе и вперемежку с литералами, например символьными:

writeln(a, ' ',b); // выведет значения переменных через пробел

Или строковыми:

writeln(a, '  =)  ',b); // выведет значения переменных и  строковый литерал между ними

Присваивание переменным результатов выражений

Переменным можно присваивать результаты выражений. Для для переменных числового типа (integer или real) такие выражения называются арифметическими.
Целочисленным переменным можно присваивать значения выражений, которые получаются в результате выполнения операций:

  1. $+$ суммы (сложения)
  2. $-$ разности (вычитание)
  3. $*$ произведения (умножение)

-- так как эти операции возвращают тип integer. Операцию же деления $/$ использовать нельзя, так она возвращает другой тип -- real (вещественные числа). В Паскале любая попытка присвоить переменной данные другого типа приводит к ошибке ("падению" программы).

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

Также в выражения, значения которых можно присваивать переменным типа integer должны входить только:

  • целочисленные литералы
  • или целочисленные переменные.

Можно сказать что тип, который возвращается выражением (тип его результата) определяется двумя моментами:

  1. типом операций (допустимые перечислены выше)
  2. типом операндов. Операнды -- это аргументы операций, подобно аргументам процедуры, на их
    основе производятся какие-то действия. Но операнды операций, в отличие от операндов процедур,
    записываются не в скобках, а справа и слева от знака операций, так как мы это делаем в математических выражениях:
    // Операция суммы с операндами 5 и 2
    a := 5 + 2 // а теперь равно 7.  
    
    // Операция произведения с операндами 5 и 2
    a := 5 * 2 // а теперь равно 10.  

Таким образом, допустимы выражения:

a := 5 + 2;
a := 5 + 2;
a := 5 * 7 + 3;
// и т.д.

А также выражения с участием других переменных:

b := 8;
c := 9;
a := b + 3;
a := a * 7 + c;
// и т.д.

Работа с результатом выражений

Результат выражения является данными с каким-то конкретным типом, а потому с выражениями можно делать то же, что и с переменными и литералами ,а именно:

  1. Присваивать их значения переменным, например: a := 22 + 3* 999;
  2. Делать одни выражения частью других (в этом случае части называют подвыражениями), например сделаем предыдущее выражение подвыражением:
    a := (22 + 3* 999) - 100;

    Подвыражение -- это любая часть основного выражения, в которой есть хотя бы один оператор (как и выражение всегда обладает каким-то возвращаемым значение известного типа). Например:

    2 + 5

    Это подвыражение выражения:

    2 + 5 + 8
  3. Передавать результаты выражения (и как следствие -- их результаты) в процедуры, например:
    write(23 * 2); // выведет в консоль 46

    Во write() и writeln() также можно передавать любое количество аргументов-выражений, а также аргументов другого вида:

    write(23 * 2, ' -- ',  6,  'privet'); // передаем данные разного происхождения и типов.

Инициализация переменной


Инициализация переменной
-- это первое присваивание какого-то значения переменной. Это может быть:

  1. или значение литерала
  2. или считывание значения для переменной извне (например, пользователь может вводить значение переменных в консоли, но об этом мы поговорим в следующих уроках)
  3. или присваивание данной переменной значения значения другой уже инициализированной переменной.
  4. или значение выражения, в котором или одни литералы или инициализированные переменные

Таким образом один из примеров выше мы могли бы переписать с такими комментариями:

a := 0;  // инициализация переменной "а"
// в качестве исходного значения в данном примере используем ноль, но вообще оно может быть любым
a := -4456; // перезаписываем значение переменной  "а"

Программа выполняется сверху вниз построчно -- перезапись значений переменных

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

Для одного из приведённых примеров справа в комментариях допишем чему оказываются равны переменные после выполнения очередной строки:

{ все целочисленные переменные 
  до инициализации равны нулю }
b := 8; // переменная "b"  стала равна 8
c := 9; // переменная  "c"   стала равна 9
a := b + 3; //  переменная  "a" стала равна 8 + 3 = 11
a := a * 7 + c; // переменная  "a" стала равна 11 * 7 + 9 = 77 + 9 = 86

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

{ все целочисленные переменные 
  до инициализации равны нулю }
b := 8; // b = 8, c = 0, a = 0
// b = 8, c = 0, a = 0
c := 9; // b = 8, c = 9, a = 0
// b = 8, c = 9, a = 0
a := b + 3; //  b = 8, c = 9, a = 10
//  b = 8, c = 9, a = 10
a := a * 7 + c; 
//  b = 8, c = 9, a = 79

-- с помощью комментариев для последней строки показано, что значение меняется после выполнения операции присваивания "сразу после точки с запятой", и если в следующих строках переменной не присваивают какое-то другое значение, то оно и не меняется.

Разбор практических примеров

Пример №1

Задача:

У вас есть целочисленная переменная $a$ и два строковых литерала:

'У Коли'

и второй:

' яблок'

Присвойте переменной $a$ значение и выведете на экран фразу с этим значением -- используя указанные выше литералы (можно не только их, но их обязательно), например для:

a:=5;

Должно выводиться:

У Коли 5 яблок и 8 груш

Начнём писать код, в теле программы:

begin
   a := 9; // пусть будет 9
end.

-- таким образом мы выполнили первое требование задачи, присвоив значение переменной. Далее от нас хотят, чтобы программа выводила фразу, где число яблок зависит от значения переменной $a$ (а точнее равно ему), при этом про число груш ничего не сказано.
Второй момент -- необходимо использовать литералы в точности так как они приведены в условии, что ж попробуем вывести фразу, используя значение переменной и указанные литералы:

var
 a : integer; //  объявим единственную переменную
begin
   a := 9; // пусть будет 9
   writeln('У Коли', a, ' яблок', ' и 8 груш');

   readln(); // удерживаем консоль
end.

-- раз про груши ничего не сказано, то их число выводим просто в составе строкового литерала (оно не будет меняться пока мы не изменим сам литерал), а вот число яблок передаём в процедуру как значение переменной $a$.
Заметьте, что литерал:
' и 8 груш'
мы начали с пробела, чтобы при выводе он не "склеился" со словом "яблок".

Запустите последний код. Чего-то там не хватает? А именно -- в консоли мы получим:

У Коли9 яблок и 8 груш

-- почему склеилось имя и значения? Чтобы понять это нужно внимательно посмотреть на код вызова процедуры:

   writeln('У Коли', a, ' яблок', ' и 8 груш'); // 4 аргумента

-- как мы можем видеть, здесь в конце первого аргумента-литерала нет пробела, а значит значение переменной $a$ (которое есть само по себе просто число, а значит содержать пробелов не может) просто выведется вплотную к первому аргументу. Чтобы исправить эту ситуацию, можно было бы изменить первый литерал, добавив в его конец символ-пробел:

   writeln('У Коли ', a, ' яблок', ' и 8 груш'); // 4 аргумента

НО: таким образом мы бы не следовали строго условию задачи использовать указанные строковые литералы ('У Коли' и ' яблок'), так как фактически

'У Коли '

и

'У Коли'

-- это разные литералы (в первом на один символ больше и этот символ -- пробел). А значит, чтобы не модифицировать первый строковый литерал, просто добавим в вызов ещё один аргумент -- символьный литерал (а точнее - пробел):

   writeln('У Коли', ' ',  a, ' яблок', ' и 8 груш'); // 5 аргументов

-- что и будет подходящим вызовом процедуры writeln() для решения задачи.

Пример №2

Пусть у вас есть задача:

Васе $m$ лет, а Паше $k$ лет. Напишите программу, в которая считает разницу между возрастом Васи и Паши (то есть выясняет насколько Вася старше Паши). Конкретные значения возрастов этих двух человек задайте в коде в виде двух переменных, которым присвойте значения целые численные значения (используя целочисленные литералы). Результат суммы запишите в третью переменную и выведите значение на экран.

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

begin
  v := 12; // пусть Васе 12 лет
  p := 10; // а Паше 10

end.

Далее разницу их возрастов просят записать в третью переменную, что ж сделаем и это:

begin

  v := 12; // пусть Васе 12 лет
  p := 10; // а Паше 10
  r := v - p; // запоминаем в переменную r результат арифметического выражения
end.

В самом конце нас просили вывести значение разницы на экран, сделаем и это используя вызов стандартной процедуры writeln(), в качестве пояснения пользователю передав строковый литерал как аргумент перед вторым аргументом-переменной:

  writeln('Разница в возрасте: ', r, ' лет.'); // передаём в процедуру 3 аргумента, второй из них- переменная, а два остальных -- строковые литералы

То есть в данный момент мы имеем код:

begin

  v := 12; // пусть Васе 12 лет
  p := 10; // а Паше 10
  r := v - p; // запоминаем в переменную r результат арифметического выражения
  writeln('Разница в возрасте: ', r, ' лет.'); // передаём в процедуру 3 аргумента, второй из них- переменная, а два остальных -- строковые литералы

readln(); // удерживаем консоль
end.

Осталось объявить все используемые в теле программы переменные. В данном случае их 3 штуки, объявим их через запятую в секции var до начала тела программы:

var
   v, //  для хранения возраста Васи
   p,  //  для хранения возраста Паши
   r :integer; // r -переменная для хранения ответа

Итоговое решение:

var
   v, //  для хранения возраста Васи
   p,  //  для хранения возраста Паши
   r :integer; // r -переменная для хранения ответа
begin

  v := 12; // пусть Васе 12 лет
  p := 10; // а Паше 10
  r := v - p; // запоминаем в переменную r результат арифметического выражения
  writeln('Разница в возрасте: ', r, ' лет.'); // передаём в процедуру 3 аргумента, второй из них- переменная, а два остальных -- строковые литералы

readln(); // удерживаем консоль
end.

Запустите этот код и посмотрите как он работает, если консоль закрывается сразу после выполнения кода, используйте вызов для задержки консоли.

Задачи для самостоятельного решения

    Теоретические вопросы:

  1. Что такое переменная? Чем она отличается от литерала?
  2. Что такое объявление переменной? Как объявляются переменные?
  3. Какие виды представления данных в программном коде вы знаете?
  4. Сколько переменных можно передавать во write() и writeln() ? Если можно передавать несколько, то как это нужно делать? Можно ли передавать в эти процедуры и переменные и литералы, если да -- то как?
  5. Что такое оператор? Что такое операнд? Приведите примеры операторов и операндов.
  6. Как работает оператор присваивания? Приведите примеры.
  7. Что такое инициализация переменной? Приведите примеры инициаллизаций.
  8. Какие литералы можно присваивать целочисленным переменным? Приведите примеры подобных присваиваний.
  9. Будет ли работать код:
    var i:integer;
    begin
      i := 123;
      writeln(i);
    
    readln(); // удерживаем консоль
    end.

    Объясните что здесь происходит.

    И ещё один вопрос:
    Будет ли работать код:

    var i:integer;
    begin
      i := '223';
      writeln(i);
    
    readln(); // удерживаем консоль
    end.

    Объясните что здесь происходит.

  10. Есть программный код:
    b := 8; 
    c := 9; 
    // чему равно  "c" в этой строке ?
    a := b + 3;
    // чему равно  "c" в этой строке ?
    a := с * 9 + c * a; 
    b := 200 - a;
    // чему равно  b в этой строке ?
    
    

    Два задания к этому коду:

    • Ответьте на вопросы в комментариях письменно.
    • Запустите этот код, предварительно объявив используемые переменные, и выведите в консоль с write() или writeln() значения переменных, в строках, где в комментариях к коду задан вопрос.
  11. Что такое выражение? Что такое арифметическое выражение? Что такое подвыражение?
    • Запишите строку, в которой с помощью одного writeln() выводятся результаты трёх разных (любых) арифметических выражений.
    • Сделайте то же самое, но выводя уже три переменные, в каждой из которых предварительно присвойте значение одного из арифметических выражений.
  12. Что такое "плохой стиль" в программировании? Как это понятие связано с объявлением переменных?
  13. Чем виды представления данных отличаются от типов данных? Какие вы знаете типы данных? Какие вы знаете виды представления данных?
  14. Что такое компилятор?
  15. Какие выражения можно присваивать переменным целого типа? Какие операнды могут входить в эти выражения?
  16. Задачи:

    (напишите код и продемонстрируйте его работу):

  17. Объявите пять целочисленных переменных списком, ещё две списком и ещё две по одной. Тело программы можно сделать пустым.
  18. Напишите программу, которая выводит на экран значения выражений:
    5 + 2*3
    6+7
    8*9

    двумя способами:

    • в столбик, разделив пробелами
    • в строчку
  19. У вас есть целочисленная переменная $a$ и два строковых литерала:
    'У Васи'

    и второй:

    'яблок'

    Присвойте переменной $a$ значение и выведете на экран фразу с этим значением -- используя указанные выше литералы (можно не только их, но их обязательно), например для:

    a:=5;

    Должно выводиться:

    У Васи 5 яблок
  20. Васе $m$ лет, а Паше $k$ лет. Напишите программу, в которая считает их суммарный возраст и выводит значение на экран. Конкретные значения возрастов этих двух человек задайте в коде в виде двух переменных, которым присвойте значения целочисленных литералов. Результат суммы запишите в третью переменную и выведите значение на экран.
  21. Напишите программу с тремя переменными целого типа, первым двум присвойте значения, а третьей переменной их произведение за вычетом их суммы (например, для значений $5$ и $2$ должно получиться выражение эквивалентное: $5*2 - (5+2)$). Выведете значение третей переменной на экран.