Конспект лекций (C#)-unlocked. 1 Основные сведения о C# Особенности языка
Скачать 1.97 Mb.
|
2.14.3 Ступенчатые массивы Ступенчатый массивы представляют собой особый тип многомерных масси- вов, у которого во второй и последующих размерностях может быть различное ко- личество элементов. Отличие в описании и использовании ступенчатых массивов, по сравнению с многомерными, заключается в следующем: каждая размерность заключается в отдельную пару квадратных скобок (вместо запятых, отделяющих размерности в многомерных массивах); т.к. каждая размерность представляет собой отдельный одномерный массив, при создании ступенчатого массива каждая размерность создаётся индивидуально от- дельными командами. За одну команду не может быть создано несколько размер- ностей. Формально, объявление и начало создания ступенчатого массива может быть записано строкой <тип>[][][[] ...] <идентификатор> = new <тип>[<размер 1>][][[] ...]; Пример: создание ступенчатого массива с тремя размерностями (графическая иллюстрация приведена на рисунке 2.1) int[][][] mas; mas = new int[2][][]; // 1 mas[0] = new int[2][]; // 2 mas[1] = new int[3][]; // 3 mas[0][0] = new int[4]; // 4 mas[0][1] = new int[2]; // 5 mas[1][0] = new int[3]; // 6 30 mas[1][1] = new int[2]; // 7 mas[1][2] = new int[4]; // 8 Рисунок 2.1 – Создание ступенчатого массива с тремя размерностями 2.14.4 Работа с массивами как с объектами Переменная-массив фактически является ссылкой на область памяти, поэтому при создании массивов используется оператора new Однако значение переменной-массиву может быть присвоено не только путём создания нового объекта, но и путём присвоения ссылки на существующий объект, например фрагмент кода int[] mas1 = {1,2}; int[] mas2 = mas1; создаёт две ссылки на одну и туже область данных. Это можно проверить следую- щим кодом 1 : mas1[0] = 3; MessageBox.Show(mas1[0].ToString()+" - "+mas2[0].ToString()); Вторая строка кода выведет сообщение «3 - 3», что подтверждает, что обе перемен- ные ссылаются на один и тот же массив. Повторное создание массива для переменной mas1 с использованием операто- ра new не изменит размерность существующего массива, а создаст новый массив, что может подтвердить код mas1 = new int[3] {4,5,6}; MessageBox.Show(mas1[0].ToString()+" - "+mas2[0].ToString()); 1 Для вывода сообщения используется метод Show() класса MessageBox, которому в качестве параметра передаётся текст сообщения. 31 выполнение которого выведет сообщение «4 - 3». Это означает, что переменная mas1 ссылается на новый массив, а переменная mas2 – на старый. Если бы не было переменной mas2 , то при повторном создании массива не осталось бы ни одной ссылки на исходный массив, и он бы был уничтожен в процессе «сборки мусора». Так как каждый массив является объектом, то он обладает рядом единых для всех массивов свойств и методов, некоторые из которых приведены в таблице 2.1. Таблица 2.1 – Некоторые свойства и методы массивов Наименование Описание CopyTo (Array array, int index) 1 Копирует все элементы из текущего одномерного массива в одномерный массив array , начиная их размещать начиная с позиции index , например: int[] mas = {1,2,3,4,5,6}; int[] mas2 = {7,8,9}; mas2.CopyTo(mas,2); // mas = {1 2 7 8 9 6} Если все элементы разместить невозможно, возникает ис- ключение. GetLength (int dimension) Возвращает количество элементов в заданной размерности, например: int[,] mas = {{1,2,3},{4,5,6}}; int i = mas.GetLength(0); // i = 2 int j = mas.GetLength(1); // j = 3 GetLowerBound (int dimension) Возвращает значение индекса нижней границы в заданной размерности, например: int[,] mas = {{1,2,3},{4,5,6}}; int i = mas.GetLowerBound(0); // i = 0 int j = mas.GetLowerBound(1); // j = 0 GetUpperBound (int dimension) Возвращает значение индекса верхней границы в заданной размерности, например: int[,] mas = {{1,2,3},{4,5,6}}; int i = mas.GetUpperBound(0); // i = 1 int j = mas.GetUpperBound(1); // j = 2 Length Возвращает суммарное количество элементов массива во всех размерностях, например: int[,] mas = {{1,2,3},{4,5,6}}; int i = mas.Length; // i = 6 Rank Возвращает ранг массива, например: int[,] mas = {{1,2,3},{4,5,6}}; int i = mas.Rank; // i = 2 1 Здесь и далее может приводиться только одна из реализаций метода. Полный список реализаций смотри в справке к Visual C# 32 2.15 Оператор цикла foreach Оператор цикла foreach может использоваться при обработке массивов в случае, когда требуется обработать все элементы массива. Формальная структура оператора имеет вид: foreach (<тип> <идентификатор переменной цикла> in <идентификатор массива>) <оператор>; <тип> и <идентификатор переменной цикла> описывают переменную, в которую будет записываться текущее значение элемента массива <идентификатор массива> на каждом этапе цикла. Поэтому <тип> должен совпадать с типом эле- мента массива. При работе цикла последовательно перебираются все элементы массива, неза- висимо от его размерности (т.е. оператор может обрабатывать и многомерные мас- сивы). Например, для нахождения суммы элементов двухмерного массива может быть использован следующий код: int[,] mas = ???; int sum = 0; foreach (int a in mas) sum += a; При выполнении цикла переменная <идентификатор переменной цикла> доступна только для чтения, поэтому изменить значение элемента массива с её по- мощью нельзя. Работу цикла можно прервать с использованием оператора break 2.16 Строки Строковый тип данных string (или String ) представляет собой ссылку на объект, хранящий последовательность символов – строку. При работе со строковыми константами используются кавычки, например, объявление и инициализация строки может быть записана как: string s = "Пример"; Строка может быть задана с помощью массива символов, например: char[] mas = {'П','р','и','м','е','р'}; string s = new string(mas); // s = "Пример" Несмотря на то, что строки являются ссылками на объекты, некоторые опера- ции с ними выполняются так, как если бы строки хранили сами значения: 33 оператор + Позволяет объединять две строки, например, оператор s = "При"+"мер"; присваивает строке s текст «Пример»; операторы == и != . Сравнивают строки по содержимому, а не по адресу. Напри- мер, во фрагменте кода string s1 = "Пример"; string s2 = "При"+"мер"; bool b = (s1 == s2); значение переменной b будет true . Следует отметить, что другие операторы сравнения при работе со строками недопустимы. При выполнении операции сложения не требуется преобразование перемен- ных к строке, например: int n = 5; string s = "Значение переменной n равно "+n; //s = "Значение переменной n равно 5" Строки являются неизменяемыми объектами 1 . Поэтому во всех операциях по изменению строки на самом деле создаются новые объекты и разрушаются старые, например, во фрагменте программы: string s = "Пример"; s += " изменения строки"; создаётся новый объект-строка с текстом «Пример изменения строки», которая при- сваивается переменной s . Старый объект-строка (с текстом «Пример») будет уни- чтожен в процессе «сборки мусора». Каждый элемент строки является символом. Доступ к элементам строки осу- ществляется с использованием номера элемента (нумерация с нуля), заключённого в квадратные скобки, например, для проверки, является ли первый элемент строки символом «П» может быть использовано условие: if (s[0] == 'П') ...; Доступ к элементам строки не может быть использован для их модификации, т.е. оператор s[1] = 'а' ; является недопустимым. Класс string предоставляет для работы со строками ряд методов и свойств, которые могут вызваны с использованием как переменной данного класса (таблица 2.2), так и с помощью самого класса (таблица 2.3) 2 1 Для работы с изменяемыми строками можно использовать класс StringBuilder или последовательность действий: перевод в массив символов - обработка - запись в строку. 2 Большинство функций являются перегруженными, имеющими дополнительные параметры сравнения и ло- кализации. В таблице указаны только некоторые варианты функций. 34 Таблица 2.2 – Некоторые методы и свойства класса string , вызываемые че- рез переменную Наименование Описание Length Возвращает длину строки, например: string s = "Пример"; int i = s.Length; // i = 6 CompareTo (string s) Сравнивает текущую строку со строкой s (по алфавиту, а не по длине). Возвращает: -1, если текущая строка расположена раньше (т.е. меньше), чем строка s ; 0, если строка s равна текущей; 1, если текущая строка расположена позднее (т.е. больше), чем строка s string s1 = "абв"; string s2 = "гд"; string s3 = "абв"; int i = s1.CompareTo(s2); // i = -1 int j = s2.CompareTo(s3); // j = 1 int k = s1.CompareTo(s3); // k = 0 Contains (string s) Возвращает true , если текущая строка содержит подстроку s , или подстрока s пустая (в противном случае возвращает false ). Срав- нение осуществляется с учётом регистра и без учёта региональных настроек. Например: string s = "Пример"; bool b1 = s.Contains("рим"); // b1 = true bool b2 = s.Contains("Рим"); // b2 = false StartsWith (string s) Возвращает true , если текущая строка начинается с подстроки s (в противном случае возвращает false ). Например: string s = "Пример"; bool b1 = s.StartsWith("Прим"); // b1 = true bool b2 = s.StartsWith("Прин"); // b2 = false EndsWith (string s) Возвращает true , если текущая строка заканчивается подстрокой s (в противном случае возвращает false ). Например: string s = "Пример"; bool b1 = s.EndsWith("мер"); // b1 = true bool b2 = s.EndsWith("мера"); // b2 = false IndexOf (string s) Возвращает позицию первого вхождения подстроки s в текущей строке. Если подстрока не найдена, возвращается -1. Например: string s = "Пример поиска подстроки"; int i1 = s.IndexOf("по"); // i1 = 7 int i2 = s.IndexOf("пол"); // i2 = -1 35 Продолжение таблицы 2.2 Наименование Описание LastIndexOf (string s) Возвращает позицию последнего вхождения подстроки s в теку- щей строке. Если подстрока не найдена, возвращается -1. Напри- мер: string s = "Пример поиска подстроки"; int i1 = s.LastIndexOf("по"); // i1 = 14 int i2 = s.LastIndexOf("пол"); // i2 = -1 Insert (int index, string s) Возвращает строку, полученную путём вставки строки s в теку- щую строку начиная с позиции index . Например: string s1 = "Слон ест мясо."; string s2 = s1.Insert(5,"не "); // s2 = "Слон не ест мясо." Remove (int sIndex [,int count]) Возвращает строку, полученную путём удаления из текущей строки всех (или count ) символов начиная с позиции sIndex (все параметры не должны выходить за пределы строки, в т.ч. sIndex+count ). Например: string s1 = "Это не правда."; string s2 = s1.Remove(4,3); // s2 = "Это правда." Replace (string oldS, string newS) Возвращает строку, полученную путём замены в текущей строке всех подстрок oldS на подстроки newS с учётом регистра и без учёта региональных настроек. Например: string s1 = "трижды три будет 4"; string s2 = s1.Replace("три","два"); // s2 = "дважды два будет 4" Substring (int sIndex [,int count]) Возвращает строку, полученную путём извлечения из текущей строки всех (или count ) символов начиная с позиции sIndex (все параметры не должны выходить за пределы строки, в т.ч. sIndex+count ). Например: string s1 = "Это не правда."; string s2 = s1.Substring(7,6); // s2 = "правда" Split (char[] sep) Возвращает массив строк, полученный путём разделения теку- щей строке на подстроки, расположенные между разделителями sep . Если два разделителя расположены в строке подряд (а так- же, если разделителем является первый или последний символ), то в массив добавляются пустые строки (от этого можно отка- заться используя расширенные варианты метода). Например: string s = " один, два,три четыре,"; char[] sep = { ' ', ',' }; string[] mas = s.Split(sep); // mas = {"", "один", "", "два", "три", "четыре", ""} 36 Продолжение таблицы 2.2 Наименование Описание ToCharArray ([int sIndex, int count]) Переводит текущую строку в массив символов. Если заданы пара- метры, то переводятся символы начиная с позиции sIndex в коли- честве count . Например: string s = "Пример"; char[] mas = s.ToCharArray(1,3); // mas = ('р','и','м') ToLower() ToUpper() Возвращает строку, полученную путём приведения текущей строки к нижнему (верхнему) регистру. Например: string s1 = "ПриМер"; string s2 = s1.ToLower(); // s2 = "пример" string s3 = s1.ToUpper(); // s3 = "ПРИМЕР" Trim ([char[] tc]) TrimStart ([char[] tc]) TrimEnd ([char[] tc]) Возвращает строку, полученную путём удаления из текущей строки всех начальных ( Trim , TrimStart ) и конечных ( Trim , TrimEnd ) пробелов (или символов, заданных в массиве tc ). Например: string s1 = " Пример, "; char[] tc = {' ',','}; string s2 = s1.Trim(); // s2 = "Пример," string s3 = s1.Trim(tc); // s3 = "Пример" Таблица 2.3 – Некоторые методы и свойства класса string , вызываемые че- рез сам класс Наименование Описание Empty Возвращает пустую строку (""). Т.е. строка есть, но состоит из 0 символов. Значение null означает, что строки вообще нет. string s = String.Empty; // s = "" Copy (string s) Возвращает строку, полученную путём копирования строки s Например: string s1 = "Пример"; string s2 = String.Copy(s1); // s2 = "Пример" Строка string s2 = s1; скопирует не значение, а ссылку! IsNullOrEmpty () Возвращает true , если строка s имеет значение null или String.Empty (в противном случае возвращает false ). Напри- мер: string s = "Пример"; bool b = String.IsNullOrEmpty(s); // b = false 37 Продолжение таблицы 2.3 Наименование Описание Format (string s, Object a0 [,Object a1 ...]) Возвращает строку, полученную путём форматирования ар- гументов a0[,a1 ...] с использованием строки форматирования s Строка форматирования содержит произвольный текст с указанием мест, в которые должны быть вставлены отформатированные опре- делённым образом аргументы. Места задаются фигурными скобка- ми, содержащими номер аргумента и, при необходимости, способ форматирования, отделённый от номера двоеточием. Способ форматирования состоит из описателя формата и количе- ства значащих цифр или десятичных знаков. Некоторые описатели формата для чисел: D или d – десятичный, используемый для целых чисел; E или e – инженерный (экспоненциальный); F или f – для вывода десятичных знаков; N или n – числовой, с разделением разрядов; X или x – шестнадцатеричный; P или p – процентный. Например: double d = 2.1; string s1 = String.Format( "Результат {0}*{0:F3} равен: {1:F1}",d,d*d); // s1 = "Результат 2,1*2,100 равен: 4,4" int i = 400; string s2 = String.Format( "Результат {0}*{0:D4} равен: {1:N1}",i,i*i); // s2 = "Результат 400*0400 равен: 160 000,0" При формировании строки возможно внедрение в неё Escape- последовательностей, обеспечивающих дополнительное форматирование строк при выводе. Каждая Escape-последовательность начинается с символа «\», после которо- го указывается тип последовательности в виде некоторого символа. Например, если строка задана как string s = "Это строка\nиз двух строк"; то при выводе данной строки она будет разделена на две: «Это строка» и «из двух строк». Некоторые Escape-последовательности приведены в таблице 2.4. Использование символа «\» для обозначения Escape-последовательности мо- жет привести к неудобствам и ошибкам, например, если имя файла задано в строке следующим образом string s = "C:\new.txt"; 38 то часть строки «\n» будет интерпретирована как переход на новую строку, и файл найден не будет. Таблица 2.4 – Список Escape-последовательностей Последовательность Описание \' Вставка одиночной кавычки в текст строки \" Вставка двойной кавычки в текст строки \\ Вставка обратной косой черты в текст строки \n Переход на новую строку \r Возврат каретки \t Вставка символа горизонтальной табуляции Для отказа от использования в строке Escape-последовательностей, перед строкой указывается символ «@», т.е. предыдущий пример может быть записан од- ним из двух способов: string s = "C:\\new.txt"; или string s = @"C:\new.txt"; Так как при применении символа «@» текст воспринимается без изменений, то в нем могут быть введены символы табуляции, перехода на новую строку и т.п. Например, если строка задана в виде string s = @"Это первая строка Это вторая строка Это третья строка"; то при выводе такой строки она будет разделена на три. Единственное преобразование, которое выполняется в строках, перед которы- ми указана символ «@» – это вставка в текст двойных кавычек. Для этого в месте вставки двойной кавычки она указывается дважды: string s = @"Он сказал ""Привет"""; 2.17 Перечисления Перечисление представляет собой набор имён, определяющих все возможные значения которые могут быть назначены переменной. Использование перечислений повышает читаемость кода программы и снижа- ет вероятность задания переменной недопустимого значения. Формальное описание перечисления имеет вид: enum <идентификатор перечисления>[: <тип>] { <идентификатор элемента 1>[=<значение 1>] |