Язык программирования предполагает наличие правил построения корректных предложений. В свою очередь, предложения строятся из выражений. Основной характеристикой выражения является значение этого выражения. Можно утверждать, что выполнение программы состоит из вычисления значений выражений, которые образуют предложения программы. Синтаксис языка не ограничивает сложности выражения. Выражение может состоять из очень большого количества более простых (элементарных) выражений.
Значение выражения характеризуется типом (типом выражения). Выражение сложной структуры может сочетать элементарные выражения различных типов. При вычислении значений таких выражений требуются дополнительные усилия по преобразованию значений одного типа в значения другого типа. Большая часть этой работы производится автоматически, в ряде случаев от программиста требуются дополнительные усилия по разработке алгоритмов преобразования.
При разработке кода любой сложности знание правил кодирования, вычисления и преобразования значений различных типов является условием создания правильно выполняемой программы.
В разделах этой главы обсуждаются система типов и основные характеристики категорий типов, литералы которые являются основным средством кодирования значений в выражениях, проблемы преобразования значений в выражениях, операторы объявления и связанная с ними проблема области действия имени.
Система типов включает несколько категорий типов:
Схема типов представлена ниже.
Простые (
Среди простых типов различаются:

Некоторые характеристики простых (элементарных) типов отражены в следующей таблице. Используемые в .NET языки программирования основываются на общей системе типов. Между именами простых типов в C# и именами типов, объявленных в Framework Class Library, существует взаимно однозначное соответствие. Смысл
Sbyte |
System.SByte |
Целый. 8-разрядное со знаком. Диапазон значений: –128 ... 127 |
Byte |
System.Byte |
Целый. 8-разрядное без знака. Диапазон значений: 0 ... 255 |
Short |
System.Int16 |
Целый. 16-разрядное со знаком. Диапазон значений: –32768 ... 32767 |
Ushort |
System.UInt16 |
Целый. 16-разрядное без знака. Диапазон значений: 0 ... 65535 |
Int |
System.Int32 |
|
uint |
System.UInt32 |
|
long |
System.Int64 |
|
ulong |
System.UInt64 |
|
char |
System.Char |
16 (!) разрядный символ UNICODE |
float |
System.Single |
Плавающий. 32 разряда. Стандарт IEEE |
double |
System.Double |
Плавающий. 64 разряда. Стандарт IEEE |
decimal |
System.Decimal |
128-разрядное значение повышенной точности с фиксированной точкой |
bool |
System.Boolean |
Значение true или false |
Ниже представлены основные отличия ссылочных типов и типов-значений.
| Типы-значения | Типы-ссылки | |
|---|---|---|
| Объект представлен | непосредственно значением | ссылкой в стеке или куче |
| Объект располагается | в стеке или куче | в куче |
| Значение по умолчанию | 0, false, ' \0 ', null |
ссылка имеет значение null |
| При выполнении операции присваивания копируется | значение | ссылка |
В C# объявление любой структуры и класса основывается на объявлении предопределенного класса object (наследует класс object ). Следствием этого является возможность вызова от имени объектов — представителей любой структуры или класса, унаследованных от класса object методов. В частности, метода ToString. Этот метод возвращает строковое (значение типа string ) представление объекта.
Все типы (типы-значения и типы-ссылки), за исключением простых типов-значений и пары предопределенных ссылочных типов ( string и object ), должны определяться (если уже не были ранее специально определены) программистами в рамках объявлений. Подлежащие объявлению типы называются производными типами.
В разных CLS-языках типам, удовлетворяющим CLS-спецификации, будут соответствовать одни и те же
Система встроенных типов C# основывается на системе типов .NET Framework Class Library. При создании IL-
Параметризованные типы занимают особое место в системе типов и обсуждаются позже.
Итак, к ссылочным типам относятся:
Для каждой категории ссылочных типов существуют собственные правила объявления. Объявления классов вводятся ключевым словом class. Правила объявления классов (как и правила объявления других ссылочных типов, а также типов-значений, объявляемых с помощью ключевого слова struct ) позволяют объявлять неограниченное множество разнообразных ссылочных типов и структур.
Среди множества классов выделяют предопределенные ссылочные типы object и string, которым соответствуют FCL-типы System.Object и System.String. Свойства, функциональность и особенности применения этих типов рассматриваются ниже.
В программах на языках высокого уровня (C# в том числе) литералами называют последовательности входящих в алфавит языка программирования символов, обеспечивающих явное представление значений, которые используются для обозначения начальных значений в объявлении членов классов, переменных и констант в методах класса.
Различаются литералы арифметические (разных типов), логические, символьные (включая
Арифметические литералы кодируют значения различных (арифметических) типов. Тип арифметического литерала определяется следующими интуитивно понятными внешними признаками:
1 ', ..., ' 9 ', ' 0 '. Значение плавающего типа также предполагает стандартный вид (точка-разделитель между целой и дробной частью, либо научная или экспоненциальная нотация – 1.2500E+052). Шестнадцатеричное представление целочисленного значения кодируется шестнадцатеричным литералом, состоящим из символов ' 0 ', ..., ' 9 ', а также ' a ', ..., ' f ', либо ' A ', ..., ' F ' с префиксом ' 0x ';l, L соответствуют типу long; ul, UL – unsigned long; f, F – float; d, D – decimal. Значения типа double кодируются без префикса.К логическим литералам относятся следующие последовательности символов: true и false. Больше логических литералов в C# нет.
Это заключенные в одинарные кавычки вводимые с клавиатуры одиночные символы: ' ,', (char)7541 – какой символ будет здесь – не ясно.
Следующие заключенные в одинарные кавычки последовательности символов являются
\a |
Предупреждение (звонок) |
\b |
Возврат на одну позицию |
\f |
Переход на новую страницу |
\n |
Переход на новую строку |
\r |
Возврат каретки |
\t |
Горизонтальная табуляция |
\v |
Вертикальная табуляция |
\0 |
Ноль |
\' |
Одинарная кавычка |
\" |
Двойная кавычка |
\\ |
Обратная косая черта |
Это последовательность символов и символьных Escape-последовательностей, заключенных в двойные кавычки.
Verbatim string – строковый литерал, интерпретируемый компилятором так, как он записан.
Verbatim string представляется при помощи символа @, который располагается непосредственно перед строковым литералом, заключенным в парные двойные кавычки. Представление двойных кавычек в Verbatim string обеспечивается их дублированием. Пара литералов (второй – Verbatim string )
..."c:\\My Documents\\sample.txt"... ...@"c:\My Documents\sample.txt"...
имеют одно и то же значение:
c:\My Documents\sample.txt
Представление двойных кавычек внутри Verbatim string достигается за счет их дублирования:
...@"""Focus"""
имеет значение
"Focus"
Строковые литералы являются литералами типа string.
Объявление – это предложение языка C#, которое используется непосредственно в теле класса для объявления членов класса (в этом случае объявлению может предшествовать спецификатор доступа) или для объявления переменных в конструкторах и методах класса.
Выполнение оператора объявления переменной типа-значения в методе класса приводит к созданию в памяти объекта соответствующего типа, возможно, проинициализированного определенным значением. Это значение может быть задано в виде литерала соответствующего типа или в виде выражения (синтаксис выражений рассматривается далее).
Предложение объявления предполагает (возможное) наличие различных спецификаторов, указание имени типа, имени объекта и (возможно) выражения инициализации. При этом имя типа может быть задано как Действительное Имя Типа (Имя FCL-типа) или как псевдоним типа (имя типа, как оно объявляется в C#). Соответствующее выражение инициализации может быть представлено литералом или выражением более сложной структуры.
Эквивалентные формы записи операторов определения переменных
int a; System.Int32 a;
Эквивалентные формы записи операторов определения и инициализации переменных типа значения:
int a = 0; int a = new int(); System.Int32 a = 0; System.Int32 a = new System.Int32();
Здесь следует учитывать важное обстоятельство: CLR не допускает использования в выражениях неинициализированных локальных переменных. В C# к таковым относятся переменные, объявленные в теле метода. Так что при разработке алгоритма следует обращать на это особое внимание.
int a; // Объявление a. int b; // Объявление b. b = 10; // Инициализация b. a=b+b; // Инициализация a.
Объявляются с дополнительным спецификатором const. Требуют непосредственной инициализации. В данном примере инициализируется литералом 3.14.
const float Pi = 3.14;
Для каждого определенного в C# типа существует собственный набор операций, определенных на множестве значений этого типа.
Эти операции задают диапазон возможных преобразований, которые могут быть осуществлены над элементами множеств значений типа. Несмотря на специфику разных типов, в C# существует общее основание для классификации соответствующих множеств операций. Каждая операция является членом определенного подмножества операций и имеет собственное графическое представление.
Общие характеристики используемых в C# операций представлены ниже.
| Arithmetic | + – * / % |
| Логические (boolean и побитовые) | | ^ ! ~ || |
| Строковые (конкатенаторы) | + |
| Increment, |
++ –– |
| Сдвига | >> << |
| Сравнения | == != < > <= >= |
| Присвоения | = += –= *= /= %= = |= ^= <<= >>= |
| Member access | . |
| Индексации | [] |
| Cast (приведение типа) | () |
| Conditional (трехоперандная) | ?: |
| Delegate concatenation and removal | + – |
| Создания объекта | new() |
| Type information | is sizeof typeof |
| Overflow exception control (управление исключениями) | checked unchecked |
* –> [] |
На основе элементарных (
| 1 | () [] . (постфикс)++ (постфикс)–– new sizeof typeof unchecked |
| 2 | ! ~ (имя типа) +(унарный) –(унарный) ++(префикс) ––(префикс) |
| 3 | * / % |
| 4 | + – |
| 5 | << >> |
| 6 | < > <= => is |
| 7 | == != |
| 8 | |
| 9 | ^ |
| 10 | | |
| 11 | |
| 12 | || |
| 13 | ?: |
| 14 | = += –= *= /= %= = |= ^= <<= >>= |
Приведение типов – один из аспектов безопасности языка.
Используемые в программе типы характеризуются собственными диапазонами значений, которые определяются свойствами типов – в том числе и размером области памяти, предназначенной для кодирования значений соответствующего типа. При этом области значений различных типов пересекаются. Многие значения можно выразить более чем одним типом. Например, значение 4 можно представить как значение типа sbyte, byte, short, ushort, int, uint, long, ulong. При этом в программе все должно быть устроено таким образом, чтобы логика преобразования значений одного типа к другому типу была бы понятной, а результаты этих преобразований – предсказуемы. В одном выражении могут быть сгруппированы операнды различных типов. Однако возможность подобного "смешения" при определении значения выражения приводит к необходимости применения дополнительных усилий по приведению значений операндов к "общему типу".
Иногда приведение значения к другому типу происходит автоматически. Такие преобразования называются неявными.
Но в ряде случаев преобразование требует дополнительного внимания со стороны программиста, который должен явным образом указывать необходимость преобразования, используя выражения приведения типа или обращаясь к специальным методам преобразования, определенным в классе System.Convert, которые обеспечивают преобразование значения одного типа к значению другого (в том числе значения строкового типа к значениям базовых типов).
Преобразование типа создает значение нового типа, эквивалентное значению старого типа, однако при этом не обязательно сохраняется идентичность (или точные значения) двух объектов.
Различаются:
Расширяющее преобразование – значение одного типа преобразуется к значению другого типа, которое имеет такой же или больший размер. Например, значение, представленное в виде 32-разрядного целого числа со знаком, может быть преобразовано в 64-разрядное целое число со знаком. Расширяющее преобразование считается безопасным, поскольку исходная информация при таком преобразовании не искажается.
Byte |
UInt16, Int16, UInt32, Int32, UInt64, Int64, Single, Double, Decimal |
SByte |
Int16, Int32, Int64, Single, Double, Decimal |
Int16 |
Int32, Int64, Single, Double, Decimal |
UInt16 |
UInt32, Int32, UInt64, Int64, Single, Double, Decimal |
Char |
UInt16, UInt32, Int32, UInt64, Int64, Single, Double, Decimal |
Int32 |
Int64, Double, Decimal |
UInt32 |
Int64, Double, Decimal |
Int64 |
Decimal |
UInt64 |
Decimal |
Single |
Double |
Некоторые расширяющие преобразования типа могут привести к потере точности. Следующая таблица описывает варианты преобразований, которые иногда приводят к потере информации.
Int32 |
Single |
UInt32 |
Single |
Int64 |
Single, Double |
UInt64 |
Single, Double |
Decimal |
Single, Double |
Сужающее преобразование – значение одного типа преобразуется к значению другого типа, которое имеет меньший размер (из 64-разрядного в 32-разрядное). Такое преобразование потенциально опасно потерей значения.
Сужающие преобразования могут приводить к потере информации. Если тип, к которому осуществляется преобразование, не может правильно передать значение источника, то результат преобразования оказывается равен константе PositiveInfinity или NegativeInfinity.
При этом значение PositiveInfinity интерпретируется как результат деления положительного числа на ноль, а значение NegativeInfinity — как результат деления отрицательного числа на ноль.
Если сужающее преобразование обеспечивается методами класса System.Convert, то потеря информации сопровождается генерацией исключения (об исключениях позже).
Byte |
Sbyte |
SByte |
Byte, UInt16, UInt32, UInt64 |
Int16 |
Byte, SByte, UInt16 |
UInt16 |
Byte, SByte, Int16 |
Int32 |
Byte, SByte, Int16, UInt16, UInt32 |
UInt32 |
Byte, SByte, Int16, UInt16, Int32 |
Int64 |
Byte, SByte, Int16, UInt16, Int32, UInt32, UInt64 |
UInt64 |
Byte, SByte, Int16, UInt16, Int32, UInt32, Int64 |
Decimal |
Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64 |
Single |
Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64 |
Double |
Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64 |
Всеобщий базовый тип. Обязательная составляющая любого типа в .NET. Функциональные характеристики типа System.Object приводятся в таблице.
Конструктор
Object |
Создает и инициализирует объект типа Object |
Общедоступные (public) методы
Equals |
Обеспечивает сравнение объектов |
GetHashCode |
Обеспечивает реализацию алгоритма хэширования для значений объектов |
GetType |
Для любого объекта создает объект типа Type, содержащий информацию о структуре типа данного объекта |
ReferenceEquals |
Проверка эквивалентности ссылок. Статический |
ToString |
Возвращает объект типа String с описанием данного объекта |
Защищенные (protected) методы
| Имя | Описание |
|---|---|
Finalize |
Реализует процедуру уничтожения объекта. |
MemberwiseClone |
Создает копию текущего объекта. |
Особенности выполнения операций над целочисленными операндами и операндами с плавающей точкой связаны с особенностями выполнения арифметических операций и с ограниченной точностью переменных типа float и double.
Представление величин:
float – 7 значащих цифр double – 16 значащих цифр
1000000*1000000==1000000000000, но максимально допустимое положительное значение для типа System.Int32 составляет 2147483647. В результате переполнения получается неверный результат –727379968.
Ограниченная точность значений типа System.Single проявляется при присвоении значений переменной типа System.Double. Приводимый ниже простой программный код иллюстрирует некоторые особенности арифметики .NET:
using System;
class Class1
{
const double epsilon = 0.00001D;
static void Main(string[] args)
{
int valI = 1000000, resI;
resI = (valI*valI)/valI;
// –727379968/1000000 == –727
Console.WriteLine
("The result of action (1000000*1000000/1000000) is {0}", resI);
float valF00 = 0.2F, resF;
double valD00 = 0.2D, resD;
// Тест на количество значащих цифр для значений типа double и float.
resD = 12345678901234567890; Console.WriteLine(">>>>> {0:F10}",resD);
resF = (float)resD; Console.WriteLine(">>>>> {0:F10}",resF);
resD = (double)(valF00 + valF00); // 0.400000005960464
if (resD == 0.4D) Console.WriteLine("Yes! {0}",resD);
else Console.WriteLine("No! {0}",resD);
resF = valF00*5.0F;
resD = valD00*5.0D;
resF = (float)valD00*5.0F;
resD = valF00*5.0D; //1.0000000149011612
if (resD == 1.0D) Console.WriteLine("Yes! {0}",resD);
else Console.WriteLine("No! {0}",resD);
resF = valF00*5.0F;
resD = valF00*5.0F; //1.0000000149011612
if (resD.Equals(1.0D)) Console.WriteLine("Yes! {0}",resD);
else Console.WriteLine("No! {0}",resD);
if (Math.Abs(resD – 1.0D) < epsilon)
Console.WriteLine("Yes! {0:F7}, {1:F7}",resD – 1.0D, epsilon);
else
Console.WriteLine("No! {0:F7}, {1:F7}",resD – 1.0D, epsilon);
}
}
В результате выполнения программы выводится такой результат:
The result of action (1000000*1000000/1000000) is -727 >>>>> 12345678901234600000,0000000000 >>>>> 12345680000000000000,0000000000 No! 0,400000005960464 No! 1,00000001490116 No! 1,00000001490116 Yes! 0,0000000, 0,0000100
float присвоить величину x из интервала –1.5E–45 < x < 1.5E–45 (x != 0), результатом операции окажется положительный ( x > 0 ) или отрицательный ( x < 0 ) нуль ( +0, –0 ).double присвоить величину x из интервала –5E–324 < x < 5E–324 (x != 0), результатом операции окажется положительный ( x > 0 ) или отрицательный ( x < 0 ) нуль ( +0, –0 ).float присвоить величину x, которая –3.4E+38 < x или x > 3.4E+38, результатом операции окажется положительная ( x > 0 ) или отрицательная ( x < 0 ) бесконечность ( +Infinity , –Infinity ).double присвоить величину x, для которой –1.7E+308 > x или x < 1.7E+308, результатом операции окажется положительная ( x > 0 ) или отрицательная ( x < 0 ) бесконечность ( +Infinity , –Infinity ).0.0/0.0 ) дает NaN (Not a Number).Причиной некорректных результатов выполнения арифметических операций является особенность представления значений арифметических типов.
Арифметические типы имеют ограниченные размеры. Поэтому любая арифметическая операция может привести к переполнению. По умолчанию в C# переполнение, возникающее при выполнении операций, никак не контролируется. Возможный неверный результат вычисления остается всего лишь результатом выполнения операции, и никого не касается, КАК эта операция выполнялась.
Механизм контроля за переполнением, возникающим при выполнении арифметических операций, обеспечивается ключевыми словами checked (включить контроль за переполнением) и unchecked (отключить контроль за переполнением), которые используются в составе выражений.
:::::
short x = 32767;
short y = 32767;
short z = 0;
try
{
z = checked(x + unchecked(x+y));
}
catch (System.OverflowException e)
{
Console.Writeline("Переполнение при выполнении сложения");
}
return z;
:::::
При этом контролируемое выражение может быть произвольной формы и сложности и может содержать другие вхождения как контролируемых, так и неконтролируемых выражений;
:::::
short x = 32767;
short y = 32767;
short z = 0, w = 0;
try
{
unchecked
{
w = x+y;
}
checked
{
z = x+w;
}
}
catch (System.OverflowException e)
{
Console.Writeline("Переполнение при выполнении сложения");
}
return z;
:::::
Естественно, контролируемые блоки при этом также могут быть произвольной сложности.
Константное выражение – это либо элементарное константное выражение, к которым относятся:
Отличительные черты константного выражения:
Перечисление объявляется с помощью ключевого слова enum, идентифицируется по имени и представляет собой непустой список неизменяемых именованных значений интегрального типа. Первое значение в перечислении по умолчанию инициализируется нулем. Каждое последующее значение отличается от предыдущего по крайней мере на единицу, если объявление значения не содержит явного дополнительного присвоения нового значения. Пример объявления перечисления приводится ниже:
enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };
Обращение к элементу перечисления осуществляется посредством сложного выражения, состоящего из имени класса перечисления, операции доступа к элементу перечисления ' .', имени элемента перечисления:
int xVal = (int)Colors.Red; //Переменная xVal инициализируется значением перечисления.
Перечисление является классом, а это означает, что в распоряжении программиста оказываются методы сравнения значений перечисления, методы преобразования значений перечисления в строковое представление, методы перевода строкового представления значения в перечисление, а также (судя по документации) средства для создания объектов —представителей класса перечисления.
Далее приводится список членов класса перечисления.
CompareTo |
Сравнивает этот экземпляр с заданным объектом и возвращает сведения об их относительных значениях |
Equals |
Переопределен. Возвращает значение, показывающее, равен ли данный экземпляр заданному объекту |
Format |
Статический. Преобразует указанное значение заданного перечисляемого типа в эквивалентное строчное представление в соответствии с заданным форматом |
GetHashCode |
Переопределен. Возвращает хэш-код для этого экземпляра |
GetName |
Статический. Выводит имя константы в указанном перечислении, имеющем заданное значение |
GetNames |
Статический. Выводит массив имен констант в указанном перечислении |
GetType (унаследовано от Object ) |
Возвращает Type текущего экземпляра |
GetTypeCodeType |
Возвращает базовый тип TypeCode для этого экземпляра |
GetUnderlying |
Статический. Возвращает базовый тип указанного перечисления |
GetValues |
Статический. Выводит массив значений констант в указанном перечислении |
IsDefined |
Статический. Возвращает признак наличия константы с указанным значением в заданном перечислении |
Parse |
Статический. Перегружен. Преобразует строковое представление имени или числового значения одной или нескольких перечисляемых констант в эквивалентный перечисляемый объект |
ToObject |
Статический. Перегружен. Возвращает экземпляр указанного типа перечисления, равный заданному значению |
ToString |
Перегружен. Переопределен. Преобразует значение этого экземпляра в эквивалентное ему строковое представление |
Защищенные конструкторы
| Enum – конструктор |
Защищенные методы
Finalize (унаследовано от Object ) |
Переопределен. Позволяет объекту Object попытаться освободить ресурсы и выполнить другие завершающие операции, перед тем как объект Object будет уничтожен в процессе сборки мусора. В языках C# и C++ для функций финализации используется синтаксис деструктора |
MemberwiseClone (унаследовано от Object) |
Создает неполную копию текущего Object |
Любая используемая в программе сущность вводится объявлением.
Объявлению подлежат:
Объявляемой сущности присваивается имя. Обращение к ранее объявленным сущностям в программе обеспечивается различными вариантами имен. Имена в программе повсюду, и главная проблема заключается в том, чтобы не допустить неоднозначности при обращении из разных мест программы к классам, членам классов, перечислениям, переменным и константам.
Конфликта имен (проблемы с обращением к одноименным объектам) позволяет избежать принятая в языке дисциплина именования. В каждом языке программирования она своя.
Избежать конфликта имен в C# позволяет такая синтаксическая конструкция, как блок операторов. Блок – это множество предложений (возможно пустое), заключенное в фигурные скобки.
Различается несколько категорий блоков:
Переменные можно объявлять в любом месте блока. Точка объявления переменной в буквальном смысле соответствует месту ее создания. Обращение к объявляемой сущности (переменной или константе) "выше" точки ее объявления лишено смысла.
Новый блок – новая область видимости. Объекты, объявляемые во внутренних блоках, не видны во внешних блоках. Объекты, объявленные в методе и во внешних блоках, видны и во внутренних блоках. Одноименные объекты во вложенных областях конфликтуют.
Объекты, объявляемые в блоках одного уровня вложенности в методе, не видны друг для друга. Конфликта имен не происходит.
В теле класса не допускается объявления одноименных данных-членов. Нарушение этого правила приводит к неоднозначности.
В теле класса не допускается объявления одноименных функций — членов (методов класса) с пустыми списками параметров. Также не допускаются объявления одноименных функций — членов (методов класса) со списками параметров, у которых совпадают типы параметров.
В списках параметров имена параметров не важны. Важно, что выражение вызова метода в этом случае будет неоднозначным.
Имена данных — членов класса не конфликтуют с одноименными переменными, объявляемыми в теле методов, поскольку в теле метода обращение к членам класса обеспечивается выражениями с операцией доступа, и никакого конфликта в принципе быть не может.
Ниже приводится простой программный код, отражающий особенности принятой в C# концепции областей видимости.
using System;
class Class1
{
static int s;
static void Main(string[] args)
{
{int s;}
{int s;}
{
Class1.s = 100; // Классифицированное имя!
int s;
{
//int s;
}
}
System.Int32 z = new int();
char a = (char)41;
char b = 'X';
Console.WriteLine("{0} {1}",a,b);
}
//void QQQ(int q0)
//{
//Class1.s = 10;
//int s;
//}
//void QQQ(int q1)
//{
//Class1.s = 10;
//int s;
//}
int QQQ(int q2)
{
Class1.s = 10;
int s;
return 0;
}
int QQQ(int q2, int q3)
{
//s = 100;
Class1.s = 10;
int s;
return 0;
}
}
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.