русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Операции над строками


Дата добавления: 2013-12-23; просмотров: 1393; Нарушение авторских прав


Объявление строк. Конструкторы класса string

Класс String

Класс char

В C# есть символьный класс char, основанный на классе System.Char и использующий двухбайтную кодировку Unicode представления символов. Для этого типа в языке определены символьные константы - символьные литералы. Константу можно задавать:

  • символом, заключенным в одинарные кавычки;
  • escape-последовательностью;
  • Unicode-последовательностью, задающей Unicode код символа.

Вот несколько примеров объявления символьных переменных и работы с ними:

/// <summary>/// Символы, коды, строки/// </summary>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 = ch; s = ch1.ToString()+ch2.ToString()+ch3.ToString(); Console.WriteLine("s= {0}, ch= {1}, code = {2}", s, ch, code); }//TestChar

Три символьные переменные инициализированы константами, значения которых заданы тремя разными способами. Переменная ch объявляется в объектном стиле, используя new и вызов конструктора класса. Тип char, как и все типы C#, является классом. Этот класс наследует свойства и методы класса object и имеет большое число собственных методов.

Существуют ли преобразования между классом char и другими классами? Явные или неявные преобразования между классами char и string отсутствуют, но, благодаря методу ToString, переменные типа char стандартным образом преобразуются в тип string. Поскольку у каждого символа есть свой код, существуют неявные преобразования типа char в целочисленные типы, начиная с типа ushort. Обратные преобразования целочисленных типов в тип char также существуют, но они уже явные.



В результате работы процедуры TestChar строка s, полученная сцеплением трех символов, преобразованных в строки, имеет значение BZX, переменная ch равна A в латинском алфавите, а ее код - переменная code - 65. Хотя преобразования символа в код и обратно просты, полезно иметь процедуры, выполняющие взаимно-обратные операции, - получение по коду символа и получение символа по его коду:

/// <summary> /// Код символа /// </summary> /// <param name="sym">символ</param> /// <returns>его код</returns> public static int SayCode(char sym) { return sym; }//SayCode /// <summary> /// Символ /// </summary> /// <param name="code">Код символа</param> /// <returns>символ</returns> public static char SaySym(int code) { return (char)code; }// SaySym

В первой процедуре преобразование к целому типу выполняется неявно. Во второй - преобразование явное.

Говоря о символах и их кодировке, следует помнить, что для символов алфавитов естественных языков (латиницы, кириллицы) применяется плотная кодировка. Это означает, что поскольку буква z в латинице следует за буквой y, код z на единицу больше кода y. Только буква "Ё" в кириллице не подчиняется этому правилу. Для цифр также используется плотная кодировка, и их коды предшествуют кодам букв. Заглавные буквы в кодировке предшествуют строчным. Ряд символов воспринимаются как управляющие, выполняя при их появлении определенное действие. К подобным относятся такие символы, как "перевод строки" (new line), "возврат каретки" (carriage return), "звонок". Эти символы не имеют видимого образа, а их коды задаются escape последовательностями ('\n', '\r'). Поскольку алфавит, задаваемый Unicode-кодировкой, содержит более 65000 символов, большинство кодов зарезервировано и им пока не соответствуют реальные символы. Рассмотрим пример, демонстрирующий коды некоторых символов.

// <summary> /// Преобразования код <-> символ /// </summary> public void SymToFromCode() { char sym1 = '0', sym2 = 'a', sym3 = 'A', sym4 = '\r', sym5 = 'а', sym6 = 'А'; PrintCode(sym1); PrintCode(sym2); PrintCode(sym3); PrintCode(sym4); PrintCode(sym5); PrintCode(sym6); int code1 = 13, code2 = 122, code3 = 1071, code4 = 70000; PrintSym(code1); PrintSym(code2); PrintSym(code3); PrintSym(code4); }

Процедуры печати PrintCode и PrintSym достаточно просты, так что код их не приводится. Результат работы этого метода показан на рис. 7.1.


Рис. 7.1. Символы и их коды

Класс char, как и все классы в C#, наследует свойства и методы родительского класса object. Но у него есть и собственные методы и свойства, и их немало. Приведу сводку этих методов.

Таблица 7.1. Статические методы и свойства класса char
Метод Описание
GetNumericValue Возвращает численное значение символа, если он является цифрой, и (-1) в противном случае.
GetUnicodeCategory Все символы разделены на категории. Метод возвращает Unicode категорию символа. Ниже приведен пример.
IsControl Возвращает true, если символ является управляющим.
IsDigit Возвращает true, если символ является десятичной цифрой.
IsLetter Возвращает true, если символ является буквой.
IsLetterOrDigit Возвращает true, если символ является буквой или цифрой.
IsLower Возвращает true, если символ задан в нижнем регистре.
IsNumber Возвращает true, если символ является числом (десятичной или шестнадцатеричной цифрой).
IsPunctuation Возвращает true, если символ является знаком препинания.
IsSeparator Возвращает true, если символ является разделителем.
IsSurrogate Некоторые символы Unicode с кодом в интервале [0x1000, 0x10FFF] представляются двумя 16-битными "суррогатными" символами. Метод возвращает true, если символ является суррогатным.
IsUpper Возвращает true, если символ задан в верхнем регистре.
IsWhiteSpace Возвращает true, если символ является "белым пробелом". К белым пробелам, помимо пробела, относятся и другие символы, например, символ конца строки и символ перевода каретки.
Parse Преобразует строку в символ. Естественно, строка должна состоять из одного символа, иначе возникнет ошибка.
ToLower Приводит символ к нижнему регистру.
ToUpper Приводит символ к верхнему регистру.
MaxValue, MinValue Свойства, возвращающие символы с максимальным и минимальным кодом. Возвращаемые символы не имеют видимого образа.

Большинство статических методов перегружены. Они могут применяться как к отдельному символу, так и к строке, для которой указывается номер символа для применения метода. Основную группу составляют методы Is, крайне полезные при разборе строки. Приведу примеры, в которых используются многие из перечисленных методов:

/// <summary> /// Свойства символов /// </summary> public void TestCharMethods() { Console.WriteLine("Метод GetUnicodeCategory:"); System.Globalization.UnicodeCategory cat1, cat2; cat1 = char.GetUnicodeCategory('A'); cat2 = char.GetUnicodeCategory(';'); Console.WriteLine("'A' - category {0}", cat1); Console.WriteLine("';' - category {0}", cat2); Console.WriteLine("Метод IsLetter:"); Console.WriteLine("'z' - IsLetter - {0}", char.IsLetter('z')); Console.WriteLine("'Я' - IsLetter - {0}", char.IsLetter('Я')); Console.WriteLine("Метод IsLetterOrDigit:"); Console.WriteLine("'7' - IsLetterOrDigit - {0}", char.IsLetterOrDigit('7')); Console.WriteLine("'Я' - IsLetterOrDigit - {0}", char.IsLetterOrDigit('Я')); Console.WriteLine("Метод IsControl:"); Console.WriteLine("';' - IsControl - {0}", char.IsControl(';')); Console.WriteLine(@"'\r' - IsControl - {0}", char.IsControl('\r')); Console.WriteLine("Метод IsSeparator:"); Console.WriteLine("' ' - IsSeparator - {0}", char.IsSeparator(' ')); Console.WriteLine("';' - IsSeparator - {0}", char.IsSeparator(';')); Console.WriteLine("Метод IsWhiteSpace:"); Console.WriteLine("' ' - IsWhiteSpace - {0}", char.IsWhiteSpace(' ')); Console.WriteLine(@"'\r' - IsWhiteSpace - {0}", char.IsWhiteSpace('\r')); }//TestCharMethods

Вот как выглядят результаты консольного вывода, порожденного выполнением метода.


Рис. 7.2. Свойства символов

Обратите внимание: буквенными символами являются как символы латиницы, так и кириллицы, символ возврата каретки относится к белым пробелам и к управляющим символам, а символ точки с запятой к разделителям не относится.

Кроме статических методов, у класса char есть и динамические методы. Большинство из них - это методы родительского класса object, унаследованные и переопределенные в классе char. Из собственных динамических методов стоит отметить метод CompareTo, позволяющий проводить сравнение символов. Он отличается от метода Equal тем, что для несовпадающих символов выдает "расстояние" между символами в соответствии с их упорядоченностью в кодировке Unicode.

2.1. Класс char[] - массив символов

В языке C# определен класс char[], и его можно использовать для представления строк постоянной длины, как это делается в С++. Более того, поскольку массивы в C# динамические, расширяется класс задач, в которых можно использовать массивы символов для представления строк. Так что имеет смысл разобраться, насколько хорошо C# поддерживает работу с таким представлением строк.

Массив char[] - это обычный массив, элементы которого являются символами. Массив символов можно преобразовать в строку, можно выполнить и обратное преобразование. У класса string есть конструктор, которому в качестве аргументов можно передать массив символов. У класса string есть динамический метод ToCharArray, преобразующий строку в массив символов.

Класс char[], как и всякий класс-массив в C#, является наследником не только класса object, но и класса Array. Некоторые методы класса Array можно рассматривать как операции над строками. Например, метод Copy дает возможность выделять и заменять подстроку в теле строки. Методы IndexOf, LastIndexOf позволяют определить индексы первого и последнего вхождения в строку некоторого символа. К сожалению, их нельзя использовать для более интересной операции - нахождения индекса вхождения подстроки в строку. При необходимости такую процедуру можно написать самому. Вот как она выглядит:

int IndexOfStr( char[]s1, char[] s2) { //возвращает индекс первого вхождения подстроки s2 в строку s1 int i =0, j=0, n=s1.Length-s2.Length; bool found = false; while( (i<=n) && !found) { j = Array.IndexOf(s1,s2[0],i); if (j <= n) { found=true; int k = 0; while ((k < s2.Length)&& found) { found =char.Equals(s1[k+j],s2[k]); k++; } } i=j+1; } if(found) return(j); else return(-1); }//IndexOfStr

В реализации используется метод IndexOf класса Array, позволяющий найти начало совпадения строк, после чего проверяется совпадение остальных символов. Реализованный здесь алгоритм является самым очевидным, но не самым эффективным.

А теперь рассмотрим метод, тестирующий преобразования строк и массивов символов.

/// <summary> /// Строки и массивы символов /// </summary> public void TestCharArray() { const string STROKA = "Строка "; const string HAS = " содержит подстроку "; const string NO = "не "; string source = "Петроград", pattern = "рад"; char[] sour = source.ToCharArray(); char[] pat = pattern.ToCharArray(); int first = SymAndStr.IndexOfStr(sour, pat); if ( first >= 0) Console.WriteLine(STROKA + source + HAS + pattern); else Console.WriteLine(STROKA + source + NO + HAS + pattern); string word = new string(sour, first - 1, 4); Console.WriteLine(word); }

2.2. Существует ли в C# строки типа char*

В языке C# указатели допускаются в блоках, отмеченных как небезопасные. Теоретически в таких блоках можно объявить переменную типа char*, рассматривая ее как строку. В C# строки типа char* использовать не рекомендуется.

Основным типом при работе со строками является тип string, задающий строки переменной длины. Класс string в языке C# относится к ссылочным типам. Над строками - объектами этого класса - определен широкий набор операций, соответствующий современному представлению о том, как должен быть устроен строковый тип.

Объекты класса string объявляются как все прочие объекты простых типов - с явной или отложенной инициализацией, с явным или неявным вызовом конструктора класса. Чаще всего, при объявлении строковой переменной конструктор явно не вызывается, а инициализация задается строковой константой. Но у класса string достаточно много конструкторов. Они позволяют сконструировать строку из:

  • символа, повторенного заданное число раз;
  • массива символов char[];
  • части массива символов.

Некоторым конструкторам в качестве параметра инициализации можно передать строку, заданную типом 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); }

Объект world создан без явного вызова конструктора, а объекты sssss, stryes, strye созданы разными конструкторами класса string. Заметьте, не допускается явный вызов конструктора по умолчанию - конструктора без параметров. Нет также конструктора, которому в качестве аргумента можно передать обычную строковую константу. Соответствующие операторы в тексте закомментированы.

Над строками определены следующие операции:

  • присваивание (=);
  • две операции проверки эквивалентности (= =) и (!=);
  • конкатенация или сцепление строк (+);
  • взятие индекса ([]).

Начну с присваивания. Поскольку string - это ссылочный тип, в результате присваивания создается ссылка на константную строку, хранимую в "куче". С одной и той же строкой в "куче" может быть связано несколько переменных строкового типа. Эти переменные являются синонимами - разными именами одного и того же объекта, разделяя общую память.

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

Бинарная операция "+" сцепляет две строки, приписывая вторую строку к хвосту первой.

Возможность взятия индекса при работе со строками отражает тот приятный факт, что строку можно рассматривать как массив и получать без труда каждый ее символ. Каждый символ строки имеет тип char, он доступен только для чтения, но не для записи.

Вот пример, в котором над строками выполняются данные операции:

/// <summary> /// Операции над строками /// </summary> public void TestOpers() { const string DEL = "->"; string s1 = "ABC", s2 = "CDE"; string s3 = s1 + s2; string s4 = s3.Substring(0, 3); bool b1 = (s1 == s4); char ch1 = s1[2]; Console.WriteLine(s1 + DEL + s2 + DEL + s3 + DEL + b1.ToString() + DEL + ch1.ToString()); }


<== предыдущая лекция | следующая лекция ==>
Общий взгляд | Метод Format


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Полезен материал? Поделись:

Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.002 сек.