Перейти к содержимому

Sbyte c что это

  • автор:

Тип данных SByte (Visual Basic)

Содержит 8-разрядные (1-байтовые) целые числа со знаком в диапазоне от –128 до 127.

Комментарии

SByte Используйте тип данных для хранения целочисленных значений, для которых не требуется полная ширина Integer данных или даже половина ширины Short данных . В некоторых случаях среда CLR может иметь возможность тесно упаковывать SByte переменные и экономить потребление памяти.

Значение по умолчанию для типа SByte — 0.

Литеральные назначения

Переменную SByte можно объявить и инициализировать, назначив ей десятичный литерал, шестнадцатеричный литерал, восьмеричный литерал или (начиная с Visual Basic 2017) двоичный литерал.

В следующем примере целые числа, равные -102, представленные как десятичные, шестнадцатеричные и двоичные литералы, назначаются значениям SByte . В этом примере требуется выполнить компиляцию с параметром компилятора /removeintchecks .

Dim sbyteValue1 As SByte = -102 Console.WriteLine(sbyteValue1) Dim sbyteValue4 As SByte = &H9A Console.WriteLine(sbyteValue4) Dim sbyteValue5 As SByte = &B1001_1010 Console.WriteLine(sbyteValue5) ' The example displays the following output: ' -102 ' -102 ' -102 

Префикс &h или &H используется для обозначения шестнадцатеричного литерала, префикса &b или &B для обозначения двоичного литерала и префикса &o или &O для обозначения восьмеричного литерала. У десятичных литералов префиксов нет.

Начиная с Visual Basic 2017, вы также можете использовать символ _ подчеркивания в качестве разделителя цифр для повышения удобочитаемости, как показано в следующем примере.

Dim sbyteValue3 As SByte = &B1001_1010 Console.WriteLine(sbyteValue3) ' The example displays the following output: ' -102 

Начиная с Visual Basic 15.5, вы также можете использовать символ подчеркивания ( _ ) в качестве начального разделителя между префиксом и шестнадцатеричными, двоичными или восьмеричной цифрами. Пример:

Dim number As SByte = &H_F9 

Чтобы использовать символ подчеркивания в качестве начального разделителя, необходимо добавить следующий элемент в файл проекта Visual Basic (*.vbproj):

Если целочисленный литерал выходит за пределы диапазона SByte (то есть, если он меньше SByte.MinValue или больше SByte.MaxValue), возникает ошибка компиляции. Если целочисленный литерал не имеет суффикса, выводится целое число . Если целочисленный литерал находится за пределами Integer диапазона типа, выводится значение Long . Это означает, что в предыдущих примерах числовые литералы 0x9A и 0b10011010 интерпретируются как 32-разрядные целые числа со знаком со значением 156, которое превышает SByte.MaxValue. Чтобы успешно скомпилировать такой код, который присваивает целое число SByte без десятичного разряда , можно выполнить одно из следующих действий:

  • Отключите проверки целочисленных границ путем компиляции с помощью параметра компилятора /removeintchecks .
  • Используйте символ типа для явного определения литерального значения, которое необходимо присвоить SByte . В следующем примере отрицательное литеральное Short значение присваивается объекту SByte . Обратите внимание, что для отрицательных чисел должен быть задан бит высокого порядка в слове числового литерала. В нашем примере это бит 15 литерального Short значения.

Dim sByteValue1 As SByte = &HFF_9As Dim sByteValue2 As SByte = &B1111_1111_1001_1010s Console.WriteLine(sByteValue1) Console.WriteLine(sByteValue2) 

Советы по программированию

  • Соответствие ТРЕБОВАНИЯМ CLS. Тип SByte данных не является частью CLS , поэтому CLS-совместимый код не может использовать компонент, который его использует.
  • Расширение. Тип SByte данных расширяется до Short , Integer , Long , Decimal , Single и Double . Это означает, что вы можете выполнить преобразование SByte в любой из этих типов без возникновения System.OverflowException ошибок.
  • Символы типов. SByte не имеет символа литерального типа или символа типа идентификатора.
  • Тип Framework. В .NET Framework данный тип соответствует структуре System.SByte.

См. также раздел

  • System.SByte
  • Типы данных
  • Type Conversion Functions
  • Сводка по преобразованию
  • Тип данных Short
  • Целочисленный тип данных
  • Тип данных Long
  • Эффективное использование типов данных

Совместная работа с нами на GitHub

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

Sbyte c что это

Все, что необходимо начинающему и опытному программисту

Типы данных.

В этом разделе мы поговорим о типах данных языка C#. Не скроем, что вы найдете здесь массу сюрпризов. Начнем с того, что все встроенные типы данных являются синонимами для соответствующих структур (в некоторых случаях классов), определенных в пространстве имен System. Это означает, что каждая объявленная вами переменная является объектом соответствующей структуры или класса (подробнее о структурах и классах читайте в следующих уроках). Например, каждый числовой тип данных имеет поля MinValue и MaxValue, хранящие соответственно минимальное и максимальное возможные значения для данного типа (см. практические примеры в этом уроке).

Представляем вашему вниманию таблицу, содержащую встроенные типы данных языка C# и соответствующие им структуры или классы пространства имен System.

C# тип .NET Framework тип Количество бит Суффикс, используемый в литералах Описание
bool System.Boolean 8 Логический тип, может принимать только два значения: true и false
byte System.Byte 8 Беззнаковый байт
sbyte System.SByte 8 Знаковый байт
char System.Char 16 Символ Unicode
decimal System.Decimal 128 m, M Десятичное число с фиксированной точностью
double System.Double 64 d, D Число с плавающей запятой
float System.Single 32 f, F Число с плавающей запятой
int System.Int32 32 Целое знаковое число
uint System.UInt32 32 u, U Целое беззнаковое число
long System.Int64 64 l, L Целое знаковое число
ulong System.UInt64 64 ul, uL, UL, Ul, lu, lU, LU, Lu Целое беззнаковое число
object System.Object Базовый тип данных, все остальные типы являются производными от него
short System.Int16 16 Целое знаковое число
ushort System.UInt16 16 Целое беззнаковое число
string System.String Строка символов Unicode

Из перечисленных имен System.Object и System.String являются классами, остальные структурами. Поэтому объекты типа string и object называются ссылочными типами, а остальные структурными. Ссылочные и структурные типы будут подробно рассмотрены в следующих уроках. В этом уроке мы всего лишь отметим основную разницу между ними.

Объект ссылочного типа создается в куче, а объект структурного типа создается в стеке. В том случае, если структурный тип присваивается объекту типа object, в куче создается временный объект, имитирующий поведение ссылочного. В этот временный объект копируются данные из структурного, а сам объект помечается специальной отметкой, чтобы система знала к какому типу он относится. Этот процесс называется упаковкой (boxing), обратный процесс называется распаковкой (unboxing).

Кстати, в языке C# отсутствует понятие указателя .

Приведение типов.

Неявно приводить можно:

Тип данных неявно приводится к
sbyte short, int, long, float, double, decimal
byte short, ushort, int, uint, long, ulong, float, double, decimal
short int, long, float, double, decimal
ushort int, uint, long, ulong, float, double, decimal
int long, float, double, decimal
uint long, ulong, float, double, decimal
long float, double, decimal
ulong float, double, decimal
char ushort, int, uint, long, ulong, float, double, decimal
float double

****** константы типа int можно присваивать переменным типов sbyte, byte, short, ushort, uint, или ulong, в случае, если они могут их «съесть». ******

Явно приводить нужно:

Тип данных явно приводится к
sbyte byte, ushort, uint, ulong, char
byte sbyte, char
short sbyte, byte, ushort, uint, ulong, char
ushort sbyte, byte, short, char
int sbyte, byte, short, ushort, uint, ulong, char
uint sbyte, byte, short, ushort, int, char
long sbyte, byte, short, ushort, int, uint, ulong, char
ulong sbyte, byte, short, ushort, int, uint, long, or char
char sbyte, byte, short
float sbyte, byte, short, ushort, int, uint, long, ulong, char, decimal
double sbyte, byte, short, ushort, int, uint, long, ulong, char, float, decimal
decimal sbyte, byte, short, ushort, int, uint, long, ulong, char, float, or double
За более полной информацией можно, как всегда, обратиться в MSDN. 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru

Sbyte c что это

Я определил несколько целочисленных переменных с ключевым словом int и использовал заключенные в кавычки строки, так что вы уже знакомы с двумя поддерживаемыми С# типами данных. На самом деле в С# поддерживаются восемь целочисленных типов данных:

Целочисленные типы данных C#

Количество бит Со знаком Без знака
8 sbyte byte
16 short ushort
32 int uint
64 long ulong

Кроме того, в С# поддерживаются два типа данных с плавающей точкой, float и double , соответствующие стандарту ANSI/IEEE 754-1985 — IEEE Standard for Binary Floating-Point Arithmetic (стандарт IEEE двоичной арифметики с плавающей точкой). Количество бит, используемое порядком и мантиссой типов float и double , таково:

Количество бит, используемое типами данных С# с плавающей точкой

Тип С# Порядок Мантисса Всего бит
float 8 24 32
double 11 53 64

Кроме того, в С# поддерживается тип decimal , использующий 128 бит для хранения данных. В состав числа этого типа входят 96-битная мантисса и десятичный масштабирующий множитель от 0 до 28. Тип данных decimal обеспечивает точность около 28 десятичных знаков. Он удобен для хранения и выполнения вычислений над числами с фиксированным количеством десятичных знаков, например, денежных сумм или процентных ставок. Я подробней рассмотрю тип decimal , работу с числами и математические вычисления в С# в приложении Б.

Если в тексте программы на С# попадется число 3.14, компилятор будет считать, что оно имеет тип double . Чтобы указать, что его тип float или decimal , используйте для типа float суффикс f а для decimal — суффикс m .

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

//------------------------------------------- // MinAndMax.cs (C) 2001 by Charles Petzold //------------------------------------------- using System; class MinAndMax < public static void Main() < Console.WriteLine("sbyte: to ", sbyte.MinValue, sbyte.MaxValue); Console.WriteLine("byte: to ", byte.MinValue, byte.MaxValue); Console.WriteLine("short: to ", short.MinValue, short.MaxValue); Console.WriteLine("ushort: to ", ushort.MinValue, ushort.MaxValue); Console.WriteLine("int: to ", int.MinValue, int.MaxValue); Console.WriteLine("uint: to ", uint.MinValue, uint.MaxValue); Console.WriteLine("long: to ", long.MinValue, long.MaxValue); Console.WriteLine("ulong: to ", ulong.MinValue, ulong.MaxValue); Console.WriteLine("float: to ", float.MinValue, float.MaxValue); Console.WriteLine("double: to ", double.MinValue, double.MaxValue); Console.WriteLine("decimal: to ", decimal.MinValue, decimal.MaxValue); > >

Как вы заметили, я поставил после каждого типа данных точку и слова MinValue или MaxValue . Эти два идентификатора являются полями структуры. К концу главы все, что делает эта программа, станет для вас понятным, а пока что просто взглянем на результаты ее выполнения:

sbyte: -128 to 127 byte: 0 to 255 short: -32768 to 32767 ushort: 0 to 65535 int: -2147483648 to 2147483647 uint: 0 to 4294967295 long: -9223372036854775808 to 9223372036854775807 ulong: 0 to 18446744073709551615 float: -3.402823E+38 to 3.402823E+38 double: -1.79769313486232E+308 to 1.79769313486232Е+308 decimal: -79228162514264337593543950335 to 79228162514264337593543950335

В С# поддерживается также тип bool , который может принимать только одно из двух значений: true или false , являющихся ключевыми словами С#. Результаты операций сравнения ( == , != , < , >, = ) — значения типа bool . Можно также описать данные типа bool явно. Приведение типа bool к целочисленным типам допускается ( true преобразуется в 1, а false — в 0), но оно должно быть явно указано в коде.

Тип данных char служит для хранения одного символа, a string — для хранения строк из нескольких символов. Тип данных char отличается от целочисленных типов, и его не следует путать с типами sbyte или byte . К тому же переменные типа char занимают 16 бит (но это не значит, что его можно путать с short или ushort ).

Тип char — 16-битный, так как С# использует кодировку Unicode 1 вместо ASCII. Вместо 7-битного представления символов в базовом варианте ASCII и 8 бит на символ в расширенных наборах символов, ставших общепринятыми на компьютерах, в Unicode для кодировки одного символа используется целых 16 бит. Это позволяет отобразить все буквы, условные обозначения и другие символы всех письменностей мира, которые могут использоваться при работе с компьютером. Unicode является расширением кодировки ASCII. Его первые 128 символов совпадают с символами ASCII.

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

Переменную можно определить и сразу же инициализировать:

string str = "Hello, World!";

Как только переменной типа string присвоено значение, ее отдельные символы нельзя изменить, однако можно присвоить ей новое значение. Строки не заканчиваются нулем, а количество символов в переменной типа string можно определить так:

str.Length

Length является свойством типа данных string ; концепцию свойств я опишу дальше в этой главе. В приложении В содержится подробная информация по работе со строками в С#.

Чтобы описать переменную-массив, поставьте после типа данных пустые квадратные скобки:

float[] arr;

Тип данных переменной arr — массив чисел с плавающей точкой, но на самом деле arr — это указатель. В языке С# массив является ссылочным типом ( reference type ). Это относится и к строке. Другие типы, о которых я рассказывал ранее, являются размерными ( value types ).

Значение переменной arr при первоначальном определении — null . Для выделения памяти массиву нужно воспользоваться оператором new и указать количество элементов в массиве:

arr = new float[3];

Можно также применить сочетание двух приведенных выше операторов:

float[] arr = new float[3];

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

float[] arr = new float[3] < 3.14f, 2.17f, 100 >;

Количество инициализирующих значений должно совпадать с объявленным размером массива. При инициализации массива можно опустить размер:

float[] arr = new float[] < 3.14f, 2.17f, 100 >;

и даже — оператор new .

float[] arr = < 3.14f, 2.17f, 100 >;

В дальнейшем в программе можно присвоить переменной arr массив типа float другого размера:

arr = new float[5];

При этом выделяется память для хранения пяти значений типа float , каждое из этих значений первоначально равно 0.

Вы можете спросить: «А что случилось с первым блоком памяти, выделенным для трех значений типа float ?» В С# нет оператора delete . Поскольку на исходный блок памяти больше не ссылается ни одна из переменных программы, он становится объектом сборки мусора ( garbage collection ). В какой-то момент Common Language Runtime освободит память, изначально выделенную массиву.

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

arr.Length;

Кроме того, С# позволяет создавать многомерные и невыровненные (jagged) массивы, являющиеся массивами массивов.

Если не нужно взаимодействие с кодом, написанным на другом языке, указатели в программах на С# требуются редко. По умолчанию параметры передаются методам по значению. Это означает, что метод может как угодно изменять параметр, а значение параметра в вызывающем методе не изменится. Чтобы изменить такое поведение параметров, можно использовать ключевые слова ref (reference — ссылка) или out , Например, определить метод, изменяющий передаваемую в качестве параметра переменную, можно так:

void AddFive(ref int i)

А метод, присваивающий переменной значение, выглядит так:

void SetToFive(out int i)

В первом примере переменной i необходимо присвоить значение перед вызовом AddFive , тогда метод AddFive сможет изменить ее значение. Во втором — i при вызове метода может не иметь никакого значения.

Важную роль в С# и .NET Framework играют перечисления. Многие константы .NET Framework определены как перечисления. Приведем пример из пространства имен SystemIO :

public enum FileAccess

Перечисления всегда являются целочисленными типами данных, по умолчанию они имеют тип int . Если не указать значение явно (в данном примере для Read оно указано), первому элементу перечисления присваивается нулевое значение. Следующим элементам присваиваются значения в порядке возрастания.

FileAccess можно использовать при работе с несколькими классами файлового ввода-вывода. (Файловый ввод-вывод подробно рассмотрен в приложении А). Необходимо указывать имя перечисления, затем, через точку имя элемента:

file.Open(FileMode.CreateNew, FileAccess.ReadWrite)

FileMode — это еще одно перечисление класса SystemIO . Если эти два перечисления в методе Open поменять местами, компилятор сообщит об ошибке. Перечисления помогают программисту избегать ошибок, связанных с константами.

1 Дополнительную информацию можно получить на Web-странице http://www.unicode.org или в The Unicode Consortium, The Unicode Standard Version 3.0 (Reading, Mass.: Addison-Wesley, 2000).

Sbyte c что это

Ранее мы рассматривали следующие элементарные типы данных: int, byte, double, string, object и др. Также есть сложные типы: структуры, перечисления, классы. Все эти типы данных можно разделить на типы значений, еще называемые значимыми типами, (value types) и ссылочные типы (reference types). Важно понимать между ними различия.

  • Целочисленные типы ( byte, sbyte, short, ushort, int, uint, long, ulong )
  • Типы с плавающей запятой ( float, double )
  • Тип decimal
  • Тип bool
  • Тип char
  • Перечисления enum
  • Структуры ( struct )
  • Тип object
  • Тип string
  • Классы ( class )
  • Интерфейсы ( interface )
  • Делегаты ( delegate )

В чем же между ними различия? Для этого надо понять организацию памяти в .NET. Здесь память делится на два типа: стек и куча (heap). Параметры и переменные метода, которые представляют типы значений, размещают свое значение в стеке. Стек представляет собой структуру данных, которая растет снизу вверх: каждый новый добавляемый элемент помещается поверх предыдущего. Время жизни переменных таких типов ограничено их контекстом. Физически стек — это некоторая область памяти в адресном пространстве.

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

class Program < static void Main(string[] args) < Calculate(5); >static void Calculate(int t) < int x = 6; int y = 7; int z = y + t; >>

При запуске такой программы в стеке будут определяться два фрейма — для метода Main (так как он вызывается при запуске программы) и для метода Calculate:

Структура стека в языке программирования C#

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

Причем если параметр или переменная метода представляет тип значений, то в стеке будет храниться непосредсвенное значение этого параметра или переменной. Например, в данном случае переменные и параметр метода Calculate представляют значимый тип — тип int, поэтому в стеке будут храниться их числовые значения.

Ссылочные типы хранятся в куче или хипе, которую можно представить как неупорядоченный набор разнородных объектов. Физически это остальная часть памяти, которая доступна процессу.

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

Так, в частности, если мы изменим метод Calculate следующим образом:

static void Calculate(int t)

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

Ссылочные типы в куче в языке программирования C#

Составные типы

Теперь рассмотим ситуацию, когда тип значений и ссылочный тип представляют составные типы — структуру и класс:

State state1 = new State(); // State — структура, ее данные размещены в стеке Country country1 = new Country(); // Country — класс, в стек помещается ссылка на адрес в хипе // а в хипе располагаются все данные объекта country1 struct State < public int x; public int y; >class Country

Здесь в методе Main в стеке выделяется память для объекта state1. Далее в стеке создается ссылка для объекта country1 ( Country country1 ), а с помощью вызова конструктора с ключевым словом new выделяется место в хипе ( new Country() ). Ссылка в стеке для объекта country1 будет представлять адрес на место в хипе, по которому размещен данный объект..

Ссылычные типы и типы значений в C#

Таким образом, в стеке окажутся все поля структуры state1 и ссылка на объект country1 в хипе.

Но, допустим, в структуре State также определена переменная ссылочного типа Country. Где она будет хранить свое значение, если она определена в типе значений?

State state1 = new State(); Country country1 = new Country(); struct State < public int x; public int y; public Country country; public State() < x = 0; y = 0; country = new Country(); >> class Country

Значение переменной state1.country также будет храниться в куче, так как эта переменная представляет ссылочный тип:

Стек и куча в языке программирования C#

Копирование значений

Тип данных надо учитывать при копировании значений. При присвоении данных объекту значимого типа он получает копию данных. При присвоении данных объекту ссылочного типа он получает не копию объекта, а ссылку на этот объект в хипе. Например:

State state1 = new State(); // Структура State State state2 = new State(); state2.x = 1; state2.y = 2; state1 = state2; state2.x = 5; // state1.x=1 по-прежнему Console.WriteLine(state1.x); // 1 Console.WriteLine(state2.x); // 5 Country country1 = new Country(); // Класс Country Country country2 = new Country(); country2.x = 1; country2.y = 4; country1 = country2; country2.x = 7; // теперь и country1.x = 7, так как обе ссылки и country1 и country2 // указывают на один объект в хипе Console.WriteLine(country1.x); // 7 Console.WriteLine(country2.x); // 7

Так как state1 — структура, то при присвоении state1 = state2 она получает копию структуры state2. А объект класса country1 при присвоении country1 = country2; получает ссылку на тот же объект, на который указывает country2. Поэтому с изменением country2, так же будет меняться и country1.

Ссылочные типы внутри типов значений

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

State state1 = new State(); State state2 = new State(); state2.country.x = 5; state1 = state2; state2.country.x = 8; // теперь и state1.country.x=8, так как state1.country и state2.country // указывают на один объект в хипе Console.WriteLine(state1.country.x); // 8 Console.WriteLine(state2.country.x); // 8 struct State < public int x; public int y; public Country country; public State() < x = 0; y = 0; country = new Country(); // выделение памяти для объекта Country >> class Country

Переменные ссылочных типов в структурах также сохраняют в стеке ссылку на объект в хипе. И при присвоении двух структур state1 = state2; структура state1 также получит ссылку на объект country в хипе. Поэтому изменение state2.country повлечет за собой также изменение state1.country.

Объекты классов как параметры методов

Организацию объектов в памяти следует учитывать при передаче параметров по значению и по ссылке. Если параметры методов представляют объекты классов, то использование параметров имеет некоторые особенности. Например, создадим метод, который в качестве параметра принимает объект Person:

Person p = new Person < name = "Tom", age = 23 >; ChangePerson(p); Console.WriteLine(p.name); // Alice Console.WriteLine(p.age); // 23 void ChangePerson(Person person) < // сработает person.name = "Alice"; // сработает только в рамках данного метода person = new Person < name = "Bill", age = 45 >; Console.WriteLine(person.name); // Bill > class Person

При передаче объекта класса по значению в метод передается копия ссылки на объект. Эта копия указывает на тот же объект, что и исходная ссылка, потому мы можем изменить отдельные поля и свойства объекта, но не можем изменить сам объект. Поэтому в примере выше сработает только строка person.name = «Alice» .

А другая строка person = new Person < name = "Bill", age = 45 >создаст новый объект в памяти, и person теперь будет указывать на новый объект в памяти. Даже если после этого мы его изменим, то это никак не повлияет на ссылку p в методе Main, поскольку ссылка p все еще указывает на старый объект в памяти.

Но при передаче параметра по ссылке (с помощью ключевого слова ref ) в метод в качестве аргумента передается сама ссылка на объект в памяти. Поэтому можно изменить как поля и свойства объекта, так и сам объект:

Person p = new Person < name = "Tom", age = 23 >; ChangePerson(ref p); Console.WriteLine(p.name); // Bill Console.WriteLine(p.age); // 45 void ChangePerson(ref Person person) < // сработает person.name = "Alice"; // сработает person = new Person < name = "Bill", age = 45 >; > class Person

Операция new создаст новый объект в памяти, и теперь ссылка person (она же ссылка p из метода Main) будет указывать уже на новый объект в памяти.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *