Простейшие новые возможности

Hits: 106295

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

  • Операторы +=, -=, *=, /=
  • Инициализация переменной при описании
  • Внутриблочные описания переменных
  • Автоопределение типа переменной при описании
  • Описание переменных в заголовке цикла for

Ометим, что их использование, хотя и удобно, но не всегда является оправданным: такие программы не будут работать в других версиях языка Object Pascal.

Операторы +=, -=, *=, /=

Данные операторы пришли из языка C. Запись a+=2 воспринимается легче, чем a:=a+2, и уж подавно легче, чем Inc(a,2). Кроме того, записи

a += 2;

можно обучать буквально на первом занятии по программированию, а запись Inc(a,2) нуждается в пояснениях: что такое стандартные процедуры и что такое передача параметра по ссылке.

Небольшая тонкость: если i: integer, то i /= 2 вызовет ошибку компиляции, поскольку будет трактоваться как i := i / 2.

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

var
  s: string := 'PascalABC';
  d: set of integer := [200..300];
begin
  s += '.NET';
  d -= [100..298];
  writeln(s);
  writeln(d);
end.

Вот файл этой программы.

Данные операторы имеются также в Free Pascal (должна быть включена опция C-like operators). Кроме того, операции += и -= активно используются для делегатов .NET (процедурные переменные в PascalABC.NET) и присутствуют также в этом качестве в системе Chrome.NET.

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

Переменная может быть инициализирована при описании:

var i: integer := 1;

Подобное можно сделать и в Delphi Object Pascal, но только для глобальных переменных. В PascalABC.NET можно производить также инициализацию локальной переменной и поля записи или класса:

procedure p;
var i: integer := 1;
begin
end;
 
type
  Frac = record
    num: integer := 0;
    denom: integer := 1;
  end;
  MyClass = class
    s: string := 'NET';
  end;

Инициализация полей класса производится в конструкторе объекта этого класса до других действий.

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

var L: List<integer> := new List<integer>;

Внутриблочные описания переменных

Если какая-то переменная используется лишь в одном месте алгоритма, то описывать ее в разделе описаний вместе с другими, более важными переменными, неудобно. Кроме того, сразу не всегда понятно, сколько переменных может потребоваться для реализации алгоритма. Выход прост: описать в разделе описаний очевидные переменные, а если при написании алгоритма понадобится дополнительная переменная, описать ее прямо внутри блока.

Например, пусть дано x и требуется вычислить y=x7, используя как можно меньше умножений. Сколько при этом понадобится дополнительных переменных - неизвестно. Начнем решение:

var x,y: real;
begin
  readln(x);

Вычислим во вспомогательных переменных x2, x3, после чего воспользуемся формулой x7=x2*x2*x3

  var a: real := x * x;
  var b: real := a * x;
  y := a * a * b;
  writeln(y);
end.

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

Кроме того, тесты показывают, что доступ к внутриблочным переменным в PascalABC.NET по скорости примерно в 2 раза быстрее, чем к глобальным.

Автоопределение типа переменной при описании

Имя типа в описании

var i: integer := 1;

избыточно. Ведь константа 1 имеет тип integer. Поэтому достаточно написать:

var i := 1;

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

Еще более показательно автоопределение типа в случае обобщенных типов:

var d := new Dictionary<string,integer>;

вместо

var d: Dictionary<string,integer> := new Dictionary<string,integer>;

Описание переменных в заголовке цикла for

Одной из проблем использования циклов for в языке Pascal является некорректное использование переменной-параметра цикла после цикла. Кроме того, описание такой переменной в разделе описаний замусоривает его.

В PascalABC.NET можно описывать параметр цикла for непосредственно в заголовке цикла:

var str := '';
for c: char := 'a' to 'z' do
  str += c;

Oбласть видимости такой переменной ограничена заголовком и телом цикла. Кроме того, можно использовать автоопределение типа параметра цикла, пользуясь следующей разновидностью описания в заголовке цикла:

var p := 1;
for var i := 1 to 10 do
  p *= i;

Вывод

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

News

10.07.23. Release PascalABC.NET 3.9.0. All changes are here.

09.03.22. Release  PascalABC.NET 3.8.3. Main features: for loop with step, foreach loop with index. All changes are here.

07.02.22. Release PascalABC.NET 3.8.2. What's new in 3.8.2.

24.08.21. Release PascalABC.NET 3.8.1. Main features - [Cache] attribute and PlotWPF unit. What's new in version 3.8.1.

07.03.21. PascalABC.NET 3.8 release. Slices of multidimensional arrays and unpacking of lambda expressions parameters into variables. What's new in version 3.8..