В С# есть пять операторов, изменяющих естественный порядок выполнения вычислений:
- оператор безусловного перехода goto;
- оператор выхода из цикла break;
- оператор перехода к следующей итерации цикла continue;
- оператор возврата из функции return;
- оператор генерации исключения throw.
Эти операторы могут передать управление в пределах блока, в котором они использованы, и за его пределы. Передавать управление внутрь другого блока запрещается.
Оператор goto
Оператор безусловного перехода goto используется в одной из трех форм:
goto метка;goto case константное_выражение;goto default;В теле той же функции должна присутствовать ровно одна конструкция вида:
метка: оператор;Оператор goto метка передает управление на помеченный оператор. Метка — это обычный идентификатор, областью видимости которого является функция, в теле которой он задан. Метка должна находиться в той же области видимости, что и оператор перехода.
Вторая и третья формы оператора goto используются в теле оператора выбора switch. Оператор goto case константное_выражение передает управление на соответствующую константному выражению ветвь, а оператор goto default — на ветвь default.
Оператор break
Оператор break используется внутри операторов цикла или выбора для перехода в точку программы, находящуюся непосредственно за оператором, внутри которого находится оператор break.
Оператор continue
Оператор перехода к следующей итерации текущего цикла continue пропускает все операторы, оставшиеся до конца тела цикла, и передает управление на начало следующей итерации.
Оператор return
Оператор возврата из функции return завершает выполнение функции и передает управление в точку ее вызова. Синтаксис оператора:
return [ выражение ];Тип выражения должен иметь неявное преобразование к типу функции. Если тип возвращаемого функцией значения описан как void, выражение должно отсутствовать.
Перечисления
Перечисление объявляется с помощью ключевого слова 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 |
Массивы
Массив — это ограниченная совокупность однотипных величин. Элементы массива имеют одно и то же имя, а различаются по порядковому номеру (индексу).
Массив в С# относится к ссылочным типам данных, то есть располагается в динамической области памяти, поэтому создание массива начинается с выделения памяти под его элементы. Элементами массива могут быть величины как значимых, так и ссылочных типов (в том числе массивы). Массив значимых типов хранит значения, массив ссылочных типов — ссылки на элементы. Всем элементам при создании массива присваиваются значения по умолчанию: нули для значимых типов и null для ссылочных.
На рис. представлен массив, состоящий из пяти элементов любого значимого типа, например, int или double, а рис. иллюстрирует организацию массива из элементов ссылочного типа.
Рис. Простые переменные и массив из элементов значимого типа
Рис. Массив из элементов ссылочного типа
Операторы создания массива из 10 целых чисел и массива из 100 строк:
int[] w = new int[10];
string[] z = new string[100];
В первом операторе описан массив w типа int[]. Операция new выделяет память под 10 целых элементов, и они заполняются нулями.
Во втором операторе описан массив z типа string[].Операция new выделяет память под 100 ссылок на строки, и эти ссылки заполняются значением null. Память под сами строки, составляющие массив, не выделяется — это будет необходимо сделать перед заполнением массива.
Количество элементов в массиве (размерность) не является частью его типа, оно задается при выделении памяти и не может быть изменено впоследствии. Размерность может задаваться не только константой, но и выражением. Результат вычисления этого выражения должен быть неотрицательным, а его тип должен иметь неявное преобразование к int, uint, long или ulong.
Элементы массива нумеруются с нуля, поэтому максимальный номер элемента всегда на единицу меньше размерности. Для обращения к элементу массива после имени массива указывается номер элемента в квадратных скобках, например:
w[4] z[i]
С элементом массива можно делать все, что допустимо для переменных того же типа. Если при работе с массивом значение индекса выходит за границы массива, генерируется исключение IndexOutOfRangeException.
Массивы одного типа можно присваивать друг другу. При этом происходит присваивание ссылок, а не элементов, как и для любого другого объекта ссылочного типа, например:
int[] a = new int[10];
int[] b = a; // b и a указывают на один и тот же массив
Все массивы в C# имеют общий базовый класс Array, определенный в пространстве имен System. В нем есть несколько полезных методов, упрощающих работу с массивами, например, методы получения размерности, сортировки и поиска.
В C# существуют три разновидности массивов: одномерные, прямоугольные и ступенчатые (невыровненные).
Одномерные массивы
Одномерные массивы используются в программах чаще всего. Варианты описания одномерных массивов в C#:
тип[] имя;
тип[] имя = new тип [ размерность ];
тип[] имя = { список_инициализаторов };
тип[] имя = new тип [] { список_инициализаторов };
тип[] имя = new тип [ размерность ] { список_инициализаторов };
Примеры описаний (один пример на каждый вариант описания):
int[] a; // 1 элементов нет
int[] b = new int[4]; // 2 элементы равны 0
int[] c = { 61, 2, 5, -9 }; // 3 new подразумевается
int[] d = new int[] { 61, 2, 5, -9 };
// 4 размерность вычисляется
int[] e = new int[4] { 61, 2, 5, -9 };
// 5 избыточное описание
Здесь описано пять массивов. Отличие первого оператора от остальных состоит в том, что в нем фактически описана только ссылка на массив, а память под элементы массива не выделена.
В каждом из остальных массивов по четыре элемента целого типа. Как видно из операторов 3–5, массив при описании можно инициализировать. Если при этом не задана размерность (оператор 3), количество элементов вычисляется по количеству инициализирующих значений. Для полей объектов и локальных переменных можно опускать операцию new, она будет выполнена по умолчанию (оператор 3). Если присутствует и размерность, и список инициализаторов, размерность должна быть константой (оператор 5).
Прямоугольные массивы
Прямоугольный массив имеет более одного измерения. Чаще всего в программах используются двумерные массивы. Варианты описания двумерного массива:
тип[,] имя;
тип[,] имя = new тип [ разм_1, разм_2 ];
тип[,] имя = { список_инициализаторов };
тип[,] имя = new тип [,] { список_инициализаторов };
тип[,] имя = new тип [ разм_1, разм_2 ] { список_инициализаторов };
Примеры описаний (один пример на каждый вариант описания):
int[,] a; // 1 элементов нет
int[,] b = new int[2, 3]; // 2 элементы равны 0
int[,] c = {{1, 2, 3}, {4, 5, 6}};
// 3 new подразумевается
int[,] c = new int[,] {{1, 2, 3}, {4, 5, 6}};
// 4 размерность вычисляется
int[,] d = new int[2,3] {{1, 2, 3}, {4, 5, 6}};
// 5 избыточное описание
К элементу двумерного массива обращаются, указывая номера строки и столбца, на пересечении которых он расположен, например:
a[1, 4] b[i, j] b[j, i]
Ступенчатые массивы
В ступенчатых массивах количество элементов в разных строках может различаться. В памяти ступенчатый массив хранится иначе, чем прямоугольный: в виде нескольких внутренних массивов, каждый из которых имеет свой размер. Кроме того, выделяется отдельная область памяти для хранения ссылок на каждый из внутренних массивов (рис.).
Рис. Ступенчатый массив
Пример
//Объявляем 2-мерный ступенчатый массив
int[][] k = new int[2][];
//Объявляем 0-й элемент нашего ступенчатого массива
//Это опять массив и в нем 3 элемента
k[0]=new int[3];
//Объявляем 1-й элемент нашего ступенчатого массива
//Это новый массив, содержащий 4 элемента
k[1]=new int[4];
k[1][3]=22; //записываем 22 в последний элемент массива
Класс System.Array
Все массивы в C# построены на основе базового класса Array, который содержит свойства и методы, наиболее часто используемые из них периведены в табл. 2.1.
Таблица 2. 1 – Некоторые элементы класса Array
Элемент | Вид | Описание |
Length | Свойство | Количество элементов массива (по всем размерностям) |
BinarySearch | Статический метод | Двоичный поиск в отсортированном массиве |
Clear | Статический метод | Присваивание элементам массива значений по умолчанию |
Copy | Статический метод | Копирование заданного диапазона элементов одного массива в другой массив |
GetValue | Метод | Получение значения элемента массива |
IndexOf | Статический метод | Поиск первого вхождения элемента в одномерный массив |
Reverse | Статический метод | Изменение порядка следования элементов на обратный |
Sort | Статический метод | Упорядочивание элементов одномерного массива |
Массивы объектов
При создании массива, состоящего из элементов ссылочного типа, память выделяется только под ссылки на элементы, а сами элементы необходимо разместить в хипе явным образом.
Символы и строки
C# для обработки текстовой информации предоставляет широкий набор средств: отдельные символы, массивы символов, изменяемые и неизменяемые строки и регулярные выражения.
Символы
Символьный тип char предназначен для хранения символов в кодировке Unicode. Символьный тип относится к встроенным типам данных C# и соответствует стандартному классу Char библиотеки.NET из пространства имен System. В этом классе определены статические методы, позволяющие задать вид и категорию символа, а также преобразовать символ в верхний или нижний регистр и в число. Некоторые методы класса System.Char приведены в табл.
Таблица – Некоторые методы класса System.Char
Метод | Описание |
GetNumericValue | Возвращает числовое значение символа, если он является цифрой, и –1 в противном случае |
IsControl | Возвращает true, если символ является управляющим |
IsDigit | Возвращает true, если символ является десятичной цифрой |
IsLetter | Возвращает true, если символ является буквой |
пIsLower | Возвращает true, если символ задан в нижнем регистре |
IsUpper | Возвращает true, если символ записан в верхнем регистре |
IsWhiteSpace | Возвращает true, если символ является пробельным (пробел, перевод строки и возврат каретки) |
Parse | Преобразует строку в символ (строка должна состоять из одного символа) |
ToLower | Преобразует символ в нижний регистр |
MaxValue, MinValue | Возвращают символы с максимальным и минимальным кодами (эти символы не имеют видимого представления) |
Строки типа string
Тип string, предназначенный для работы со строками символов в кодировке Unicode, является встроенным типом C#. Ему соответствует базовый класс System.String библиотеки.NET.
Создать строку можно несколькими способами:
string s; // инициализация отложена
string t = "qqq"; // инициализация строковым литералом
string u = new string(' ', 20);
// конструктор создает строку из 20
//пробелов
char[] a = { '0', '0', '0' };
// массив для инициализации строки
string v = new string(a);
// создание из массива символов
Для строк определены следующие операции:
- присваивание (=);
- проверка на равенство (==);
- проверка на неравенство (!=);
- обращение по индексу ([]);
- сцепление (конкатенация) строк (+).
Несмотря на то, что строки являются ссылочным типом данных, на равенство и неравенство проверяются не ссылки, а значения строк. Строки равны, если имеют одинаковое количество символов и совпадают посимвольно.
Обращаться к отдельному элементу строки по индексу можно только для получения значения, но не для его изменения. Это связано с тем, что строки типа string относятся к так называемым неизменяемым типам данных. Методы, изменяющие содержимое строки, создают новую копию строки. Неиспользуемые "старые" копии автоматически удаляются сборщиком мусора.
Некоторые элементы класса System.String приведены в табл.
Таблица – Некоторые элементы класса System.String
Название | Вид | Описание |
Compare | Статический метод | Сравнение двух строк в лексикографическом (алфавитном) порядке. Разные реализации метода позволяют сравнивать строки и подстроки с учетом и без учета регистра и особенностей национального представления дат и т. д. |
Concat | Статический метод | Конкатенация строк. Метод допускает сцепление произвольного числа строк |
Copy | Статический метод | Создание копии строки |
Format | Статический метод | Форматирование в соответствии с заданными спецификаторами формата (см. далее) |
IndexOf, IndexOfAny, LastIndexOf, LastIndexOfAny | Методы | Определение индексов первого и последнего вхождения заданной подстроки или любого символа из заданного набора |
Insert | Метод | Вставка подстроки в заданную позицию |
Join | Статический метод | Слияние массива строк в единую строку. Между элементами массива вставляются разделители |
Length | Свойство | Длина строки (количество символов) |
Split | Метод | Разделение строки на элементы, используя заданные разделители. Результаты помещаются в массив строк |
Substring | Метод | Выделение подстроки, начиная с заданной позиции |
ToCharArray | Метод | Преобразование строки в массив символов |
ToLower, ToUpper | Методы | Преобразование символов строки к нижнему или верхнему регистру |
Форматирование строк
Для форматирования строк в C# используется метод Format, который заменяет все вхождения параметров в фигурных скобках значениями соответствующих переменных из списка вывода. После номера параметра можно задать минимальную ширину поля вывода, а также указать спецификатор формата, который определяет форму представления выводимого значения.
В общем виде параметр задается следующим образом:
{n [,m[:спецификатор_формата]]}
Здесь n — номер параметра. Параметры нумеруются с нуля, нулевой параметр заменяется значением первой переменной из списка вывода, первый параметр — второй переменной, и т. д. Параметр m определяет минимальную ширину поля, которое отводится под выводимое значение. Если выводимому числу достаточно меньшего количества позиций, неиспользуемые позиции заполняются пробелами. Если числу требуется больше позиций, параметр игнорируется.
Спецификатор формата, как явствует из его названия, определяет формат вывода значения. Например, спецификатор C (Currency) означает, что параметр должен форматироваться как валюта с учетом национальных особенностей представления, а спецификатор Х (Hexadecimal) задает шестнадцатеричную форму представления выводимого значения. Код P (Percent) задает форматирование в виде процентов с точностью до сотой доли.
Пример
public void TestFormat()
{
//метод Format
int x=77;
string s= string.Format("x={0}",x);
label1.Text = s;
s= string.Format("Итого:{0,10} грн.",x);
label2.Text=s;
s= string.Format("Итого:{0,6:######} грн.",x);
label3.Text=s;
s= string.Format("Итого:{0:P} ",0.77);
label4.Text=s;
s= string.Format("Итого:{0,4:C} ",77.77);
label5.Text=s;
//Национальные особенности
System.Globalization.CultureInfo ci =
new System.Globalization.CultureInfo("en-US");
s= string.Format(ci,"Итого:{0,4:C} ",77.77);
label6.Text=s;
}//TestFormat
В примере показано использование различных спецификаций формата с разным числом параметров и разными кодами форматирования. В частности, показан вывод процентов и валют. В последнем примере с валютами демонстрируется задание провайдером национальных особенностей. С этой целью создается объект класса CultureInfo, инициализированный так, чтобы он задавал особенности форматирования, принятые в США. Заметьте, класс CultureInfo наследует интерфейс IFormatProvider. Российские национальные особенности форматирования установлены по умолчанию. Результат работы программы приведен на рис.