PrintCollection("col1",col1);
CreateCollection(col2);
PrintCollection("col2",col2);
CreateCollection(col3);
PrintCollection("col3",col3);
CreateTwoDimAr(col4);
PrintCollection("col4",col4);
// поиск элемента
int first = Array.IndexOf(col1, 2);
int last = Array.LastIndexOf(col1,2);
if (first == -1)
Console.WriteLine("Нет вхождений 2 в массив col1");
else if (first ==last)
Console.WriteLine("Одно вхождение 2 в массив col1");
Else
Console.WriteLine("Несколько вхождений 2 в массив col1");
//first = Array.IndexOf(col4, 4); только одномерный массив
Array.Reverse(col1);
Console.WriteLine("Обращение массива col1:");
PrintCollection("col1",col1);
//копирование
Array.Copy(col1, col3, col1.Length);
Console.WriteLine(" Массив col3 после копирования массива col1:");
PrintCollection("col3",col3);
Array.Copy(col1,1,col2,1,2);
Console.WriteLine("копирование двух элементов col1 в col2:");
PrintCollection("col1",col1);
PrintCollection("col2",col2);
//быстрая сортировка Хоара
Array.Sort(col1);
Console.WriteLine("Отсортированный массив col1:");
PrintCollection("col1",col1);
first = Array.BinarySearch(col1, 2);
Console.WriteLine("Индекс вхождения 2 в col1: {0}",first);
//Создание экземпляра (массива)
Array my2Dar = Array.CreateInstance(typeof(double), 2,3);
PrintCollection("my2Dar",my2Dar);
//клонирование
my2Dar = (Array)col4.Clone();
Console.WriteLine("Массив my2Dar после клонирования col4:");
PrintCollection("my2Dar",my2Dar);
//копирование CopyTo
col1.CopyTo(col2,0);
Console.WriteLine("Массив col2 после копирования col1:");
PrintCollection("col2",col2);
}
В этой процедуре продемонстрированы вызовы различных статических методов класса Array. Для метода Copy показан вызов двух реализаций этого метода, когда копируется весь массив и часть массива. Закомментированный оператор вызова метода IndexOf напоминает о невозможности использования методов поиска при работе с многомерными массивами.
Строки в С#
Класс Сhar
В C# есть символьный класс Char, основанный на классе System.Char и использующий двухбайтную кодировку Unicode представления символов. Для этого типа в языке определены символьные константы - символьные литералы. Константу можно задавать:
· символом, заключенным в одинарные кавычки;
· escape-последовательностью, задающей код символа;
· Unicode-последовательностью, задающей Unicode-код символа.
public void TestChar(){
char ch1='A', ch2 ='\x5A', ch3='\u0058';
char ch = new Char();
int code; string s;
ch = ch1;
//преобразование символьного типа в тип int
code = ch; ch1=(char) (code +1);
//преобразование символьного типа в строку
s = ch1.ToString()+ch2.ToString()+ch3.ToString();
Console.WriteLine("s= {0}, ch= {1}, code = {2}", s, ch, code);
}
Тип char, как и все типы C#, является классом. Этот класс наследует свойства и методы класса Object и имеет большое число собственных методов.
Таблица 1.5 - Статические методы и свойства класса Char
Метод | Описание |
GetNumericValue | Возвращает численное значение символа, если он является цифрой, и (-1) в противном случае |
IsDigit | Возвращает true, если символ является десятичной цифрой |
IsLetter | Возвращает true, если символ является буквой |
IsLetterOrDigit | Возвращает true, если символ является буквой или цифрой |
IsLower | Возвращает true, если символ задан в нижнем регистре |
IsNumber | Возвращает true, если символ является числом (десятичной или шестнадцатиричной цифрой) |
IsUpper | Возвращает true, если символ задан в верхнем регистре |
ToLower | Приводит символ к нижнему регистру |
ToUpper | Приводит символ к верхнему регистру |
Класс Сhar[] - массив символов
В языке C# определен класс Char[], и его можно использовать для представления строк постоянной длины. Массив char[] - это обычный массив. Он не задает строку, заканчивающуюся нулем. Более того, его нельзя инициализировать строкой символов, как это разрешается в С++. Константа, задающая строку символов, принадлежит классу String, а в C# не определены взаимные преобразования между классами String и Char[], даже явные. У класса String есть динамический метод ToCharArray (), задающий подобное преобразование. Возможно также посимвольно передать содержимое переменной string в массив символов:
// Программа 4. Массивы символов Char[]
string CharArrayToString(char[] ar) {
string result="";
for(int i = 0; i< ar.Length; i++) result += ar[i];
return(result);
}
void PrintCharAr(string name,char[] ar) {
Console.WriteLine(name);
for(int i=0; i < ar.Length; i++)
Console.Write(ar[i]);
Console.WriteLine();
}
public void TestCharArAndString() {
//массивы символов
//char[] strM1 = "Hello, World!"; ошибка: нет преобразования класса string в класс char[]
string hello = "Здравствуй, Мир!";
char[] strM1 = hello.ToCharArray();
PrintCharAr("strM1",strM1);
char[] World = new char[3];
Array.Copy(strM1,12,World,0,3); //копирование подстроки
PrintCharAr("World",World);
Console.WriteLine(CharArrayToString(World));
}
Класс Char[], как и всякий класс-массив в C#, является наследником не только класса Object, но и класса Array, и, следовательно, обладает всеми методами родительских классов.
Класс String
Основным типом при работе со строками является тип string, задающий строки переменной длины. Класс String в языке C# относится к ссылочным типам. Над строками - объектами этого класса - определен широкий набор операций, соответствующий современному представлению о том, как должен быть устроен строковый тип. Объекты класса String объявляются как все прочие объекты простых типов - с явной или отложенной инициализацией, с явным или неявным вызовом конструктора класса. Чаще всего, при объявлении строковой переменной конструктор явно не вызывается, а инициализация задается строковой константой. Но у класса Sring достаточно много конструкторов. Они позволяют сконструировать строку из:
· символа, повторенного заданное число раз;
· массива символов char[];
· части массива символов.
public void TestDeclStrings(){
//конструкторы
string world = "Мир";
//string s1 = new string("s1");
//string s2 = new string();
string sssss = new string('s',5);
char[] yes = "Yes".ToCharArray();
string stryes = new string(yes);
string strye = new string(yes,0,2);
Console.WriteLine("world = {0}; sssss={1}; stryes={2};"+ " strye= {3}", world, sssss, stryes, strye);
}
Над строками определены следующие операции:
· присваивание (=);
· две операции проверки эквивалентности (= =) и (!=);
· конкатенация или сцепление строк (+);
· взятие индекса ([]).
Поскольку string - это ссылочный тип, то в результате присваивания создается ссылка на константную строку, хранимую в "куче". В отличие от других ссылочных типов операции, проверяющие эквивалентность, сравнивают значения строк, а не ссылки. Эти операции выполняются как над значимыми типами.
Бинарная операция "+" сцепляет две строки, приписывая вторую строку к хвосту первой.
Возможность взятия индекса при работе со строками отражает тот приятный факт, что строку можно рассматривать как массив и получать без труда каждый ее символ. Каждый символ строки имеет тип char, доступный только для чтения, но не для записи.
// Программа 5. Строки класса String
public void TestOpers(){
//операции над строками
string s1 ="ABC", s2 ="CDE";
string s3 = s1+s2;
bool b1 = (s1==s2);
char ch1 = s1[0], ch2=s2[0];
Console.WriteLine("s1={0}, s2={1}, b1={2}," + "ch1={3}, ch2={4}", s1,s2,b1,ch1,ch2);
s2 = s1;
b1 = (s1!=s2);
ch2 = s2[0];
Console.WriteLine("s1={0}, s2={1}, b1={2}," +"ch1={3}, ch2={4}", s1,s2,b1,ch1,ch2);
//Неизменяемые значения
s1= "Zenon";
//s1[0]='L';
}
Строковые константы
В C# существуют два вида строковых констант:
· обычные константы, которые представляют строку символов, заключенную в кавычки;
· @-константы, заданные обычной константой c предшествующим знаком @.
В обычных константах некоторые символы интерпретируются особым образом. Связано это прежде всего с тем, что необходимо уметь задавать в строке непечатаемые символы, такие, как, например, символ табуляции. Для всех этих целей используется комбинация символов, начинающаяся символом "\" - обратная косая черта. В @-константах все символы трактуются в полном соответствии с их изображением. Поэтому путь к файлу лучше задавать @-константой. Единственная проблема в таких случаях: как задать символ кавычки, чтобы он не воспринимался как конец самой константы. Решением является удвоение символа. Вот соответствующие примеры:
//Два вида констант
s1= "\x50";
s2=@"\x50""";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
s1 = "c:\\c#book\\ch5\\chapter5.doc";
s2 = @"c:\c#book\ch5\chapter5.doc";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
s1= "\"A\"";
s2=@"""A""";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
Класс String относится к неизменяемым классам (immutable). Ни один из его методов не меняет значения существующих объектов. Конечно, некоторые из методов создают новые значения и возвращают в качестве результата новые строки.
Таблица 1.6 - Статические методы и свойства класса String
Метод | Описание |
Empty | Возвращается пустая строка. Свойство со статусом read only |
Compare | Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. При этом можно учитывать или не учитывать регистр, особенности национального форматирования дат, чисел и т.д. |
CompareOrdinal | Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. Сравниваются коды символов |
Concat | Конкатенация строк. Метод перегружен, допускает сцепление произвольного числа строк |
Copy | Создается копия строки |
Format | Выполняет форматирование в соответствии с заданными спецификациями формата. |
Join | Конкатенация массива строк в единую строку. При конкатенации между элементами массива вставляются разделители. |
Метод Format
Общий синтаксис таков: {N [,M [:<коды_форматирования>]]}
Обязательный параметр N задает индекс объекта, заменяющего формат. Индексация объектов начинается с нуля, как это принято в массивах.
Второй параметр M, если он задан, определяет минимальную ширину поля, которое отводится строке, вставляемой вместо формата.
Третий необязательный параметр задает коды форматирования, указывающие, как следует форматировать объект.
public void TestFormat() {
int x=77;
string s= string.Format("x={0}",x);
Console.WriteLine(s + "\tx={0}",x);
s= string.Format("Итого:{0,10} рублей",x);
Console.WriteLine(s);
s= string.Format("Итого:{0,6:######} рублей",x);
Console.WriteLine(s);
s= string.Format("Итого:{0:P} ",0.77);
Console.WriteLine(s);
s= string.Format("Итого:{0,4:C} ",77.77);
Console.WriteLine(s);
}