'

Работа с массивами в C#

Понравилась презентация – покажи это...





Слайд 0

Работа с массивами в C#


Слайд 1

Массивы в С# Массивы в С# с точки зрения синтаксиса практически не отличаются от массивов в С, C++ и Java. Однако внутренне массив в С# устроен как тип, производный от класса System.Array. Формально массив определяется как набор элементов, доступ к которым производится с помощью числового индекса.


Слайд 2

Объявление массива Массивы объявляются путем помещения квадратных скобок ([ ]) после указания типа данных для элементов этого массива.


Слайд 3

// Массив символьных строк с 10 //элементами {0, 1,…, 9} string[] booksOnCOM; booksOnCOM = new string[10]; // Массив символьных строк с 2 //элементами {0, 1} string[] booksOnPLl = new string[2]; // Массив символьных строк из 100 //элементов {О, 1,…, 99} string[] booksOnDotNet = new string[100];


Слайд 4

Такое объявление массива приведет к ошибке компилятора: // При определении массива //фиксированного размера мы обязаны //использовать ключевое слово new int[4] ages = {30, 54, 4, 10}; // Ошибка! Pазмер массива задается при его создании, но не объявлении.


Слайд 5

//Будет автоматически создан массив с //4 элементами. Обратите внимание на //отсутствие ключевого слова new //и на пустые квадратные скобки int[] ages = {20, 22, 23, 0};


Слайд 6

Заполнение массива в С# Заполнить массив можно, перечисляя элементы последовательно в фигурных скобках. А можно использовать для этой цели числовые индексы.


Слайд 7

// Используем последовательное //перечисление элементов массива: string[] firstNames = new string[5] {“Steve”, “Gina”, “Swallow”, “Baldy”, “Gunner”}; // Используем числовые индексы: string[] firstNames = new string[5]; firstNames[0] = “Steve”; firstNames[1] = “Glna”; firstNames[2] = “Swallow”; firstNames[3] = “Baldy”; firstNames[4] = “Gunner”;


Слайд 8

Важное различие между массивами C++ и С# В С# элементам массива автоматически присваиваются значения по умолчанию в зависимости от используемого для них типа данных. Например, для массива целых чисел всем элементам будет изначально присвоено значение 0, для массива объектов — значение NULL и т. д.


Слайд 9

Многомерные массивы Помимо массивов с одним измерением в С# поддерживаются также две основные разновидности многомерных массивов. Первую разновидность многомерных массивов иногда называют “прямоугольным массивом”. Такой тип массива образуется простым сложением нескольких измерений. При этом все строки и столбцы в данном массиве будут одинаковой длины.


Слайд 10

// Прямоугольный многомерный массив int[] myMatrix; myMatrix = new int[6, 6]; // Заполняем массив 6 на 6 for (int i = 0; i < 6; i++) for (int j = 0; j < 6; j++) myMatrix[i, j] = i*j; // Выводим элементы многомерного массива на //системную консоль for (int i = 0 ; i < 6; i++) { for (int j = 0; j < 6; j++) { Console.Write(myMatrix[i, j] +"\t"); } Console. WriteLine(); }


Слайд 11

Результат работы программы


Слайд 12

Второй тип многомерного массива можно назвать “ломаным” (jagged). Такой массив содержит в качестве внутренних элементов некоторое количество внутренних массивов, каждый из которых может иметь свой внутренний уникальный размер.


Слайд 13

// "Ломаный" многомерный массив (массив из // массивов). В нашем случае - это массив // из пяти внутренних массивов разного // размера int[][] myJagArray = new int[5][]: // Создаем "ломаный" массив for (int i = 0; i < myJagArray. Length; i++) { myJagArray[i] = new int[i + 7]; }


Слайд 14

// Выводим каждую строку на системную консоль (как //мы помним, каждому элементу // присваивается значение по умолчанию - в нашем //случае 0) for (int i = 0; i < 5; i++) { Console.Write(“Length of row {0} is {1}:\t”, i, myJagArray[i].Length); for (int j = 0; j < myJagArray[i].Length; j++) { Console.Write(myJagArray[i][j] + " "); } Console.WriteLine(); }


Слайд 15

Результат работы программы


Слайд 16

Базовый класс System.Array Все наиболее важные различия между массивами в C++ и С# происходят оттого, что в С# все массивы являются производными от базового класса System. Array. За счет этого любой массив в С# наследует большое количество полезных методов и свойств, которые сильно упрощают работу программиста.


Слайд 17

Таблица Член класса Назначение BinarySearch() Этот статический метод можно использовать только тогда, когда массив реали- зует интерфейс IComparer, в этом случае метод позволяет найти элемент массива. Clear() Этот статический метод позволяет очистить диапазон


Слайд 18

элементов (числовые элементы приобретут значения 0, а ссылки на на объекты – null) CopyTo() Используется для копирования элементов из исходного массива в массив назначения GetEnumerato() Возвращает интерфейс IEnumerator для указанного массива.


Слайд 19

GetLengt().Lenght Метод GetLength() используется для определения количества элементов в указанном измерении массива. Length - это свойство только для чтения, с помощью которого можно получить количество элементов массива GetLowerBound() Эти методы используются GetUpperBound() для определения верхней и нижней границы


Слайд 20

выбранного вами измерения массива. GetValue() Возвращает или SetValue() устанавливает значение указанного индекса для массива. Этот метод перегружен для нормальной работы как с одномерными, так и с многомерными массивами Reverse() Этот статический метод позволяет расставить


Слайд 21

элементы одномерного массива в обратном порядке. Sort() Сортирует одномерный массив встроенных типов данных. Если элементы массива поддерживают интерфейс IComparer, то с помощью этого метода вы сможете производить сортировку и ваших пользовательских типов данных.


Слайд 22

Пример // Создаем несколько массивов символьных // строк и экспериментируем с членами // System.Array class Arrays { public static int Main(string[] args) { // Массив символьных строк string[] firstNames - new string[5] {“Steve”, “Gina”, “Swallow”, “Baldy”, “Gunner”}


Слайд 23

// Выводим имена в соответствии с порядком // элементов в массиве Console. WriteLine(“Here is the array:”); for (int i = 0; i < firstNames. Length; i++) Console. Write(firstNames[i] + "\t"); // Расставляем элементы в обратном порядке //при помощи статического // метода Reverse()


Слайд 24

Array.Reverse(firstNames ); // ...и снова выводим имена Console. WriteLine(“Here is the array once reversed:”); for (int i = 0; i < firstNames.Length; i++) Console. Write(firstNames[i] + “\t”); // А теперь вычищаем всех, кроне юного // Гуннара Console.WriteLine(“Cleared out all but one...”); Array. Clear(firstNames. 1, 4);


Слайд 25

for (int i = 0; i < firstNames. Length: i++) { Console. Write(firstNames[i] + "\t\n"); } return 0; } }


Слайд 26

Результат программы


Слайд 27

Работа со строками в С#


Слайд 28

Строки в С# String (строки Unicode) — это встроенный тип данных С#. Все строки в мире С# и .NET происходят от единственного базового класса — System.String. System.String обеспечивает множество методов, которые призваны выполнить за вас всю черновую работу: возвратить количество символов в строке, найти подстроки, преобразовать все символы в строчные или прописные и т. д.


Слайд 29

Таблица Член класса Назначение Length Это свойство возвращает длину указанной строки. Concat() Этот статический метод класса String возвращает новую строку, “склеенную” из двух исходных. CompareTo() Сравнивает две строки.


Слайд 30

Сору() Этот статический метод создает новую копию существующей строки Format() Используется для форматирования строки с использованием других примитивов (числовых данных, других строк) и подстановочных выражений вида {0}. Insert() Используется для вставки строки внутрь существующей.


Слайд 31

PadLeft() Эти методы позволяют заполнить PadRight() (“набить”) строку указанными символами. Remove() Эти методы позволяют создать Replace() копию строки с внесенными изменениями (удаленными или замененными символами) ToUpper() Эти методы используются для ToLower() получения копии строки, в которой все символы станут строчными или прописными.


Слайд 32

Обратить внимание Хотя string — это ссылочный тип данных, при использовании операторов равенства (== и !=) происходит сравнение значений строковых объектов, а не адресов этих объектов в оперативной памяти. Оператор сложения (+) в С# перегружен таким образом, что при применении к строковым объектам он вызывает метод Concat().


Слайд 33

Управляющие последоватльности В С#, как и в С, и в C++, и в Java строки могут содержать любое количество управляющих последовательностей (escape characters).


Слайд 34

Пример // Применение управляющих //последовательностей - \t, \\, \n и прочих string anotherString; anotherString = “Every programming book need \“Hello World\””; Console.WriteLine("\t" + anotherString); anotherString = “c:\\CSharpProjects\\Strings\\string.cs”; Console.WriteLine(“\t” + anotherString);


Слайд 35

Таблица Управляющие Назначение посл-ти \ Вставить одинарную кавычку в строку \” Вставить двойную кавычку в строку \\ Вставить в строку обратный слэш. Особенно полезно при работе с путями в файловой системе.


Слайд 36

\a Запустить системное оповещение (Alert). \b Вернуться на одну позицию (Backspace). \f Начать следующую страницу (Form feed). \n Вставить новую строку (New line). \r Вставить возврат каретки (carnage Return). \t Вставить горизонтальный символ табуляции (horizontal Tab).


Слайд 37

\u Вставить символ Unicode. \v Вставить вертикальный символ табуляции (Vertical tab). \0 Представляет пустой символ (NULL)


Слайд 38

Помимо управляющих последовательностей, в С# предусмотрен также специальный префикс @ для дословного вывода строк вне зависимости от наличия в них управляющих последовательностей. Строки с этим префиксом называются “дословными” (verbatim strings). Это — очень удобное средство во многих ситуациях: // Префикс @ отключает обработку // управляющих последовательностей string finalString - @"\n\tString file: 'C:\CSnarpProjects\Strings\string.cs'"; Console.WriteLine(finalString); Вывод служебных символов


Слайд 39

Применение System.Text.StringBuilder При работе со строками в С# необходимо помнить очень важную вещь: значение строки не может быть изменено. Все методы, казалось бы, изменяющие строку, на самом деле лишь возвращают её измененную копию.


Слайд 40

Пример // Вносим изменения в строку? На самом деле // нет... System.String strFixed = "This is how I began life"; Console.WriteLine(strFixed); string upperVersion = strFixed.ToUpper(); // Возвращает "прописную" копию strFixed Console.WriteLine(strFixed); Console.WriteLine(upperVersion);


Слайд 41

Работа с копиями копий может надоесть. Поэтому в С# существует класс, позволяющий изменять строки напрямую – это класс StringBuilder, определенный в пространстве имен System.Text. Он во многом напоминает CString в MFC. Все изменения, которые вы вносите в объект этого класса, немедленно в нем отражаются, что во многих ситуациях гораздо эффективнее, чем работать с множеством копий.


Слайд 42

// Демонстрирует применение класса StringBullder using System; using System.Text; // Здесь живет StringBuilder! class StringApp { public static int Main(stnng[] args) { // Создаем объект StringBuilder и изменяем его //содержимое StringBuilder myBuffer = new StringBuilder(“I am a buffer”); myBuffer.Append(“ that just got longer...”); Console.WriteLine(myBuffer ); return 0; } }


Слайд 43

Помимо добавления класс StringBuilder допускает и другие операции, например удаление определенных символов или их замену. После того как вы добились нужного вам результата, часто бывает удобным вызвать метод ToString( ), чтобы перевести содержимое объекта StringBuilder в обычный тип данных String.


Слайд 44

using System; using System.Text; class StringApp { public static int Main(string[] args) { StringBuilder myBuffer = new StringBuilder(“I am a buffer”); myBuffer.Append(" that just got longer..."); Console.WriteLine(myBuffer) ; myBuffer.Append(“and even longer.”); Console. WriteLine(myBuffer); // Делаем все буквы прописными string theReallyFinalString = myBuffer.ToString(). ToUpper(); Console.WriteLine(theReallyFinalString); return 0; } }


Слайд 45

Перечисления в С#


Слайд 46

Часто бывает удобным создать набор значимых имен, которые будут представлять числовые значения. // Создаем перечисление enum EmpType { Manager, // = О Grunt, // = 1 Contractor, // = 2 VP // = 3 }


Слайд 47

// Элементы перечисления могут иметь // произвольные числовые значения enum EmpType { Manager = 10, Grunt = 1, Contractor = 100, VP = 99 }


Слайд 48

При компиляции, компилятор попросту подставляет вместо элементов перечисления соответствующие числовые значения. По умолчанию для этих числовых значений компилятор использует тип данных Int. Однако ничто не мешает явным образом объявить компилятору, что следует использовать другой тип данных, например, byte.


Слайд 49

// Вместо элементов перечисления будут // подставляться числовые значения типа byte enum EmpType : byte { Manager = 10, Grunt = 1, Contractor = 100, VP = 9 } Точно таким же образом можно использовать любой из основных целочисленных типов данных С#(byte, sbyte, short, ushort, int, uint, long, ulong).


Слайд 50

Базовый класс System.Enum Все перечисления в С# происходят от единого базового класса System.Enum. Конечно же, в этом базовом классе предусмотрены методы, которые могут существенно облегчить работу с перечислениями.


Слайд 51

GetUnderlyingType ( ) Это статический метод, который позволяет получить информацию о том, какой тип данных используется для представления числовых значений элементов перечисления: // Получаем тип числовых данных // перечисления (в нашем примере это будет // System. Byte) Console.WriteLine(Enum. GetUnderlyingType(typeof(EmpType)));


Слайд 52

Enum.Format ( ) Статический метод, который может получать значимые имена элементов перечисления по их числовым значениям. В нашем примере переменной типа EmpType соответствовало имя элемента перечисления Contractor (то есть эта переменная разрешалась в числовое значение 100). Для того чтобы узнать, какому элементу переменной соответствует это числовое значение, необходимо вызвать метод Enum.Format, указать тип перечисления


Слайд 53

числовое значение (в нашем случае через переменную) и флаг форматирования (в нашем случае — G, что означает вывести как тип string) // Этот код должен вывести на системную // консоль строку "You are a Contractor EmpType fred; fred = EmpType.Contractor; Console.WriteLine(“You are a {0}”, Enum. Format (typeof( EmpType), fred, "G"));


Слайд 54

GetValues() Статический метод, который возвращает экземпляр System.Array, при этом каждому элементу массива будет соответствовать член указанного перечисления. // Получаем информацию о количестве // элементов в перечислении Array obj = Enum.GetValues(typeof(EmpType)); Console. WriteLine(“This enum has {0} members.”, obj.Length);


Слайд 55

// А теперь выводим имена элементов // перечисления в формате string и // соответствующие им числовые значения foreach(EmpType e in obj) { Console. Write("String name: {0}“, Enum. Format (typeof (EmpType), e, "G")); Console. Write(" ({0})“, Enum. Format(typeof( EmpType), e, "D")); Console. Write(" hex: {0}\n“, Enum. Format ( typeof (EmpType), e, "X")); }


Слайд 56

Результат работы программы


Слайд 57

IsDefined Свойство класса System.Enum, которое позволяет определить, является ли выбранная вами символьная строка элементом указанного перечисления. Например, предположим, что требуется узнать, является ли значение Salesperson элементом перечисления EmpType.


Слайд 58

// Есть ли в EmpType элемент // Salesperson? if (Enum. IsDefined(typeof (EmpType). "Salesperson")) Console. WrlteLine(“Yes, we have sales people.”); else Console. WriteLine(“No, we have no profits...”);


Слайд 59

Перечисления С# поддерживают работу с большим количеством перегруженных операторов, которые могут выполнять различные операции с числовыми значениями переменных. // Какому из этих двух переменных-членов // перечисления соответствует большее числовое // значение? EmpType Joe = EmpType. VP: EmpType Fran = EmpType. Grunt; if (Joe < Fran) Console. WrlteLine(“Joe's value is less than Fran's”); else Console. WnteLine(“Fran's value is less than Joe's”);


Слайд 60

Структуры в С#


Слайд 61

Определение структур в С# Cтруктуры С# можно рассматривать как некую особую разновидность классов. Для структур можно определять конструкторы (только принимающие параметры). Структуры могут реализовывать интерфейсы.


Слайд 62

Структуры могут содержать любое количество внутренних членов. Для структур С# не существует единого базового класса (тип System.Structure в С# не предусмотрен). Косвенно все структуры являются производными от типа ValueType.


Слайд 63

Пример // Вначале нам потребуется наше // перечисление enum EmpType : byte { Manager = 10, Grunt = 1, Contractor = 100, VP = 9 } struct EMPLOYEE {


Слайд 64

public EmpType title; // Одно из полей структуры - // перечисление, определенное выше public string name; public short deptID; } class StructTester { public static int Main(string[] args) { // Создаем и присваиваем значения Фреду EMPLOYEE fred; fred.deptID = 40; fred.name = "Fred"; fred.title = EmpType.Grunt; return 0; } }


Слайд 65

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


Слайд 66

Все ваши конструкторы обязательно должны принимать один или несколько параметров. // Для структур можно определить // конструкторы, но все они должны // принимать параметры struct EMPLOYEE { // Поля public EmpType title;


Слайд 67

public string name; public short deptID; // Конструктор public EMPLOYEE (EmpType et, string n, short d) { title = et; name = n; deptID = d; } }


Слайд 68

При помощи такого определения структуры, в котором предусмотрен конструктор, вы можете создавать новых сотрудников следующим образом: class StructTester { // Создаем Мэри и присваиваем ей //значения при помощи конструктора public static int Main(string[] args)


Слайд 69

{ // Для вызова нашего // конструктора мы обязаны // использовать ключевое слово // new EMPLOYEE mary = new EMPLOYEE(EmpType.VP, “Mary”, 10); return 0; } }


Слайд 70

Cтруктуры могут быть использованы в качестве принимаемых и возвращаемых методами параметров.


Слайд 71

Упаковка и распаковка Упаковка и распаковка — это наиболее удобный способ преобразования структурного типа в ссылочный, и наоборот. Основное назначение структур — возможность получения некоторых преимуществ объектной ориентации, но при более высокой производительности за счет размещения в стеке.


Слайд 72

Чтобы преобразовать структуру в ссылку на объект, необходимо упаковать ее экземпляр: // Создаем и упаковываем нового // сотрудника EMPLOYEE Stan = new EMPLOYEE(EmpType.Grunt, “Stan”, 10); object stanInBox = stan; //stanInBox относится к ссылочным типам // данных, но при этом сохраняет //внутренние значения исходного типа // данных EMPLOYEE


Слайд 73

Можно использовать stan во всех случаях, когда нужен объект, и при необходимости производить распаковку: //Поскольку мы ранее произвели //упаковку данных, мы можем //распаковать их и производить операции //с содержимым public void UnboxThisEmployee(object о)


Слайд 74

{ // Производим распаковку в структуру // EMPLOYEE для получения доступа // ко всем полям EMPLOYEE temp = (EMPLOYEE)o; Console.WriteLine(temp.name +“is alive!”); }


Слайд 75

Вызов этого метода может выглядеть следующим образом: // Передаем упакованного сотрудника на // обработку t.UnboxThisEmployee(stanInBox); Компилятор С# при необходимости автоматически производит упаковку. Поэтому допускается передать объект stan (типа EMPLOYEE) напрямую: // Stan будет упакован автоматически t.UnboxThisEmployee(stan);


Слайд 76

Пользовательские пространства имен в С#


Слайд 77

Определение пользовательских пространств имен Часто бывает очень полезным сгруппировать используемые в приложении типы данных в специально созданные для этой цели пространства имен. В С# эта операция производится при помощи ключевого слова namespace.


Слайд 78

Пример // shapeslib.cs namespace MyShapes { using System; // Класс Circle public class Circle { // Интересные методы }


Слайд 79

public class Hexagon // Класс Hexagon { // Более интересные методы } public class Square // Класс Square { // Еще более интересные методы } }


Слайд 80

Пространство имен MyShapes действует как контейнер для всех этих типов. Можно разбить единое пространство имен С# на несколько физических файлов. Для этого достаточно просто определить в разных файлах одно и то же пространство имен и поместить в него определения классов.


Слайд 81

// circle.cs namespace MyShapes { using System; // Класс Circle class Circle { // Интересные методы } } Подобным образом определяются hexagon.cs и square.cs.


Слайд 82

Если потребуется использовать эти классы внутри другого приложения, удобнее всего это сделать при помощи ключевого слова using: namespace MyApp { using System; using MyShapes; class ShapeTester {


Слайд 83

public static void Main() { // Все эти объекты были определены // в пространстве имен MyShapes Hexagon h = new Hexagon(); Circle с = new Circle(); Square s = new Square(); } } }


Слайд 84

Применение пространств имен для разрешения конфликтов между именами классов Пространства имен могут быть использованы для разрешения конфликтов между именами объектов в тех ситуациях, когда в нашем приложении используются разные объекты с одинаковыми именами.


Слайд 85

// Еще одно пространство имен для // геометрических фигур namespace My3DShapes { using System; // Класс 3D Circle class Circle{} // Класс 3D Hexagon class Hexagon{} // Класс 30 Square class Square{} }


Слайд 86

// В коде есть двусмысленность! namespace MyApp { using System: using MyShapes; using My3DShapes: class ShapeTester { public static void Main() { // Неизвестно, к объектам какого пространства имен мы //обращаемся Hexagon h = new Hexagon(); Circle с = new Circle(); Square s = new Square(); } } }


Слайд 87

Проще всего избавиться от подобных конфликтов, указав для каждого класса его полное имя вместе с именем соответствующего пространства имен: // Конфликтов больше нет public static void Main() { My3DShapes.Hexagon h = new My3DShapes.Hexagon(); My3DShapes.Circle с = new My3DShapes.Circle(); My3DShapes.Square s = new MyShapes.Square(); }


Слайд 88

Использование псевдонимов для имен классов Еще одна возможность избавиться от конфликтов имен — использовать для имен классов псевдонимы. namespace MyApp { using System; using MyShapes: using My3DShapes;


Слайд 89

// Создаем псевдоним для класса из // другого пространства имен using The3DHexagon = My3DShapes. Hexagon ; class ShapeTester { public static void Main() { Hexagon h = new Hexagon(); Circle с = new Circle(); Square s = new Square();


Слайд 90

// Создаем объект при помощи // псевдонима The3DHexagon h2 = new The3DHexagon(); } } }


Слайд 91

Вложенные пространства имен Можно без каких-либо ограничений вкладывать одни пространства имен в другие. Такой подход очень часто используется в библиотеках базовых классов .NET для организации типов.


Слайд 92

Пример // Классы для геометрических фигур // расположены в пространстве имен // Chapter2Types.My3DShapes namespace Chapter2Types { namespace My3DShapes { using System;


Слайд 93

// Класс 3D Circle class Circle{} // Класс 3D Hexagon class Hexagon{} // Класс 30 Square class Squared } }


Слайд 94

Конец!!!


×

HTML:





Ссылка: