Занятие 1. Pascal abc.net: Основные особенности при работе с переменными и условный оператор

Работа с переменными: особенности; условный оператор в Pascal abc.net

Принцип локальности

В обычном Паскале описание переменных обычно находится до тела программы:

{описание переменных}
begin
  ...
end.

Если программный код достаточно большой, то такой вариант инициализации переменных весьма неудобен. В Pascal abc.net переменные могут описываться внутри тела программы — между begin и end и инициализироваться при описании.

В этом состоит принцип локальности: переменная описывается непосредственно перед началом своего использования.

Внутриблочные переменные позволяют сильно уменьшить количество глобальных переменных в разделе описания.

Т.е. чем ближе к месту использования описывается некоторый программный объект, тем читабельней код и модифицируемей программа.

Пример: поиск факториала числа

Раньше:

var n,i,p:integer;
begin
 read(n);
 ...
 p:=1;
 for i:=1 to n do
  p:=p*i;
...

Pascal abc.net:

begin
var n:integer;
read(n);

ИЛИ

begin
var n:=ReadInteger('введите n: ');
var p:=1; // канонический способ - тип определяется по правой части
 
for var i:=1 to n do
  p:=p*i; // можно заменить на компактную форму p*=i;
print (p); // write() заменяем на print()
end.

Теперь этот фрагмент кода можно вырезать и перенести в функцию или в модуль. В этом и заключается модифицируемость.

Ввод данных:

var n:=ReadInteger();
var n:=ReadReal();

Канонический способ:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var 
  a: integer;
  b: real;
 
begin
  a := 1;
  writeln('a := 1; a = ',a);
  a += 2; // Увеличение на 2
  writeln('a += 2; a = ',a);
  a *= 3; // Умножение на 3
  writeln('a *= 3; a = ',a);
  writeln;
  b := 6;
  writeln('b := 6; b = ',b);
  r /= 2;
  writeln('b /= 2; b = ',b);
end.
Пример: Вычислите значение функции

y = 5(x−3)6 − 8(x−3)3 + 2

для нескольких заданных x.

✍ Решение:
 

    1
    2
    3
    4
    5
    6
    7
    
    begin
      writeln('Введите значение x');
      var x:=ReadReal;
      var a:=(x-3)*(x-3)*(x-3);
      var y:= 5*sqr(a)-8*a+2;
      writeln('Значение функции для x = ', y);
    end.
Задача abc_net 1. Найдите расстояние между двумя точками с заданными координатами (x1,y1) и (x2,y2) на плоскости. Расстояние вычисляется по формуле:
pascal abc расстояние между точками
  
Проверьте правильность вашей программы на следующих значениях:

d((0, 0); (6, 0)) = 6;
d((0, -4); (0, 1)) = 5;
d((-1, 1); (2, 5)) = 5.

[Название файла: L1abc1.pas]

Базовые типы и методы внутри стандартных типов

Для обращения к методам используется точечная нотация:

arr.MaxValue;

Целочисленные:

var i:integer;
i. ... // выпадает список методов для целочисленных
 
i.MaxValue;
i.MinValue;
i.ToString;

Вещественные:

begin
var a:=1.0;
var b:=0.0; 
 
print (a.MinValue); // -1.79769313486232E+308
 
print (a/b); // в прежних компиляторах выдается RunTime Error - исключение
// в abc.net  результатом будет бесконечность
 
print(Sqrt(-1)); // результат NAN - не число

Исключение — управляемая ошибка, которую можно перехватывать и погашать.

Что значит форматный вывод?
  • Для удобно и красивого вывода следует использовать форматный вывод с процедурой WritelnFormat:
  • WritelnFormat('f({0}, {1}) = {2}', a, b, c);

    Результатом будет:

    f(x, y) = z
    Первым параметром в скобках и одинарных кавычках указывается форматная строка, которая задаёт формат вывода выражений.
  • Так, если мы хотим вывести:
  • a + b = b + a = сумма

    то нужно просто заменить a, b на {0}, {1}:

    WritelnFormat('{0} + {1} = {1} + {0} = {2}', a, b, x + y)

    Стандартные функции

    Обмен значениями переменных происходит без использования буферной переменной:

    swap(a,b);

    Поиск максимального и минимального значения:

    min(a,b);
    max(a,b);
    Задача abc_net 2. В танцевальном клубе участвуют 10 представительниц женского пола. Найдите средний возраст танцовщиц. Решить задачу без использования массива, используя принцип локальности, компактную форму записи и методы внутри стандартных типов.

    Операции целочисленного деления и остатка

    Операция div предназначена для вычисления целой части от результата деления целых чисел (неполное частное). Пример:

    16 div  2 = 8
    22 div  7 = 3
    66 div 10 = 6

    [Название файла: L1abc2.pas]

  • То есть, число N div K показывает, сколько полных раз K «помещается внутри» N.
  • Операция mod предназначена для вычисления остатка от деления одного целого числа на другое. Если числа делятся нацело, то остаток равен нулю.
    Пример:

    16 mod  2 = 0
    22 mod  7 = 1
    66 mod 10 = 6
  • Число N mod K показывает, что «остаётся от N» после того, как из него «убрали» максимальное число фрагментов размером K.
  • Работа с отдельными цифрами числа

  • Если мы работаем в 10-й системе счисления, то любое число можно разобрать на цифры, используя степени 10 и операции div и mod.
  • Стандартный вид числа:
  • 123 = 1∗100 + 2∗10 +3
    Таким образом, можно понять, как получить из общего числа отдельные его цифры:

  • для получения сотен из трёхзначного числа, нужно вычислить частное от деления на 100;
  • для получения десятков, нужно вычислить остаток от деления на 100, а затем частное от деления на 10 (возможен другой вариант)
  • для получения единиц, нужно взять остаток от деления на 10.
  • Пример: Дано трёхзначное целое число. Вывести сумму его цифр. Убедитесь, что ваша программа корректно работает с отрицательными числами.

    ✍ Решение:
     

      begin
        var a := abs(readinteger); // модуль числа
        println(a div 100 + (a div 10) mod 10 + a mod 10);
      end.
    Задача abc_net 3. Дано двузначное целое число. Требуется вывести сумму и произведение его цифр.
    Пример:

    35 => 8, 15
    90 => 9, 0
    -11 => 2, 1  // сумма и произведение цифр положительны
    

    Приведите лог работы программы с одним из введенных чисел в форме комментария.

    [Название файла: L1abc3.pas]

    Задача abc_net 4. Дано трёхзначное целое число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).
    Пример:

    234 >>>  342
    -602 >>> -26
    

    [Название файла: L1abc4.pas]

    Логические выражения и условный оператор

    Логические переменные и выражения

      Логическое выражение после его вычисления возвращает значение True (истина) или False (ложь).  
       
      Логическое выражение может включать:

      • логические переменные (имеют тип: boolean);
      • логические операции (or, and, xor, not);
      • операции сравнения чисел и числовых переменных (например, x <= y, где x и y имеют тип real или integer).
    • Для вывода результата вычисления логического выражения может быть использован операторы write и print.
    • Если требуется проверить истинность какого-либо выражения, то эти операторы могут выводить значения True и False; достаточно написать:
    • Writeln(<логическое выражение>);
    Пример: Даны два целых числа. Проверить истинность высказывания: первое число больше второго (вывести True или False).

    ✍ Решение:
     

      begin
        var (a, b) := readinteger2;
        println(a > b);
      end.
    Задание abc_net 5: Даны три целых числа: A, B, C. Проверить истинность двойного неравенства A < B < C.
    Пояснение: Запрещено использовать условный оператор. Следует использовать вывод результата вычисления логического выражения.

    [Название файла: L1abc5.pas]

    Задание abc_net 6:Даны два целых числа. Проверить истинность высказывания: хотя бы одно из этих чисел является нечётным.
    Пояснение: Используйте стандартную функцию odd.

    [Название файла: L1abc6.pas]

    Условный оператор IF
    Чаще всего логические выражения используются внутри условного оператора, который выполненяет определённые действия в зависимости от истинности выражения:
      
    Короткая форма условного оператора:

    if <логическое выражение> then
      <оператор>  // выполнится, если <условное выражение> возвращает True

    Полная форма:

    if <логическое выражение> then
      <оператор-1>
    else
      <оператор-2>

     
    При использовании нескольких операторов в одном условии необходимы операторные скобки begin..end:

    if <логическое выражение> then
    begin
      <оператор-1>
      <оператор-2>
      ...
    end
    Важно: Не следует ставить точку с запятой перед else
      
    Пример: Дано целое число. Если оно является положительным, то прибавить к нему 1; в противном случае вычесть из него 1. Вывести число в конце программы.

    -3 => -4
     0 => -1
     1 =>  2
     5 =>  6

    ✍ Решение:
     

      begin
        var a := readinteger;
        if (a > 0) then 
           a := a + 1
        else 
           a := a - 1;
        println(a);
      end.
    Задание: Даны целые числа x, y. Вычислить значение функции:

    Дополните программу:

    begin
      var x, y: integer; // аргументы функции f
      Write('Введите числа x, y: ');
      Readln(x, y);
      var f: integer;   
      // записать в переменную f значение функции f(x, y)
      ...
      WritelnFormat('f({0}, {1}) = {2}', x, y, f);
    end.
    Задание abc_net 7: Даны три вещественных числа. Вывести значение True, если среди этих чисел нет ни одного положительного, и False - в противном случае.

    [Название файла: L1abc7.pas]

    Задание abc_net 8: Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равнобедренным, и False - в противном случае.

    [Название файла: L1abc8.pas]

    Оператор множественного выбора

    Рассмотрим оператор на примере:

    Пример: Единицы длины пронумерованы следующим образом:

    1 — дециметр, 2 — километр, 3 — метр, 4 — миллиметр, 5 — сантиметр

    Вводится номер единицы длины (целое число в диапазоне 1–5) и длина отрезка в этих единицах (вещественное положительное число). Найти длину отрезка в метрах.

    ✍ Решение:
     

      begin
        var n := readinteger('Введите номер единицы:');
        var a := readreal('Введите длину в заданных единицах:');
        case n of
          1: a /= 10;    // дециметр
          2: a *= 1000;  // километр
          4: a /= 1000;  // миллиметр
          5: a /= 100;   // сантиметр
        end;
        println('Длина в метрах:', a);
      end.
    Задание abc_net 9: Даны два целых числа: D (день) и M (месяц), определяющие правильную дату невисокосного года. Вывести знак Зодиака, соответствующий этой дате:

    «Водолей» (20.1–18.2), «Рыбы» (19.2–20.3), «Овен» (21.3–19.4), «Телец» (20.4–20.5), «Близнецы» (21.5–21.6), «Рак» (22.6–22.7), «Лев» (23.7–22.8), «Дева» (23.8–22.9), «Весы» (23.9–22.10), «Скорпион» (23.10–22.11), «Стрелец» (23.11–21.12), «Козерог» (22.12–19.1).

    [Название файла: L1abc9.pas]