алгоритмы. алгор. Компьютерная программа представляет собой список команд, которые указывают компьютеру
![]()
|
, определенный во вложенном пространстве имен , скрывает идентификатор , определенный во внешнем пространстве имен Например , в коде var var var var i: integer; procedure procedure procedure procedure p; var var var var i: integer; begin begin begin begin i := 5; end end end end; значение 5 будет присвоено переменной i , описанной в процедуре p ; внутри же процедуры p сослаться на глобальную переменную i невозможно Переменные , описанные внутри блока , не могут иметь те же имена , что и переменные из раздела описаний этого блока Например , следующая программа ошибочна : var var var var i: integer; begin begin begin begin var var var var i: integer; // ошибка end end end end. В производных классах , напротив , можно определять члены с теми же именами , что и в базовых классах , при этом их имена скрывают соответствующие имена в базовых классах Для обращения к одноименному члену базового класса из метода производного класса используется ключевое слово inherited inherited inherited inherited : type type type type A=class class class class i: integer; procedure procedure procedure procedure p; begin begin begin begin i := 5; end end end end; end end end end; B=class class class class(A) i: integer; procedure procedure procedure procedure p; begin begin begin begin i := 5; inherited inherited inherited inherited p; end end end end; end; end; end; end; - Алгоритм поиска имени в классе следующий: вначале имя ищется в текущем классе, затем в его базовых классах, а если не найдено, то в глобальной области видимости. Алгоритм поиска имени в глобальной области видимости при наличии нескольких подключенных модулей следующий: вначале имя ищется в текущем модуле, затем, если не найдено, по цепочке подключенных модулей в порядке справа налево. Например, в программе uses unit1,unit2; begin id := 2; end. описание переменной id будет искаться вначале в основной программе, затем в модуле unit2, затем в модуле unit1. При этом в разных модулях могут быть описаны разные переменные id. Данная ситуация означает, что unit1 образует внешнее пространство имен, пространство имен unit2 в него непосредственно вложено, а пространство имен основной программы вложено в unit2. Если в последнем примере оба модуля - unit1 и unit2 - определяют переменные id, то рекомендуется уточнять имя переменной именем модуля, используя конструкцию ИмяМодуля.Имя: uses unit1,unit2; begin unit1.id := 2; end. Обзор типов Типы в PascalABC.NET подразделяются на простые, строковые , структурированные, типы указателей , процедурные и классовые типы. К простым относятся целые и вещественные типы, логический , символьный , перечислимый и диапазонный тип. Структурированные типы образованы массивами , записями , множествами и файлами Все простые типы, кроме вещественного, называются порядковыми. Только значения этих типов могут быть индексами массивов с фиксированной размерностью и параметрами цикла for. Кроме того, для порядковых типов используются функции Ord, Pred и Succ, а также процедуры Inc и Dec. Все типы, кроме типов указателей, являются производными от типа Object (как в .NET). Каждый тип в PascalABC.NET имеет отображение на тип .NET . Тип указателя принадлежит к неуправляемому коду и моделируется типом void*. Все типы подразделяются на две большие группы: размерные и ссылочные. Данные размерных типов располагаются на стеке, данные ссылочных типов представляют собой указатели, хранящие адрес динамической памяти, где расположены собственно данные указанного типа. К размерным относятся все простые типы, указатели, записи, статические массивы. К ссылочным типам относятся множества, классы, динамические массивы, строки, файлы и процедурный тип. Строковый тип Строки имеют тип string , состоят из набора последовательно расположенных символов char и используются для представления текста Строки могут иметь произвольную длину К символам в строке можно обращаться , используя индекс : s[i] обозначает i - тый символ в строке , нумерация начинается с единицы Если индекс i выходит за пределы длины строки , то генерируется исключение Операция + для строк означает конкатенацию ( слияние ) строк Например : 'Петя'+'Маша' = 'ПетяМаша' Операция += для строк добавляет в конец строки - левого операнда строку - правый операнд Например : var var var var s: string := 'Петя'; s += 'Маша'; // s = 'ПетяМаша' Строки реализуются типом System.String платформы .NET и представляют собой ссылочный тип Таким образом , все операции над строками унаследованы от типа System.String Однако , в отличие от .NET - строк , строки в PascalABC.NET изменяемы Например , можно изменить s[i] ( в .NET нельзя ). Более того , строки string в PascalABC.NET ведут себя как размерные : после var var var var s2 := 'Hello'; var var var var s1 := s2; s1[2] := 'a'; строка s1 не изменится Аналогично при передаче строки по значению в подпрограмму создается копия строки , т е обеспечивается поведение , характерное для Delphi Object Pascal, а не для .NET. Однако , строке можно присвоить nil , что необходимо для работы с NET- кодом Кроме того , в PascalABC.NET реализованы размерные строки Для их описания используется тип string[n] , где n - константа целого типа , указывающая длину строки В отличие от обычных строк , содержимое размерных строк при присваивании и передаче по значению копируется Кроме того , размерные строки , в отличие от обычных , можно использовать как компоненты типизированных файлов Для совместимости с Delphi Object Pascal в стандартном модуле описан тип shortstring=string[255] Стандартные подпрограммы работы со строками представлены здесь В .NET каждый тип является классом Члены класса string приведены здесь Отметим , что в методах класса string считается , что строки индексируются с нуля Указатели Указатель - это ячейка памяти, хранящая адрес. В PascalABC.NET указатели делятся на типизированные (содержат адрес ячейки памяти данного типа) и бестиповые (содержат адрес оперативной памяти, не связанный с данными какого-либо определенного типа). Тип указателя на тип T имеет форму ^T, например: type pinteger = ^integer; var p: ^record r,i: real end; Бестиповой указатель описывается с помощью слова pointer. Для доступа к ячейке памяти, адрес которой хранит типизированный указатель, используется операция разыменования ^: var i: integer; pi: ^integer; pi := @i; // указателю присвоили адрес переменной i pi^ := 5; // переменной i присвоили 5 Операция разыменования не может быть применена к бестиповому указателю. Типизированный указатель может быть неявно преобразован к бестиповому: var p: pointer; pr: ^real; p := pr; Обратное преобразование также может быть выполнено неявно: pr := p; pr^ := 3.14; Указатели можно сравнивать на равенство (=) и неравенство (<>). Для того чтобы отметить тот факт, что указатель никуда не указывает, используется стандартная константа nil (нулевой указатель) : p := nil. Внимание ! Ввиду особенностей платформы .NET тип T типизированного указателя не должен быть ссылочным или содержать ссылочные типы на каком-то уровне (например, запрещены указатели на записи, у которых одно из полей имеет ссылочный тип). Причина такого ограничения проста: указатели реализуются неуправляемым кодом, который не управляется сборщиком мусора. Если в памяти, на которую указывает указатель, содержатся ссылки на управляемые переменные, то они становятся недействительными после очередной сборки мусора. Исключение составляют динамические массивы и строки, обрабатываемые особым образом. То есть, можно делать у казатели на записи , содержащие в качестве полей строки и динамические массивы. Процедурный тип Переменные , предназначенные для хранения процедур и функций , называются процедурными Тип процедурной переменной представляет собой заголовок процедуры или функции без имени Например : type type type type procI = procedure procedure procedure procedure(i: integer); funI = function function function function: integer; Процедурной переменной можно присвоить процедуру или функцию с совместимым типом : procedure procedure procedure procedure my(i: integer); begin begin begin begin end end end end; function function function function f: integer; begin begin begin begin end end end end; var var var var p1: procI; f1: funI; p1 := my; f1 := f; После этого можно вызвать процедуру или функцию через эту процедурную переменную , пользуясь обычным синтаксисом вызова : p1(5); write(f1); Для процедурных переменных принята структурная эквивалентность типов : можно присваивать друг другу и передавать в качестве параметров процедурные переменные , совпадающие по структуре ( типы и количество параметров , тип возвращаемого значения ). Обычно процедурные переменные передаются как параметры для реализации обратного вызова : procedure procedure procedure procedure forall(var var var var a: array array array array of of of of real; p: procedure procedure procedure procedure(var var var var r: real)); begin begin begin begin for for for for var var var var i := 0 to to to to a.Length-1 do do do do p(a[i]); end end end end; procedure procedure procedure procedure mult2(var var var var r: real); begin begin begin begin r := 2*r; end end end end; procedure procedure procedure procedure add3(var var var var r: real); begin begin begin begin r := r + 3; end end end end; procedure procedure procedure procedure print(var var var var r: real); begin begin begin begin write(r,' '); end end end end; forall(a,mult2); // умножение элементов массива на 2 forall(a,add3); // увеличение элементов массива на 3 forall(a,print); // вывод элементов массива Процедурная переменная может хранить нулевое значение , которое задается константой nil Вызов подпрограммы через нулевую процедурную переменную приводит к ошибке Процедурные переменные реализуются через делегаты .NET. Это означает , что они могут хранить несколько подпрограмм Для добавления / отсоединения подпрограмм используются операторы += и -= : p1 += mult2; p1 += add3; forall(a,p1); Подпрограммы в этом случае вызываются в порядке прикрепления : вначале умножение , потом сложение Отсоединение неприкрепленных подпрограмм не выполняет никаких действий : p1 -= print; Кроме того , к процедурной переменной можно прикреплять / откреплять статические и экземплярные методы классов Пример . type type type type A = class class class class private private private private x: integer; public public public public constructor constructor constructor constructor Create(xx: integer); begin begin begin begin x := xx; end; end; end; end; procedure procedure procedure procedure pp; begin begin begin begin write(x); end end end end; procedure procedure procedure procedure ppstatic; static static static static; begin begin begin begin write(1); end end end end; end end end end; begin begin begin begin var var var var p: procedure procedure procedure procedure; var var var var a1: A := new A(5); p += a1.pp; p += A.ppstatic; p; end end end end. В результате запуска данной программы на экран будет выведено : 51 Целые типы Ниже приводится таблица целых типов, содержащая также их размер и диапазон допустимых значений. Тип Размер, байт Диапазон значений shortint 1 -128..127 smallint 2 -32768..32767 integer , longint 4 -2147483648..2147483647 int64 8 - 9223372036854775808..9223372036854775807 byte 1 0..255 word 2 0..65535 longword , cardinal 4 0..4294967295 uint64 8 0..18446744073709551615 Типы integer и longint , а также uint64 и cardinal являются синонимами. Максимальные значения для каждого целого типа определены как внешние стандартные константы : MaxInt64 , MaxInt , MaxSmallInt , MaxShortInt , MaxUInt64 , MaxLongWord , MaxWord , MaxByte Для каждого целого типа T определены также следующие константы как члены класса T.MinValue - константа, представляющая минимальное значение типа T ; T.MaxValue - константа, представляющая максимальное значение типа T ; Константы модуля PABCSystem MaxShortInt = shortint.MaxValue; Максимальное значение типа shortint MaxByte = byte.MaxValue; Максимальное значение типа byte MaxSmallInt = smallint.MaxValue; Максимальное значение типа smallint MaxWord = word.MaxValue; Максимальное значение типа word MaxInt = integer.MaxValue; Максимальное значение типа integer MaxLongWord = longword.MaxValue; Максимальное значение типа longword MaxInt64 = int64.MaxValue; Максимальное значение типа int64 MaxUInt64 = uint64.MaxValue; Максимальное значение типа uint64 MaxDouble = real.MaxValue; Максимальное значение типа double MinDouble = real.Epsilon; Минимальное положительное значение типа double MaxReal = real.MaxValue; Максимальное значение типа real MinReal = real.Epsilon; Минимальное положительное значение типа real MaxSingle = single.MaxValue; Максимальное значение типа single MinSingle = single.Epsilon; Минимальное положительное значение типа single Pi = 3.141592653589793; Константа Pi E = 2.718281828459045; Константа E Вещественные типы Ниже приводится таблица вещественных типов, содержащая их размер, количество значащих цифр и диапазон допустимых значений: Тип Размер, байт Количество значащих цифр Диапазон значений real 8 15-16 -1.8 ·10 308 .. 1.8 ·10 308 double 8 15-16 -1.8 ·10 308 .. 1.8 ·10 308 single 4 7-8 -3.4 ·10 38 .. 3.4 ·10 38 Типы real и double являются синонимами. Самое маленькое положительное число типа real приблизительно равно 5.0·10 -324 , для типа single оно составляет приблизительно 1.4 ·10 -45 Максимальные значения для каждого вещественного типа определены как внешние стандартные константы : MaxReal, MaxDouble и MaxSingle. Для каждого вещественного типа R определены также следующие константы как члены класса: R.MinValue - константа, представляющая минимальное значение типа R ; R.MaxValue - константа, представляющая максимальное значение типа R ; R.Epsilon - константа, представляющая самое маленькое положительное число типа R ; R.NaN - константа, представляющая не число (возникает, например, при делении 0/0); R.NegativeInfinity - константа, представляющая отрицательную бесконечность ( возникает, например, при делении -2/0); R.PositiveInfinity - константа, представляющая положительную бесконечность ( возникает, например, при делении 2/0). Для каждого вещественного типа R определены следующие статические функции: R.IsNaN(r) - возвращает True , если в r хранится значение R.NaN , и False в противном случае; R.IsInfinity(r) - возвращает True , если в r хранится значение R.PositiveInfinity или R.NegativeInfinity , и False в противном случае; R.IsPositiveInfinity(r) - возвращает True , если в r хранится значение R.PositiveInfinity , и False в противном случае; R.IsNegativeInfinity(r) - возвращает True , если в r хранится значение R.NegativeInfinity , и False в противном случае; R.Parse(s) - функция, конвертирующая строковое представление числа в значение типа R Если преобразование невозможно, то генерируется исключение; R.TryParse(s,res) функция, конвертирующая строковое представление числа в значение типа R и записывающая его в переменную res . Если преобразование возможно, то возвращается значение True , в противном случае - False Кроме того, определена экземплярная функция ToString , возвращающая строковое представление переменной типа R Вещественные константы можно записывать как в форме с плавающей точкой, так и в экспоненциальной форме: 1.7 0.013 2.5e3 (2500) 1.4e-1 (0.14) Логический тип Значения логического типа boolean занимают 1 байт и принимают одно из двух значений , задаваемых предопределенными константами True ( истина ) и False ( ложь ). Для логического типа определены статические функции : boolean.Parse(s) - функция , конвертирующая строковое представление числа в значение типа boolean Если преобразование невозможно , то генерируется исключение ; boolean.TryParse(s,res) - функция , конвертирующая строковое представление числа в значение типа boolean и записывающая его в переменную res Если преобразование возможно , то возвращается значение True , в противном случае - False Кроме этого , определена экземплярная функция ToString , возвращающая строковое представление переменной типа boolean Логический тип является порядковым В частности , False < True , Ord(False) =0, Ord(True) =1. Символьный тип Символьный тип char занимает 2 байта и хранит Unicode- символ Символы реализуются типом System.Char платформы .NET. Стандартные подпрограммы работы с символами представлены здесь Члены класса char приведены здесь Для преобразования между символами и их кодами в кодировке Windows (CP1251) используются стандартные функции Chr и Ord : Chr(n) - функция , возвращающая символ с кодом n в кодировке Windows; Ord(с) - функция , возвращающая значение типа byte , представляющее собой код символа c в кодировке Windows. Для преобразования между символами и их кодами в кодировке Unicode используются стандартные функции ChrUnicode и OrdUnicode : ChrUnicode(w) - возвращает символ с кодом w в кодировке Unicode; OrdUnicode(с) - возвращает значение типа word , представляющее собой код символа c в кодировке Unicode. Кроме того , выражение #число возвращает Unicode- символ с кодом число ( число должно находиться в диапазоне от 0 до 65535). Аналогичную роль играют явные преобразования типов : char(w) возвращает символ с кодом w в кодировке Unicode; word(с) возвращает код символа c в кодировке Unicode. Перечислимый и диапазонный типы Перечислимый тип определяется упорядоченным набором идентификаторов type type type type typeName = (value1, value2, ..., valuen); Значения перечислимого типа занимают 4 байта Каждое значение value представляет собой константу типа typeName , попадающую в текущее пространство имен Например : type type type type Season = (Winter,Spring,Summer,Autumn); DayOfWeek = (Mon,Tue,Wed,Thi,Thr,Sat,Sun); К константе перечислимого типа можно обращаться непосредственно по имени , а можно использовать запись typeName.value , в которой имя константы уточняется именем перечислимого типа , к которому она принадлежит : var var var var a: DayOfWeek; a := Mon; a := DayOfWeek.Wed; Для значений перечислимого типа можно использовать функции Ord , Pred и Succ , а также процедуры Inc и Dec Функция Ord возвращает порядковый номер значения в списке констант соответствующего перечислимого типа , нумерация при этом начинается с нуля Для перечислимого типа определена экземплярная функция ToString , возвращающая строковое представление переменной перечислимого типа При выводе значения перечислимого типа с помощью процедуры write также выводится строковое представление значения перечислимого типа Например : type type type type Season = (Winter,Spring,Summer,Autumn); var var var var s: Season; begin begin begin begin s := Summer; writeln(s.ToString); // Summer writeln(s); // Summer end end end end. Диапазонный тип представляет собой подмножество значений целого , символьного или перечислимого типа и описывается в виде a..b , где a - нижняя , b - верхняя граница интервального типа , a < b : var var var var intI: 0..10; intC: 'a'..'z'; intE: Mon..Thr; Тип , на основе которого строится диапазонный тип , называется базовым для этого диапазонного типа Значения диапазонного типа занимают в памяти столько же , сколько и значения соответствующего базового типа |