Приведем пример константы типа массив:
type
Status = (Active,Passive,Waiting);
StatusMap = array[Status] of string[7];
const
StatStr: StatusMap = ('Active','Passive','Waiting');
В этом примере определяется константа-массив StarStr, которая может использоваться для преобразования значений типа Status в соответствующие им строковые представления. ЭлементамимассиваStarStr являются:
StatStr[Active] = 'Active'
StatStr[Passive] = 'Passive'
StatStr[Waiting] = 'Waiting'
Тип элемента константы-массива может быть любым, кроме файлового типа. Упакованные константы строкового типа (символьные массивы) могут быть определены и как одиночные символы, и как строки. Определение:
const
Digits:array[0..9] of
char=('0','1','2','3','4','5','6','7','8','9');
можно представить в более удобном виде:
const
Digits: array[0..9] of char = '0123456789';
При разрешении расширенного синтаксиса (с помощью директивы
компилятора {$X+}) массивы с нулевой базой могут инициализироваться строкой, которая короче, чем описанная длина массива, например:
const
FileName = array[0..79] of Char = 'TEXT.PAS';
В таких случаях оставшиеся символы устанавливаются в NULL (#0), и массив содержит строку с завершающим нулем. При описании константы типа "многомерный массив" константы каждой размерности заключаются в отдельные скобки и разделяются запятыми. Расположенные в середине константы соответствуют самым правым размерностям. Описание:
type
Cube= array[0..1,0..1,0..1] ofinteger;
const
Maze: Cube = (((0,1),(2,3)),((4,5),(6,7)));
задает следующие начальные значения массива Maze:
Maze[0, 0, 0] = 0
Maze[0, 0, 1] = 1
Maze[0, 1, 0] = 2
Maze[0, 1, 1] = 3
Maze[1, 0, 0] = 4
Maze[1, 0, 1] = 5
Maze[1, 1, 0] = 6
Maze[1, 1, 1] = 7
Константы типа запись
Описание константы типа запись содержит идентификатор и значение каждого поля, заключенные в скобки и разделенные точками с запятой.
Приведем несколько примеров констант-записей:
type
Point = record
x,y: real;
end;
Vector = array[0..1] of Point;
Month =
(Jan,Feb,Mar,Apr,May,Jun,Jly,Aug,Sep,Oct,Nov,Dec);
Date = record
d: 1..31; m: Month; y: 1900..1999;
end;
const
Origin : Point = (x: 0.0; y: 0.0);
Line : Vector = ((x: -3.1; y: 1.5),(x: 5.8; y: 3.0));
SomeDay : Date = (d: 2; m: Dec; y: 1960);
Поля должны указываться в том же порядке, как они следуют в описании типа запись. Если запись содержит поля файлового типа, то для этого типа запись нельзя описать константу. Если запись содержит вариант, то можно указывать только поля выбранного варианта. Если вариант содержит поле признака, то его значение должно быть определено.
Константы объектного типа
При описании константы объектного типа используется тот же синтаксис, что и при описании константы типа запись. Значения для элементов (компонентов) метода задаваться не могут. С учетом приводимых ранее описаний объектных типов, приведем некоторые примеры констант объектного типа:
const
ZeroPoint: Point = (X: 0; Y: 0)
ScreenRect: Rect = (A: (X: 0; Y: 0); B: (X: 80; Y: 25);
CountField: NumField = (X: 5; Y: 20; Len: 4; Name: nil;
Value: 0; Min: -999; Max: 999);
Константы объектного типа, которые содержат виртуальные методы, не требуется инициализировать с помощью вызова конструктора. Эта инициализация автоматически выполняется компилятором.
Константы множественного типа
Описание константы множественного типа может содержать несколько элементов, заключенных в квадратные скобки и разделенных запятыми. Каждый элемент такой константы представляет собой константу или отрезок типа, состоящий из двух констант, разделенных двумя точками.
Приведем несколько примеров констант-множеств:
type
Digits = set of 0..9;
Letters = set of 'A'..'Z';
const
EvenDigits: Digits = [0,2,4,6,8];
Vowels : Letters = ['A','E','I','O','U','Y'];
HexDigits : set of '0'..'z' =
['0'..'9','A'..'F','a'..'f'];
Константы ссылочного типа
Описание константы ссылочного типа может содержать только значение nil (пусто). Приведемнесколькопримеров
type
TDirection = (Left, Right, Up, Down);
TStringPtr = ^String;
TNodePtr = ^Node;
TNode = record
Next: NodePtr;
Symbol: StringPtr;
Value: Direction;
end;
const
S1: string[4] = 'DOWN';
S2: string[2] = 'UP';
S3: string[5] = 'RIGHT';
S4: string[4] = 'LEFT';
N1: Node = (Next: nil; Symbol: @S1; Value: Down);
N2: Node = (Next: @N1; Symbol: @S2; Value: Up);
N3: Node = (Next: @N2; Symbol: @S3; Value: Right);
N2: Node = (Next: @N3; Symbol: @S4; Value: Left);
DirectionTable: NodePtr = @N4;
Если разрешен расширенный синтаксис (указана директива компилятора {$X+}), типизированная константа типа PChar может инициализироваться строковой константой, например:
const
Message: PChar = 'Программа завершена';
Prompt: PChar = 'Введите значения: ';
Digits: array[0..9] of PChar = (
'Ноль', 'Один', 'Два', 'Три', 'Четыре',
'Пять', 'Шесть', 'Семь', 'Восемь', 'Девять');
Результатом будет то, что указатель теперь указывает на область памяти, содержащую копию строкового литерала с завершающим нулем.
Константы процедурного типа
Константы процедурного типа должны определять идентификатор процедуры или функции, совместимый по присваиванию с типом константы.
Приведемследующийпример:
type
ErrorProc = procedure(ErrorCode: Integer);
procedure DefaultError(ErrorCode: Integer); far;
begin
WriteLn('Error ', ErrorCode, '.');
end;
const
ErrorHandler: ErrorProc = DefaultError;
3. Приведите полный список базовых целочисленных типов и занимаемый ими размер памяти в байтах
Целочисленные типы - обозначают множества целых чисел в различных диапазонах. Имеется пять целочисленных типов, различающихся диапазоном допустимых значений и размером занимаемой оперативной памяти. Целочисленные типы обозначаются идентификаторами: Byte, ShortInt, Word, Integer, LongInt; их характеристики приведены в следующей таблице.
Таблица 1 - Целочисленные типы
Тип | Диапазон | Размер в байтах |
ByteShortIntWordIntegerLongInt | 0 ... 255-128 ... 1270 ... 65535-32768 ... 32767-2147483648 ... 2147483647 | 11224 |
Значения целых типов записываются в программе привычным способом:
123 4 -3 +345 -699
Наличие десятичной точки в записи целого числа недопустимо. Будет ошибкой записать целое число следующим образом:
123.0
Кроме привычной десятичной формы записи допускается запись целых чисел в шестнадцатиричном формате, используя префикс $, например:
$01AF $FF $1A $F0A1B
Регистр букв A,B, ..., F значения не имеет.
Допустимые операции:
- присваивание;
- все арифметические: +, - ,*, /, div, mod (при обычном делении [/] результат вещественный!);
- сравнение <, >, >=, <=, <>, =.
4. Что такое указатель? Как по указателю можно занести значение? Приведите примеры
Специальными объектами в программах на языках Си++ являются указатели.
Различают указатели-переменные (именно их мы будем называть указателями) и указатели-константы. Значениями указателей служат адреса участков памяти, выделенных для объектов конкретных типов: именно поэтому в определении и описании указателя всегда присутствует обозначение соответствующего ему типа. Эта информация позволяет в последующем с помощью указателя получить доступ ко всему сохраняемому объекту в целом.
Указатели делятся на две категории - указатели на объекты и указатели на функции. Выделение этих двух категорий связано с отличиями в свойствах и правилах использования. Например, указатели ФУНКЦИЙ не допускают применения к ним арифметических операций, а указатели объектов разрешено использовать в некоторых арифметических выражениях. Начнем с указателей объектов.
В простейшем случае определение и описание указателя-переменной на некоторый объект имеют вид:
tуре *имя_ указателя;
где tуре _ обозначение типа; имя_указателя - это идентификатор;
* - унитарная операция раскрытия ссылки (операция разыменования; операция обращения по адресу; операция доступа по адресу), операндом которой должен быть указатель (именно в соответствии с этим правилом вслед за ней следует имя_указателя).
Признаком указателя при лексическом разборе определения или описания служит символ '*', помещенный перед именем. Таким образом, при необходимости определить несколько указателей на объекты одного и того же типа этот символ '*' помещают перед каждым именем. Например, определение int*i1р, *i2р, *iЗр, i; вводит три указателя на объекты целого типа i1р, i2р, i3р и одну переменную i целого типа. Переменной i будет отведено в памяти 2 байта (ТС++ или ВС++), а указатели i1р, i2р, i3р разместятся в участках памяти, размер которых также зависит от реализации, но которые только иногда имеют длину 2 байта.
В совокупности имя типа и символ '*' перед именем воспринимаются как обозначение особого типа данных "указатель на объект данного типа".
При определении указателя в большинстве случаев целесообразно выполнить его инициализацию. Формат определения станет таким:
tуре *имя_ указателя инициализатор;
Как упоминалось, инициализатор имеет две формы записи, поэтому допустимы следующие две формы определения указателей:
tyре *имя_указателя = инициализирующее_выражение;
tурe *имя_указателя (инициализирующее_выражение);
В качестве инициализирующего_выражения должно использоваться константное выражение, частными случаями которого являются:
- явно заданный адрес участка памяти;
- указатель, уже имеющий значение;
- выражение, позволяющее получить адрес объекта с помощью операции '&'.
Если значение константного выражения равно нулю, то это нулевое значение преобразуется к пустому (иначе нулевому) указателю. Синтаксис языка "гарантирует, что этот указатель отличен от указателя на любой объект". Кроме того, внутреннее (битовое) представление пустого указателя может отличаться от битового представления целого значения 0. В компиляторах ТС++ и ВС++ условное нулевое значение адреса, соответствующее значению пустого указателя, имеет специальное обозначение NULL. Примеры определений указателей:
сhаr cc = 'd'; // Символьная переменная (типа сhаr)
сhаr *рс = &cс; // Инициализированный указатель на объект
// типа сhаr
сhаr *рtr(NULL); // Нулевой указатель на объект типа сhаr
сhаr *р; // Неинициализированный указатель на