Основные отличия PascalABC.NET

от автора

PascalABC.NET имеет базовую совместимость с Turbo Pascal, что должно было позволить портировать старые программы с меньшим трудом. Однако, благодаря этому, сложилась тенденция, использовать PascalABC.NET только в стиле Turbo Pascal и игнорировать современные конструкции. Тут я хочу коротко изложить основные отличия и показать правильное использование этого диалекта.

Стандартные функции для ввода и вывода

Не самое важное отличие, однако это пригодится нам для дальнейшего сравнения.

В Turbo Pascal для ввода и вывода используются процедуры read[ln] и write[ln] соответственно.

var    a, b: integer;    begin   write('a=');    readln(a);      write('b=');    readln(b);      writeln('сумма ', a, ' и ', b, ' равна ', a+b); end.

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

write('a=');  a:= ReadlnInteger;

Аналогичные функции есть для остальных типов (real, string, etc). Более того, эти функции могут выводить приглашение для ввода самостоятельно.

a:= ReadReal('a =');

Для вывода используется подпрограмма Print[ln], которая автоматически разделяет переданные параметры пробелами. Таким образом, можно убрать из команды вывода лишние пробелы.

В результате программа приобретает такой вид:

var    a, b: integer;    begin   a:= ReadlnInteger('a =');   b:= ReadlnInteger('b =');      Println('сумма', a, 'и', b, 'равна', a+b); end.

Локальные переменные

В Turbo Pascal переменные объявляются перед основной программой или перед телом подпрограммы. Например для решения квадратного уравнения может потребоваться такой набор переменных

var   a, b, c, d, x1, x2: real; // коэффициенты, дискриминант, корни   count: integer; // кол-во найденных корней

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

В PascalABC.NET переменные могут объявляться прямо в коде. Делать это нужно как можно ближе к месту первого использования переменной.

Посмотрим на примере программы, складывающей числа.

begin   var a: integer; // объявляем   a:= ReadlnInteger('a ='); // инициализируем      var b: integer;   b:= ReadlnInteger('b =');      Println('сумма', a, 'и', b, 'равна', a+b); end.

Объявление переменной можно совместить с инициализацией.

begin   var a: integer:= ReadlnInteger('a =');   var b: integer:= ReadlnInteger('b =');      Println('сумма', a, 'и', b, 'равна', a+b); end.

Более того, компилятор понимает, что мы инициализируем переменную значением типа integer и тип можно не указывать явно. Работает автовыведение типов.

begin   var a:= ReadlnInteger; // a: integer   var b:= 24.5;          // b: real      Println('сумма', a, 'и', b, 'равна', a+b); end.

Всё это применимо и к циклу for

for var i:= 0 to 10 do ;

Динамические массивы

В Turbo Pascal используются статические массивы, основная проблема которых — необходимость указывать размер массива ещё на этапе создания программы. В результате массивы зачастую создаются «с запасом». Вместо этого PascalABC.NET предлагает использовать динамические массивы.

begin   var n:= ReadLnInteger('Введите размер массива:');      var arr: array of integer;   arr:= new integer[n];      var arr2:= new integer[n]; // автовывод типа end.

Такие массивы индексируются с ноля.

Помимо стандартного заполнения массива по индексам существует ряд других методов.

begin   var x:= 1;      // заполнение известными значениями   var arr:= |1, 10, 43, x|;       // чтение 10 значений из консоли   var arr2:= ReadArrInteger(10); end.

Свойства и расширения типов

Каждый стандартный тип данных имеет достаточно большое количество свойств и методов расширения. Это элементы, доступные по точечной нотации.

Пример для integer

begin   var x:= 2;   var f:= x.IsEven;   // чётное ли число   var f2:= x.Divs(4); // делится ли на 4   x.Print;            // вывод в консоль end.

Пример для динамических массивов:

begin   var arr:= |1, 31, 40, 4, 1|;   arr.Sort; // сортировка   var len:= arr.Length; // получение размера   var max:= arr.Max; // получение максимального   var count:= arr.CountOf(1); // кол-во указанного элемента end.

Многие из этих расширений для массивов относятся к LINQ, но это достаточно обширная тема.

Благодаря этому код на PascalABC.NET может выглядеть как цепочка методов. Например эта программа находит количество двоек в записи считанного числа

begin   ReadlnInteger.ToString.CountOf('2').Print; end.

Кстати .Print[ln] можно использовать для всех базовых типов. Это особенно удобно в длинных выражениях.

Кортежи

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

begin   var point: (integer, integer);   point:= (1, 2);      Print(point.Item1, point.Item2); end.

В стандартной библиотеке есть функции, считывающие из консоли несколько значений сразу и возвращающих кортеж

begin   var point1:= ReadInteger2;   print(point1.Item1, point1.Item2);      var point2:= ReadReal2;   Print(point2.Item1, point2.Item2); end.

Кортеж можно распаковать в отдельные переменные

begin   var point:= (1, 4, 2);      var x, y, z: integer;      (x, y, z):= point;      Print(y); // 4 end.

И наконец, объявление переменных можно совместить с распаковкой

begin   var point:= (1, 4, 2);        var (x, y, z):= point;      Print(y); // 4 end.

Заключение

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

Конечно я затронул лишь малую часть отличий языка. Однако я постарался передать основные идеологические моменты программирования на PascalABC.NET.

Пишите современный код!


ссылка на оригинал статьи https://habr.com/ru/articles/783740/


Комментарии

Добавить комментарий

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