Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Глава 5. Переменные и типизированные константы

Описания переменных

             Описание переменной  представляет собой список идентификато-
        ров, которые обозначают новые переменные и их типы.

         описание     -------------  ----  ----                ----
         переменной ->¦список иден-+->¦ : +->¦тип+-T-----------T->¦ ; +>
                      ¦тификаторов ¦  L----  L---- ¦           ¦  L----
                      L-------------               ¦ ---------¦
                                                   L>¦absolute+-
                                                     L---------

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

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

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

             var
               X,Y,Z: real;
               I,J,K: integer;
               Digit: 0..9;
               C: Color;
               Done,Error: boolean;
               Operator: (plus, minus, times);
               Hue1,Hue2: set of Color;
               Today: Date;
               Results: MeasureList;
               P1,P2: Person;
               Matrix: array[1..10,1..10] of Real;

             Переменные, описанные  вне  процедуры и функции,  называются
        глобальными переменными и располагаются в сегменте данных.  Пере-
        менные,  описанные в самой процедуре или функции,  называются ло-
        кальными переменными и располагаются в сегменте стека.


Сегмент данных

Максимальный размер сегмента данных равен 65520 байт. При компоновке программы (что автоматически осуществляется в конце компиляции программы) глобальные переменные всех модулей, исполь- зуемых программой, а также собственные глобальные переменные программы, размещаются в сегменте данных. Если для глобальных переменных требуется более 65520 байт, то следует распределить большие структуры в виде динамических пе- ременных. Дальнейшее описание этой темы можно найти в разделе "Указатели и динамические переменные" настоящей главы.

Сегмент стека

Размер сегмента стека устанавливается с помощью директивы компилятора $M и лежит в пределах от 1024 до 65520 байт. По умол- чанию размер стека равен 16384 байт. При каждой активизации (вызове) процедуры или функции в стек помещается множество локальных переменных. При завершении работы память, занимаемая локальными переменными, освобождается. В любой момент выполнения программы общий размер локальных переменных в активных процедурах и функциях не должен превышать размера сег- мента стека. Примечание: Если вы пишете приложение для Windows, то Windows налагает на сегменты данных и стека специальные требования, так что рабочий максимум стека и область сег- мента данных могут быть меньше, чем упомянутые максимальные области сегмента данных и стека. Директива компилятора $S используется для проверок перепол- нения стека в программе. В состоянии {$S+}, принятом по умолча- нию, генерируется код, осуществляющий проверку переполнения стека в начале каждой процедуры или функции. В состоянии {$S-} такие проверки не проводятся. Переполнение стека может вызвать аварий- ное завершение работы системы, поэтому не следует отменять про- верки стека, если нет абсолютной уверенности в том, что перепол- нения не произойдет.

Абсолютные переменные

Переменные можно описать так, что они будут располагаться по определенному адресу в памяти, и в этом случае они называются аб- солютными переменными. Описание таких переменных должно содержать после типа оператор absolute: описание --------- ---------- ---- ---------- абсолютной --->¦absolute+-T->¦целое без+->¦ : +->¦целое без+-T-> переменной L--------- ¦ ¦ знака ¦ L---- ¦ знака ¦ ¦ ¦ L---------- L---------- ¦ ¦ -------------- ¦ L------>¦идентификатор+------------- ¦ переменной ¦ L-------------- Отметим, что список идентификаторов в описании переменной при указании оператора absolute может содержать только один иден- тификатор. Первая часть оператора absolute содержит сегмент и смещение, то есть адрес, по которому переменная должна быть размещена. CrtMode : byte absolute $0040:$0049; Первая константа обозначает базу сегмента, а вторая опреде- ляет смещение внутри этого сегмента. Обе константы не должны вы- ходить за пределы диапазона от $0000 до $FFFF (от 0 до 65535). В программах защищенного режима DOS и в Windows первую форму оператор absolute нужно использовать очень аккуратно, если вообще стоит это делать. Во время выполнения прикладной программы Windows или DOS защищенного режима она может не иметь полномочий доступа к областям памяти вне вашей программы. Попытка доступа к этим областям памяти может привести к сбою программы. Вторая форма оператора absolute используется для описания переменной, которая помещается "поверх" другой переменной, то есть по тому же самому адресу, что и другая переменная. var Str: string[32]; StrLen: byte absolute Str; Это описание указывает, что переменная StrLen должна разме- щаться с того же адреса, что и переменная Str, а поскольку первый байт строковой переменной содержит динамическую длину строки, то StrLen будет содержать длину Str. Эту вторую форму оператора absolute можно без опасения ис- пользовать при программировании в Windows или в защищенном режиме DOS. Память, к которой вы обращаетесь, находится в области прог- раммы.

Ссылки на переменные

Ссылка на переменную может обозначать следующее: - переменную; - компонент в переменной структурного или строкового типа; - динамическую переменную, на которую указывает переменная типa указатель. Синтаксис ссылки на переменную имеет вид: -------------- ссылка на -T-->¦идентификатор+----------------------------T--> переменную ¦ ¦ переменной ¦ ^^ ------------- ¦ ¦ L-------------- ¦L--+квалификатор¦<-- ¦ ---------------- ¦ L------------- +-->¦приведение типа+------+ ¦ ¦ переменной ¦ ¦ ¦ L---------------- L----- ¦ ---------- ------------- ¦ L-->¦выражение+->¦квалификатор+--- L---------- L------------- Отметим, что синтаксис ссылки на переменную допускает ис- пользование выражения, вычисляющего значение ссылочного типа. Вы- ражение должно следовать за квалификатором, разыменовывающим ссы- лочное значение (или индексирующим значением указателя, если с помощью директивы {$X+} разрешен расширенный синтаксис), что дает фактическую ссылку на переменную.

Квалификаторы

Обращение к функции представляет собой идентификатор пере- менной с несколькими квалификаторами или без них, которые изменя- ют значение обращения к функции. ------- квалификатор --T-->¦индекс+----------> ¦ L------- ^ ¦ ------------- ¦ +-->¦ десигнатор +--+ ¦ ¦ поля ¦ ¦ ¦ L------------- ¦ ¦ ---- ¦ L-->¦ ^ +------------ L---- Идентификатор массива без квалификатора является ссылкой на весь массив, например: Results Идентификатор массива с указанным индексом обозначает конк- ретный элемент массива, в данном случае структурную переменную: Results[Current+1] В случае, если элементом является запись, за индексом можно указать обозначение поля. В этом случае ссылка на переменную оз- начает конкретное поле конкретного элемента массива: Results[Current+1].Data Десигнатор поля в указателе-поле может сопровождаться сим- волом указателя (^) с тем, чтобы указать различие между указате- лем-полем и динамической переменной, на которую он указывает. Results[Current+1].Data^ Если переменная, на которую указывается, является массивом, то можно добавить индексы для обозначения компонентов этого мас- сива. Results[Current+1].Data^[J]

Массивы, строки и индексы

Конкретный элемент массива обозначается с помощью ссылки на переменную массива, за которой указывается индекс, определяющий данный элемент. Конкретный символ в строковой переменной обозначается с по- мощью ссылки на строковую переменную, за которой указывается ин- декс, определяющий позицию символа. ---- ---------- ---- индекс -->¦ [ +------->¦выражение+----T-->¦ ] +--> L---- ^ L---------- ¦ L---- ¦ ---- ¦ L-------+ , ¦<-------- L---- Индексные выражения обозначают компоненты в соответствующей размерности массива. Число выражений не должно превышать числа индексных типов в описании массива. Более того, тип каждого выра- жения должен быть совместимым по присваиванию с соответствующим индексным типом. В случае многомерного массива можно использовать несколько индексов или несколько выражений в индексе. Например: Matrix[I][J] что тождественно записи: Matrix[I,J] Строковую переменную можно проиндексировать с помощью оди- ночного индексного выражения, значение которого должно быть в ди- апазоне 0...n, где n - указанный в описании размер строки. Это дает доступ к каждому символу в строковом значении, если значение символа имеет тип Char. Первый символ строковой переменной (индекс 0) содержит дина- мическую длину строки, то есть Length(S) тождественно Ord(S[0]). Если атрибуту длины присваивается значение, то компилятор не про- веряет, является ли это значение меньшим описанного размера стро- ки. Вы можете указать индекс строки и вне ее текущей динамической длины. В этом случае считываемые символы будут случайными, а присваивания вне текущей длины не повлияют на действительное зна- чение строковой переменной. Когда с помощью директивы компилятора {$X+} разрешен расши- ренный синтаксис, значение PChar может индексироваться одиночным индексным выражением типа Word. Индексное выражение задает смеще- ние, которое нужно добавить к символу перед его разыменованием для получения ссылки на переменную типа Char.

Записи и десигнаторы полей

Конкретное поле переменной-записи обозначается с помощью ссылки на переменную-запись, после которой указывается обозначе- ние поля, специфицирующее это поле. ---- -------------- обозначение поля --->¦ . ¦--->¦идентификатор¦---> L---- ¦ поля ¦ L-------------- Приведем несколько примеров десигнаторов полей: Today.Year Results[1].Count Result[1].When.Month В операторе, входящем в оператор with, обозначению поля не должна предшествовать ссылка на переменную, содержащую запись.

Десигнаторы компонентов объекта

Формат десигнатора компонента объекта совпадает с форматом десигнатора поля записи. То есть, он состоит из экземпляра (ссыл- ки на переменную), за которым следует точка и идентификатор ком- понента. Десигнатор компонента, который обозначает метод, называ- ется десигнатором метода. К экземпляру объектного типа можно применить оператор with. В этом случае при ссылке на компоненты объектного типа экземпляр и точку можно опустить. Экземпляр и точку можно опустить также в любом блоке метода. При этом эффект будет тот же, что и при записи перед ссылкой на компонент Self и точки.

Переменные-указатели и динамические переменные

Значением переменной-указателя является или nil (то есть пустое значение), или адрес значения, указывающий на динамическую переменную. Ссылка на динамическую переменную, на которую указывает пе- ременная-указатель, записывается в виде переменной-указателя, после которой ставится символ указателя (^). Динамические переменные и значения их указателей создаются с помощью стандартных процедур New и GetMem. Вы можете использовать операцию @ и стандартную функцию Ptr для создания значений указа- теля, которые рассматриваются как указатели динамических перемен- ных. Значение nil не указывает ни на какую переменную. Если вы попытаетесь получить доступ к динамической переменной при неопре- деленном значении указателя или указателе, равном nil, результат будет неопределенным. Приведем несколько примеров ссылок (указателей) на динами- ческие переменные: P1^ P1.Sibling^ Results[1].Data^

Приведение типов переменных

Ссылка на переменную одного типа может быть преобразована в ссылку на переменную другого типа с помощью приведения типов пе- ременных. -------------- ---- ----------- ---- приведение --->¦идентификатор+-->¦ ( +-->¦ссылка на +-->¦ ) +-> типов ¦ типа ¦ L---- ¦переменную¦ L---- L-------------- L----------- Когда приведение типов применяется к ссылке на переменную, ссылка на переменную рассматривается как экземпляр типа, предс- тавленного идентификатором типа. Размер переменной (число байт, занимаемых переменной) должен быть равен размеру типа, представ- ленного идентификатором типа. После приведения типа переменной можно указать один или несколько квалификаторов, если это допус- кается указанным типом. Примечание: Определять допустимость приведения типа должен программист. Приведем несколько примеров приведения типов переменных: type TByteRec = record lo, hi: byte; end; TWordRec = record low, high: word; end; TPtrRec = record ofs, seg: word; end; PByte = ^Byte; var B: byte; W: word; L: longint; P: pointer; begin W := $1234; B := TByteRec(W).lo; TByteRec(W).hi := 0; L := $1234567; W := TWordRec(L).lo; B := PByte(L)^; P := Ptr($40,$49); W := TPtrRec(P).seg; Inc(TPtrRec(P).Ofs,4); end. Обратите внимание на использование для доступа к младшим и старшим байтам слова типа TByteRec: это соответствует встроенным функциям Lo и Hi, только над левой частью в операции присваивание может выполняться приведение типа. Отметим также, что для доступа к младшим и старшим словам длинного целого, а также к смещению и адресу сегмента указателя используются типы TWordRec и TPtrRec. Borland Pascal также полностью поддерживает приведение типов для процедурных типов. Например, имея следующие описания: type Func = function(X: Integer): Integer; var F: Func; P: Pointer; N: Integer; вы можете построить следующие присваивания: F := Func(P); { присвоить F значение процедурного типа в P } Func(P) := F; { присвоить P значение процедурного типа в F } @F := P; { присвоить F значение-указатель в P } P := @F; { присвоить P значение-указатель в F } N := F(N); { вызвать функцию через F } N := Func(P)(N); { вызвать функцию через P } Обратите в частности внимание на операцию получения адреса @, которая применяется к переменной процедурного типа. Ее можно использовать в левой части присваивания. Кроме того, отметьте приведение типа на последней строке при вызове функцию через пе- ременную-указатель.

Типизированные константы

Типизированные константы можно сравнить с инициализированны- ми переменными - переменными, значения которых определяются на входе в их блок. В отличие от нетипизированных констант в описа- нии типизированной константы указывается как тип, так и значение константы. описание типизированной константы ¦ -------------- ---- ---- ---- --------------- L->¦идентификатор+->¦ : +->¦тип+->¦ = +->¦типизированная+--> L-------------- L---- L---- L---- ¦ константа ¦ L--------------- типизированная -------------------- константа ------T--->¦ константа +-------> ¦ L-------------------- ^ ¦ -------------------- ¦ +--->¦ адресная константа+---+ ¦ L-------------------- ¦ ¦ -------------------- ¦ +--->¦ константа-массив +---+ ¦ L-------------------- ¦ ¦ ------------------- ¦ +--->¦ константа-запись +----+ ¦ L------------------- ¦ ¦ -------------------- ¦ +--->¦ константа-объект +---+ ¦ L-------------------- ¦ ¦ -------------------- ¦ L--->¦константа-множество+---- L-------------------- Типизированные константы можно использовать точно так же, как переменные того же самого типа, и они указываются в левой части оператора присваивания. Отметим, что типизированные конс- танты инициализируются только один раз - в начале выполнения программы. Таким образом, при каждом новом входе в процедуру или функцию локально описанные типизированные константы заново не инициализируются. Кроме обычных выражений-констант значение типизированной константы может задаваться с помощью адресного выражения-констан- ты. Адресное выражение-константа - это выражение, предусматриваю- щее получение адреса, смещения или сегмента глобальной перемен- ной, типизированной константы, процедуры или функции. Адресные выражения-константы не могут ссылаться на локальные переменные (расположенные в стеке) или динамические переменные (размещенные в динамически распределяемой области памяти), поскольку их адреса нельзя вычислить на этапе компиляции.

Константы простого типа

Описание типизированной константы с простым типом означает указание значения константы: const Maximum : integer = 9999; Factor : real = -0.1; Breakchar : char = #3; Как уже упоминалось ранее, значение типизированной константы можно задать с помощью адресного выражение-константы, то есть вы- ражения, в котором используются адрес, смещение или сегмент гло- бальной переменной, типизированной константы, процедуры или функ- ции. Например: var Buffer: array[0..1023] of Byte; const BufferOfs: Word = Ofs(Buffer); BufferSeg: Word = Seg(Buffer); Поскольку типизированная константа фактически представляет собой переменную со значением константы, она не является взаимо- заменяемой для обычных констант. Например, она не может использо- ваться в описании других констант или типов. const Min : integer = 0; Max : integer = 99; type Vector = array[Min..Max] of integer; Описание Vector является недопустимым, поскольку Min и Max являются типизированными константами.

Константы строкового типа

Описание типизированной константы строкового типа содержит максимальную длину строки и ее начальное значение: const Heading : string[7] = 'Section'; NewLine : string[2] = #13#10; TrueStr : string[5] = 'Yes'; FalseStr : string[5] = 'No';

Константы структурного типа

Описание константы структурного типа определяет значение каждого компонента структуры. Borland Pascal поддерживает описа- ния констант типа массив, запись, множество и указатель. Констан- ты файлового типа и константы типа массив или запись, содержащие компоненты файлового типа, не допускаются.

Константы типа массив

Описание константы типа массив содержит значения элементов, заключенные в скобки и разделенные запятыми. ---- --------------- ---- константа-массив --->¦ ( +---->¦типизированная+--T->¦ ) +--> L---- ^ ¦ константа ¦ ¦ L---- ¦ L--------------- ¦ ¦ ---- ¦ L------+ , ¦<--------- L---- Приведем пример константы типа массив: 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), и массив содержит строку с завершающим нулем. Примечание: Подробнее о строках с завершающим нулем рассказывается в Главе 18. При описании константы типа "многомерный массив" константы каждой размерности заключаются в отдельные скобки и разделяются запятыми. Расположенные в середине константы соответствуют самым правым размерностям. Описание: type Cube = array[0..1,0..1,0..1] of integer; 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

Константы типа запись

Описание константы типа запись содержит идентификатор и зна- чение каждого поля, заключенные в скобки и разделенные точками с запятой. константа-запись ¦ ---- -------------- ---- --------------- ---- L->¦ ( +--->¦идентификатор+->¦ : +->¦типизированная+-T->¦ ) +-> L---- ^ ¦ поля ¦ L---- ¦ константа ¦ ¦ L---- ¦ L-------------- L--------------- ¦ ¦ ---- ¦ L-------------------+ ; ¦<------------------- L---- Приведем несколько примеров констант-записей: 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); Константы объектного типа, которые содержат виртуальные ме- тоды, не требуется инициализировать с помощью вызова конструкто- ра. Эта инициализация автоматически выполняется компилятором.

Константы множественного типа

Описание константы множественного типа может содержать нес- колько элементов, заключенных в квадратные скобки и разделенных запятыми. Каждый элемент такой константы представляет собой конс- танту или отрезок типа, состоящий из двух констант, разделенных двумя точками. ---- ---- константа-множество ->¦ [ +-T---------------------------->¦ ] +> L---- ¦ ------------------ ^ L---- L--->¦константа-элемент+-T-- ^ L------------------ ¦ ¦ ---- ¦ L--------+ , ¦<--------- L---- ---------- константа-элемент ---->¦константа+--T-------------------------> L---------- ¦ --- ---------- ^ L->¦..+-->¦константа+--- L--- L---------- Приведем несколько примеров констант-множеств: 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 = ( 'Ноль', 'Один', 'Два', 'Три', 'Четыре', 'Пять', 'Шесть', 'Семь', 'Восемь', 'Девять'); Результатом будет то, что указатель теперь указывает на об- ласть памяти, содержащую копию строкового литерала с завершающим нулем. Подробности вы можете найти в Главе 18 "Строки с завершаю- щим нулем".

Константы процедурного типа

Константы процедурного типа должны определять идентификатор процедуры или функции, совместимый по присваиванию с типом конс- танты. ------------------ процедурная константа ------T--->¦константа-элемент+-----------> ¦ L------------------ ^ ¦ ------------------ ¦ +--->¦константа-элемент+---+ ¦ L------------------ ¦ ¦ ---- ¦ L--------->¦nil+------------ L---- Приведем следующий пример: type ErrorProc = procedure(ErrorCode: Integer); procedure DefaultError(ErrorCode: Integer); far; begin WriteLn('Error ', ErrorCode, '.'); end; const ErrorHandler: ErrorProc = DefaultError;
                       Назад | Содержание | Вперед

 

Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...