Одномерные массивы
обращение к элементу массива: a[4]
Инициализация
int[ ] a; //массив a целого типа
как у переменных
будут инициализировать нули
↑
int[ ] a = new int[5]; // фиксируется длина символа
↓
при работе с массивом можно указывать целое выражение!
индексы от 0 до 4
При работе размер массива будет определяться по последнему индексу:
a[5]=1; //окажется массив на 6 элементов от 0 до 5
элементы 0:4 будут иметь значение Nul
↓
проверить?
int[ ] a = {15,2,8,4};
↓
начальные значения
размерность массива будет длиной 4
выражение указывать нельзя!
int[ ] a = new [6] {8,4,2};
↓
число элементов начальные значения
(остальные будут нули)
Прямоугольные массивы
a[1,2] // двумерный массив прямоугольный
a[2,3,1] // трёхмерный массив прямоугольный
У прямоугольного массивы размеры постоянны т.е n строк и m столбцов для матрицы.
Инициализация (примеры для двумерных!, т.е. матриц)
int[, ] a;
int[, ] a= new int[2,3];
int[, ] a= { {1,4,8}, {5,6}};
n=2m=3
1-я строка 2-я строка
int [, ] a= new int [2,3] { {1,4,8}, {5,6} };
В обоих последних случаях будет инициализирована матрица
|
|
1 4 8
a = n=2
5 6 0
m=3
Ступенчатые массивы
Инициализация:
1) int[ ][ ] a;
2) int[ ][ ] a=new int[3][ ];
a[0]= new int[5]; //каждая строка матрицы инициализируется как одномерный массив
// в данном примере это строка номер один
Нельзя
3) int[ ][ ] a=new int [ ] [3]!
↓
так как перед указанием размера
второго индекса размер первого
уже должен быть указан!
4) int[ ][ ] a={new int[ ], new int[5], new int[4]};
три строки
Лучше как 2) делать, а не так!!!
Функции над массивами
Все массивы являются объектом Array!
a.Length - для одномерного массива его размер, для двумерного- число строк.
a[0].Length - число столбцов, т.е второго размера нулевой строке.
a[0][1].Length - число элементов 3-его размера в 0-й строке и 1-м столбце.
a. Rank -- число размеров массива
a.GetValue(1) – тоже, что a[1].
К статическим методам нужно обращаться через указание класса Array:
Array.Sort(a) // сортировка одномерного массива а по возрастанию
Перечисление
Перечисление – это список именованных констант. В отличие от константы при выводе выводится не числовые значения константы, а ее имя!
Public enum zvanie
{рядовой, сержант, майор, генерал}
// Программа
zvanie x;
x= (zvanie)1;
Console.Write (“звание = {0}”, x); // Будет напечатано: звание = сержант.
Операции с перечислениями:
+ - ++ --
Пример:
zvanie x, y;
x= (zvanie)1; // проверить можно ли x = 1; записать!
y = x++;
Console.Write (“звание = {0}”, y); // будет напечатано звание = майор.
Можно и так:
zvanie x, y;
x = zvanie.рядовой;
y = x++;
Console.Write (“звание = {0}”, y); // звание = сержант
Перечисление напоминает текстовый массив (это имена перечисления) с инкапсупируемыми индексами. Все операции записи (т. е присвоения) делаются над индексами, а на выводе выводятся имена.
|
|
Это можно было бы более сложно заменить массивом:
int[ ] x= {“рядовой”, “сержант”, “майор”);
int i = 1;
Console.Write (“звание = {0}”, x[ i ]); // будет напечатано звание = сержант
i++;
Console. Write (“звание = {0}”, x[ i ]; // будет напечатано звание = майор
Но в этом случае надо хранить в отдельной переменной индекс массива.
Перечисления как видно более удобны
Функции перечислений.
Enum.GetName(typeof(zvanie)) -- Возвращает список имён в строковый массив.
См. стр 218.
string[] names=Enum.GetName(typeof(zvanie));
Отличие от стр 218, там объявление класса Array
Enum.GetValues – возвращает значения перечисления.
Enum.IsDefined(typeof(zvanie), “сержант”); -- Определяет есть ли в перечислении имя, указание вторым параметром строкой.
Регулярные выражения
Назначение регулярных выражений состоит в возможности выделения из строки символов подстрок, соответствующих шаблону. Например для шаблона \bm\s* будут выделены все подстроки, перед которыми имеется пробел(метасимвол \b), подстроки будут начинаться с буквы m и иметь любой набор символов(метасимвол \s) произвольной длины(знак*). Шаблон формируется с использованием метасимволов.
Рассмотрим сначала как строится шаблон
1) Шаблон – это строка string, состоящая из набора специальных символов, конструкций и произвольного текста. Произвольный текст это любая последовательность символов из кодовой таблицы.
2) Та как часть символов кодовой таблицы зарезервирована под специальные символы шаблона (метосимволы) но в произвольном тексте эти символы должны указываться символом \. Пример: \(- т.к. скобка является метосимволом, то в произвольном тексте она должна записываться именно так. Вот перечень этих символов: \ [ ] () { }. * +? | ^ $.
Кроме этих символов вместе с \ указываются специальные символы, не отображаемые в редакторе и являющиеся служебными: \ n - символ новой строки (этот символ имеется в строке, занимает байт, имеет код 13, но естественно никак не отображается)
\ r -символ возврата коретки (код 10)
\ t-символ табуляции
\ v- символ вертикальной табуляции
\ f – символ перевода страницы
Синтаксис шаблона состоит из фрагментов и комментариев. Комментарии не являются частью шаблона и обозначаются конструкцией (? # текст комментария). Фрагмент может в шаблоне выделяться в виде наименованного фрагмента:
Фрагмент 1 (фрагмент 2) фрагмент 3
где фрагмент 2 выделен в шаблоне
или в виде именованного фрагмента:
фрагмент 1 (?<pole1> фрагмент 2) фрагмент 3
где фрагмент 2 наименован строкой «pole1».
Именованные фрагменты необходимы в двух случаях:
1) Если в выделенной строке по шаблону надо потом делать ещё выделение фрагмента 2
2) Если фрагмент 2 несколько раз используется в шаблоне. В этом случае это делается так: ф1 (?<pole 1> ф2) ф3 (\k<pole 1>) ф4
На место «\k» в шаблоне будет вставлен фрагмент ф2.
Фрагмент шаблона можно повторно в шаблоне указывать через \2, где 2- номер по порядку фрагмента, начиная с 1
НАПРИМЕР: ф1 (ф2) ф3 (?<a> ф4) ф5 (ф6) ф7 \ 2 ф8 => на место комбинации \2 будет подставлен второй фрагмент с (), т.е. фрагмент ф4. См. стр. 911 Прайса
Фрагмент шаблона может включать следующие метасимволы, указания типа символа:
\ cx – соответствует в кодовой табл. управляющему символу Сtrl +x:
Пример: \ cM – упр. символ Ctrl+ M
\ d – соотв. любой цифре;
\ D – соотв. любому символу кроме цифры;
\ w – соотв. букве, цифре или знаку подчеркивания;
\ W – соотв. любому символу кроме буквы, цифры и знака подчеркивания;
\ s – соотв. символу пробел или символу форматирования (\t\ n и т.п.);
\ S – соотв. любому символу кроме специального;
\ xnm – шестнадцатеричная escape последовательность ASCII – кода с номером nm:
\xАВ
Значения n и m надо указывать обязательно, даже если n = 0
. – любой символ, кроме конца строки \n
[ послед. ] - любой одиночный символ из последовательности, записанной внутри []:
|
|
[abc] – любой из символов abc. Если символы идут подряд, то последовательность указывается диапазоном:
[ac – z2-7] 2-7 – диапазон цифр от 2 до 7; c-z – диапазон букв от c до z;
Порядок символов соответствует кодовой табл. символов
[^ последов ]- любой из символов, кроме тех, которые указаны в последовательности
Следующие метасимволы являются повторителями символа или фрагмента. Эти метасимволы записываются за символом или фрагментом.
символ {n} – соответствует повторению символа или фрагмента (фр) ровно n раз:
(abc){3} равносильно записи abc abc abc
Симв {n,} - соответствует повторению символа как минимум n раз.
Симв {,m} – соответствует повторению символа не больше m раз.
Симв {n,m} – соответствует повторению символа от n до m раз.
- - ноль и более повторений предыдущего символа.
+ - одно и белее повторений предыдущего символа.
? – ни одного или одно повторение предыдущего символа.
МЕТАСИМВОЛЫ ПОЗИЦИОНИРОВАНИЯ
\ b символ - соответствуют только символу перед которым стоит пробел. Не путать эту конструкцию с _ символ, т.к. в последнем случае будет отбираться строка вместе с пробелом.
Символ \b – выделение символа, за которым идет пробел. Если при записи \ b возникает двухсмысленность:
аbс\bdef
(непонятно \b для с или d), то надо использовать круглые скобки: аb(с\b)def – здесь очевидно \ b используется для с буквы.
\ В – соответствует середине слова:
аbс(def)\Вqh
соответствует def только в середине слова или строки
^ символ – символ только в начале строк, т.е. после \n.
ПРИМЕР: ^(аbсd) – строка аbсd только в начале строки.
$ символ - символ только в конце строки, т.е. перед \n.
\А символ – символ следует искать только перед первой строкой.
\Z символ – символ следует искать только в конце последней строки.
МЕТОСИМВОЛЫ ВЫБОРА ВАРИАНТОВ:
(?: фр1 | фр2 | фр3) – соответствие фр1 или фр2 или фр3.
символ (?= фр1 | фр2 | фр3) – соответствует символ, если за ним через пробел идут фр1 или фр2 или фр3:
(животное)(?кот|собака)
Соответствует фрагменту животное, если за этим словом через пробел будут слова кот или собака
|
|
символ (?!фр1(фр2|фр3) – соответствует символу, если за ним через пробел идут любое слово кроме фр1 или фр2 или фр3.
РАБОТА С ШАБЛОНАМИ
1. Занести шаблон в строку
string Shablon =@ “(\w+)_=_\$(\d=+)[.;]”; // это шаблон вида «вата_=_5$.
2. Объявить объект класса Regex с инициализацией шаблона Shablon:
Regex r = new Regex(Shablon);
3. Задать строку text, из которой будут извлекаться подстроки по шаблону Shablon:
string text = “вата_=_$5; ручка_=_$3;”;
4. Создать объект класса Match, в который занести все множество подстрок в строке text, совпадающих с шаблоном в объекте r:
Match ms = r.Match(text);
5. Проверить, есть ли в ms подстроки:
if(ms.Success){….}
- Извлекается подстрока из ms
string s= ms.Groups[0].ToString();
ms может содержать несколько подстрок, удовлетворяющих шаблону, но в начале указатель в ms расположен на 1-й подстроке. Индекс [0] указывает на первую подстроку.
7. Обрабатываем подстроку S (например печатаем её и т.п.).
8. Перемещаем указатель в ms на следующую подстроку:
ms=ms.NextMatch();
9. переход на п.5
Извлечение из подстроки ms по фрагментам шаблона, заключенных в шаблоне Shablon в скобки (фр1):
String s1= ms.Groups[2].Tostring();
будет извлекаться
фрагмент шаблона, скобки (фр1)
которого в шаблоне shablon
вторые по счету, включая именованные
фрагменты
Для именованных фрагментов шаблона извлечения делается в виде:
s1= ms.Groups(''fr1'').ToString();
где '' fr1'' – имя фрагмента, указанного в шаблоне (?<fr1>фр1)
Шаблон разбиения строки на подстроки по заданному в шаблоне набору разделителей
1) Формируем шаблон разделителей:
String shablon = ‘’[.,:;_]+'';
2) Объявляем объект класса Regex:
Regex r=new Regex(shablon);
3) Объявляем строку, откуда будут извлекаться подстроки:
String text = ‘’a=1; b=5; c=4’’;
4) Объявляем массив строк куда будут заноситься подстроки из строки text по шаблону shablon:
String [] slist = new string[50]; // проверить можно ли не указывать размер 50?
5) Заносим в массив строк slist подстроки из text:
slist = r.Split(text);
6) Работаем с slist как с обычным массивом строк.
Замена в исходной строке text одного фрагмента на другой:
string text1 = Regex.Replace(text,’’Маша’’,’’Нина’’);
Строка text1 будет копией text с заменой в text всех слов «Маша» на «Нина»
Проверка наличия в строке text подстроки с заданным шаблоном
1) Формируем по шаблону shablon объект r класса Regex, как это было показано выше
2) Задаем проверяемую строку text
3) Проверяем наличие в text шаблона r:
if (r.IsMatch(text)) { // есть совпадения с шаблоном}.
Прототипы- данные
Класс-прототип List <T> используется для удобной работы с вектором данных.
Об]явление:
List<string> St=new List<string>(); // будет сформирован вектор строк
Добавление элемента в список:
St.Add(“кошка”);
По этому методу Add индекс вектора увеличится на +1 и в него запишется строка «кошка»
St.Add(“животное“,”собака”);
По этому методу Add индекс вектора увеличится нa +1, ему будет установлен ключ «животное» и в элемент с этим ключом запишется строка «собака»
Пример:
List<int> Zp=new List<int>();
Zp.Add(4);
Zp.Add(“февраль”,8);
Zp.Add(“март”,7);
Zp.Add(11);
Zp.Add(“май”,16);
Из вектора Zp при этом элементы можно выбрать как по номеру, так и по ключу (номера индексов с 0):
int i=Zp[1]; // в i будет число 8
int i=Zp[«март»]; // в i будет число 7
int i=Zp[3]; // в i будет число 11
Свойства класса List:
Zp.Count -> число элементов в списке
Zp.Keys -> возвращает список ключей
Zp.Values -> возвращает список значений
Методы класса List;
Zp.Add() -> добавляет элемент в конец списка
Xp.Clear() -> очищает список
bool b =Zp.ContainsKey («февраль»);
Определяет наличие (true) или отсутсвие (false) указанного ключа в списке
Zp.Remove («февраль»); - удаление из списка элемента c ключом “февраль”
S=Zp.GetByIndex(4); - возвращает значение 4-го элемента списка.
S=Zp.GetKey(4); - возвращает ключ 4-ого элемента списка
I=Zp.IndexOfKey(«март»); -- возвращает номер элемента по ключу
Zp.RemoveAt(4); -- удаляет 4-ый элемент списка
Zp.SetByIndex(4,5); замена 4-го элемента значением 5, где 5 –значение,4- номер элемента. Тоже, что Zp[4]=5;
Zp.TrimToSize(); -- уменьшает емкость списка до реального числа элементов в списке
Zp.Sort(); -- сортирует список по возрастанию значений
КЛАСС SortedList ничем не отличается от List, кроме того, что у него список всегда отсортирован по возрастанию ключей
КЛАСС Dictionary это разновидность списка, но при добавлении элемента в список в отличие от List ведется проверка на наличие добавляемого ключа в список
Обьявление:
Dictionary<типКлюча, тип значения> Zp=new Dictionary<тип Ключа, тип значения>;
В отличие от List к элементу списка Dictionary можно обратиться только по ключу.
Подпрограммы
Подпрограмма – это инкапсулированная последовательность кода, которая по имени может вызываться много раз. Аналогия со стандартными функциями типа sin!
Текст функции формируется по следующим правилам:
static Tип Имя (параметры)
{
Тело функции
Return выражение
}
Тип - любой тип как и у переменной дополнительно: void – это значит, что определена не функция, а процедура.
Примеры:
ФункцияПроцедура
Static int M(double X) Static void MM(double X)
{ {
Return Math.Round(X); Concole.Write({0},X);
} }
Пример обращения Обращение
Y=x*M(X); MM(X);
Параметры подпрограмм
Параметры значения
int X
В программу передаётся значение в специальной ячеейке. Это не позволяет через заголовок изменить параметр.
Пример
static int M(int x)
{return x*x;
x=6;
}
Программа:
x=2;
y=x*M(x); // y=2*(2*2)=8
y=x; // y будет равно 2
Параметры ссылки
ref int x
В n/n передаётся именно адрес параметра, а не копия. Это позволяет в n/n изменять значение параметра.
Пример: 30
static int M (ref int x)
{ return x*x;
x=6;
}
Программа:
x=2;
y=x*M (ref x); // y=8
y=x; // y будет равно 6.
Выходные параметры
out int x
↓
Внутрь п/п ничего не передается т.е. Nul,
а на выход на ref.
Пример:
static int M (out int x)
{ return x*x;
x=6;
}
Программа
x=2;
y=x*M (out x); // ошибка!
y=x; // y=6
Параметры массивы
Можно все, т.е. значение, ссылка, выходной.
int[ ] x
Пример
static int M (int[ ] x);
{ n=x.Length
S=0;
for (i=0; i<n; i++) S+=x[ i ];
return S;
}
Программа:
int[ ] x={1, 3, 5};
y=M (x); // y=1+3+5=9.
Переменное число параметров
Этот параметр всегда указывается в конце списка. Может совмещаться со значением, ссылкой и выходным.
params int[ ] x
Пример:
static int M(int a, params int[ ] x)
{ n=x. Length;
S=a;
for (i=0; i<n; i++) S+=x [i];
return S;
}
Программа
b=4;
int [ ] z={1, 3, 5};
y=M (b, z); // y=4+1+3+5
Другой пример, что отличает params от параметра массива:
b=4;
a1=2;
a2=3;
a3=4;
y=M (b, a1, a2,a3); // y=4+2+3+4 из-за «a1, a2, a3» этот параметр показывается с переменными числом аргументов
Вместо a1 … можно использовать и одномерные массивы и это количество выйдет в длину параметра!
Перегрузка подпрограмм
С# различает список параметров для п/п с одним и тем же методом, поэтому можно для одной и той же п/п делать разные варианты в зависимости от списка параметров (имеется в виду их число и тип). Это называется перегрузкой п/п.
Пример: п/п для нахождения максимума из а и b разного типа
static int Max(int a, int b)
{ int Z;
if(a>b) Z=a; else Z=b;
return Z;
}
static double Max(double a, double b)
{double Z;
if(a>b) Z=a; else Z=b;
return Z;
}
Здесь перегрузка отличается типами возвращаемого аргумента и типами параметров.
Рекурсия.
П/п – функции можно в теле самой функции вызывать рекурсивно, т.е. вызывать саму себя.
Условие: для избежания зацикливания нужно предусмотреть окончание рекурсии.
Пример: вычислить рекурсией факториал
n:=1*2*3*…n
static long fact(long n)
{
if(n<=1) return 1;
else
return n*fact(n – 1);
Плохо: а) из-за повторных вызовов тратиться время; б) засоряется стэк
Хорошо: очень компактно и изящно.
Обобщённые подпрограммы.
Используются для обращения к ней с любим типом аргумента. Это позволяет не делать перегруженных методов!
1) Объявление подпрограммы
static void sort<T>(ref T[] a)
where T:Icomparable<T>
{int n=a.Length;
a[1]=5;
a[2]=4*a[1];
и т.п.
}
2) В программе выполняется обращение к той программе:
int[] k={4,8,9,13,20};
sort<int>(ref k);
double[] x={8.1,4.5,3.2};
sort<double>(ref x);
Вопрос?: а что делать, если тип возвращаемого значения подпрограммной – функцией должен совпадать с Т
Допускается ли конструкция
static <T> sort<T>…
Можно ли так указывать?
Обработка исключительных ситуаций
Используется в двух случаях:
1) Если нужно перехватить стандартную исключительную ситуацию и:
а) Сделать об этом сообщение своё на экран
б) Обработать эту ситуацию, чтобы программа не остановилась
2) Если нужно в программе сгенерировать свою исключительную ситуацию по условию не предусмотренному стандартными исключительными ситуациями
Исключительная ситуация обрабатывается блоком try по следующему синтаксису: