Компилятор Делавар. Нововведения в языке. Типы

Материал из ТХАБ.РФ
Перейти к: навигация, поиск

Нововведения в языке. Типы

Встроенные (базовые) типы данных остались прежними: bool, int, char, byte, word и string, также появились новые.


У типа string появился конструктор, который принимает целое число (константу) в байтах в качестве параметра для выделения буфера памяти под строку. Пример: string str = string(128). Кроме того, стало возможным обращаться к символу в строке посредством индекса, например: char ch = str[0]. В строковых литералах возможен ввод символов с использованием знака косой черты. Например: "abc\n", где \n - означает перевод строки. Возможен ввод следующих символов: \t - горизонтальная табуляция, \r - возврат каретки, \a - звонок, \" - двойная кавычка, \\ - косая черта. Также можно вставить символ в шестнадцатиричном формате. Пример:

  string s = "insert tab\x9line\x0A;feed".

Добавлен пустой тип void. Появились вещественные типы float и double. Однако, есть некоторые ограничения. Например, вещественную константу можно присвоить переменной (или передать в качестве параметра функции) только типа float.

Теперь, приравнять тип с большей размерностью к типу с меньшей размерностью просто так нельзя. Необходимо использовать явное приведение. Например: int a = 5 byte b = (byte) a. Неявное приведение вещественных типов к целым типам также запрещено. Типы bool, char и byte по-прежнему имеют размерность 8 бит, int, word и float - 32 бита, double - 64 бита. Длина идентификаторов в языке увеличена до 128 символов.

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

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

Объявление ссылочного массива выглядит следующим образом:

  <class_name>[[,]...] varname [ = <class_name>[v1[, v2]...] ]. 

Так, например, для объявления одномерного массива целых чисел ссылочного типа потребуется следующий код:

  int[] arr - будет создана ссылка на одномерный массив целых чисел;
  int[] arr = int[5] - будет также выделена память для хранения пяти элементов массива.
  int[,] arr = int[5,6] - объявление двумерного массива целых чисел и выделение памяти для ссылки на массив и 30 элементов массива.

Возможно также выделение памяти под массив с одновременной его инициализацией:

  int[] arr = { 0, 1, 2 }
  string[] sarr = { "one", "two", "three" }

Объявление двумерного массива целых чисел 2х3 с инициализацией: int[,] arr = { {0, 1, 2}, {4, 5, 6} }

Обратиться к элементу массива можно, указав индекс в квадратных скобках:

  int a = arr[0]

Объявление массива значимого типа имеет несколько иной синтаксис:

  <type_name>[v1[, v2]...] varname. 

Например:

  int[3] arr - объявление одномерного массива целых чисел значимого типа 
  int[2,3] arr = { {0, 1, 2}, {4, 5, 6} } - объявление двумерного массива с инициализацией
  foo[5] fooName - объявление массива значимого типа, состоящего из пяти элементов, где foo некоторый тип, объявленный с помощью ключевого слова type.

Ссылочные типы объявляются с помощью ключевого слова class. Они описываются аналогично значимым типам:

class Name 
{
  [Здесь следует перечень полей пользовательских и базовых типов]
  [конструктор(ы)]
  [метод(ы)]
  [деструктор]
}

Пример:

class dot
{
  int x, y
  dot() 
  {
     x = 0
     y = 0
  }
  dot(int x, int y)
  {
     this.x = x
     this.y = y
  }
  void SetX(int x)
  {
     this.x = x
  }
}

Так как компилятор на текущий момент является однопроходным, методы составного типа должны быть определены до их вызова (это же касается и глобальных функций, для которых, однако, возможна предварительная декларация). На данный момент, все поля и методы пользовательских (составных) типов являются открытыми (public). Для обращения к полям внутри класса можно использовать ключевое слово this (но не обязательно), которое является ссылкой на экземпляр класса.

Объявить переменную ссылочного типа можно следующим образом:

  dot d, при этом выделяется память для хранения ссылки.
  dot c = dot() - с помощью вызова конструктора класса осуществляется создание экземпляра класса, на который сылается переменная с. Память под такой объект выделяется 

в стеке. Поэтому нужно учесть, что при завершении работы функции или метода, где вызывается конструктор ссылочного типа, уничтожается и сам объект. В версии 0.61 компилятора Делавар появилась возможность использовать оператор new, позволяющий создать экземпляр класса в динамической памяти. В этом случае, освободить выделенную память необходимо с помощью оператора delete.

Массив ссылок (не сами объекты) на структуры типа dot объявляется аналогично ссылочным массивам базовых типов:

  dot[] darr = dot[5] 

Для создания элемента массива класса dot используйте вызов конструктора:

  darr[0] = dot()

Теперь можно обращаться к полям и методам экземпляра класса.

Вместо ключевого слова class можно использовать конструкцию pointer type.

Введен новый базовый тип object. Предполагается, что любой пользовательский тип, определяемый с помощью ключевого слова class, наследуется от данного типа. Это удобно при использовании приведений типов. Т.е., любой ссылочный тип может быть присвоен (или приведен к) типу object:

   object o = c, где с - экземпляр типа dot.

Ссылке на объект или массив, а также типу object можно присвоить фиксированный адрес, используя явные приведения:

  object o = (object)(word) expr, где expr - выражение, приводимое к беззнаковому целому. 

Например, ссылку на объект можно инициализировать следующим образом: dot d = (object)(word) 0. Следует отметить, что константы целого типа, большие -128 и меньшие 256 имеют размерность байта. В версии компилятора 0.56 появилась предопределенная константа типа object по имени NULL. Она предназначена для инициализации ссылочных переменных, а также для сравнения таких переменных со специальным нулевым значением. Поэтому вышеуказанную инициализацию правильнее сделать так: dot d = (dot) NULL. Аналогичная инициализация ссылки на массив может выглядеть следующим образом: dot[] dArr = (dot[]) NULL.

В данной версии компилятора отсутствует инициализация составных типов (наподобие dot d = {1, 0}). Для этого используйте конструкторы. Для значимых составных типов в версии 0.59 реализован вызов конструктора по умолчанию (без параметров) в момент объявления переменной.

Появилась возможность задавать перечень констант с помощью ключевого слова enum. Для определения перечня используется следующий синтаксис:

  enum Name
  {
     Value1[=Number],
     ...,
     ValueN[=Number]
  }, где Number - беззнаковое целое число

Если конкретные значения элементам перечисления не заданы, то значения им присваиваются автоматически, начиная с нуля, с инкрементом 1. Пример:

  enum Color
  {
     Red,
     Green = 5,
     Blue
  }

Использование:

  Color clr = Color.Red

Размерность такой константы составляет машинное слово. Перечисление возможно преобразовать к целому типу путем явного приведения:

int b = (int) clr

В языке также появилось ключевое слово delegate, которое позволяет объявить новый тип переменной - ссылку на функцию. На данный момент имеется ограничение: кандидатом в делегаты может быть только глобальная функция. Объявляется делегат следующим образом:

  delegate <decl_function>, где decl_function - прототип функции.

Пример использования:

  int printf(string, ...)
  delegate int MyProc(int a, int b);
  int Summa(int a, int b)
  {
     return a + b
  }
  void Start()
  {
     MyProc Proc = MyProc(Summa);
     printf("%d\n", Proc(5, 5));
  }


В функции Start создается переменная Proc типа делегат MyProc, далее вызывается конструктор делегата, который принимает в качестве параметра для инициализации переменной Proc подходящую функцию Summa. Естественно, что сигнатура функции должна совпадать с сигнатурой прототипа, объявленного в делегате.

Из ограничений для типов перечисление и делегат нужно отметить отсутствие реализации массивов данных типов.

См. также


Яндекс | Картинки | Видео | Карты | Карты ОСМ | Спутник | Гугл | Вольфрам-Альфа | РуВики | EnWiki