184
МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ЗАНЯТИЯМ И САМОСТОЯТЕЛЬНОЙ РАБОТЕ ПО УЧЕБНОМУ ПРЕДМЕТУ ОП.11 Объектно-ориентированное моделирование (индекс и наименование учебной дисциплины) 09.02.04 Информационные системы (по отраслям) (код и наименование специальности) Квалификация выпускника Техник по информационным системам (наименование квалификации) Уровень базового образования обучающихся основное общее образование Воронеж 2018

МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ЗАНЯТИЯМ И САМОСТОЯТЕЛЬНОЙ РАБОТЕ

ПО УЧЕБНОМУ ПРЕДМЕТУ

ОП.11 Объектно-ориентированное моделирование (индекс и наименование учебной дисциплины)

09.02.04 Информационные системы (по отраслям) (код и наименование специальности)

Квалификация выпускника Техник по информационным системам

(наименование квалификации)

Уровень базового образования обучающихся – основное общее образование

Воронеж 2018

Page 2: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

3

Оглавление ГЛАВА 1. ОСНОВЫ ЯЗЫКА .................................................... 6

1.1 Основные понятия .......................................................... 6 1.1.1 Состав языка. ............................................................ 6 1.1.2 Типы данных ............................................................ 12 1.1.3 Преобразование встроенных типов данных .......... 16 1.1.4 Контрольные вопросы .............................................. 18

1.2 Переменные, константы, операции ................................ 19 1.2.1 Переменные ............................................................... 19 1.2.2 Константы ................................................................. 21 1.2.3 Простейшие операции ввода/вывода ..................... 24 1.2.4 Операции и выражения ............................................ 25 1.2.4 Математические функции ....................................... 33

1.3 Контрольные вопросы ..................................................... 35 1.4 Лабораторная работа №1 ............................................... 35

ГЛАВА 2. ОСНОВНЫЕ АЛГОРИТМИЧЕСКИЕ КОНСТРУКЦИИ ........................................................................ 37

2.1. Операторы ........................................................................ 37 2.1.1 Операторы ветвления ............................................... 37 2.1.2 Операторы цикла ...................................................... 41 2.1.3 Операторы передачи управления ........................... 46 2.1.4 Контрольные вопросы ............................................. 50

2.2 Обработка исключительных ситуаций ......................... 50 2.2.1 Понятие исключения и основные способы его обработки ............................................................................. 50 2.2.2 Оператор обнаружения и обработки исключений . . . 52 2.2.3 Защищенный код ...................................................... 56 2.2.4 Программирование под Windows: форма, кнопка, .. 57 текстовое поле ..................................................................... 57 2.2.5 Диалоговые окна и сообщения об ошибке в приложениях под Windows ................................................ 67

2.3 Контрольные вопросы .................................................... 69 2.4 Лабораторная работа №2 ............................................... 69

ГЛАВА 3. МАССИВЫ ................................................................ 70 3.1 Одномерный, двумерный и ступенчатый массив .... 70

Page 3: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

4

3.1.1 Понятие массива ................................................... 70 3.1.2 Одномерный массив .............................................. 72 3.1.3 Прямоугольный массив ......................................... 74 3.1.4 Ступенчатый массив .............................................. 77

3.2 Встроенные операторы и классы для работы с массивами 79

3.2.1 Оператор foreach .................................................... 79 3.2.2 Класс System.Array ................................................ 81

3.3 Класс System.Random ............................................... 84 3.4 Программирование под Windows: меню, таблицы, регулятор «вверх-вниз» ........................................................... 86 3.5 Контрольные вопросы ................................................ 93 3.6 Лабораторная работа №3 .......................................... 93 3.7 Лабораторная работа №4 .......................................... 95 ГЛАВА 4. СТРОКИ И СИМВОЛЫ .................................... 97

4.1 Типы данных для хранения текстовой информации ... 97 4.1.1 Символьный тип ....................................................... 97 4.1.2 Массивы символов ................................................. 100 4.1.3 Тип string ................................................................ 101

4.2 Строки типа StringBuilder ......................................... 107 ГЛАВА 5. ФАЙЛЫ ................................................................... 110

5.1 Понятие файла .............................................................. 110 5.2 Работа с файлами .......................................................... 115

5.2.1 Потоки байтов ........................................................ 115 5.2.2 Потоки символов ................................................ 117 5.2.3 Двоичные потоки ................................................. 121

5.3 Работа с каталогами ................................................... 124 5.4 Программирование под Windows: richTextBox, диалоговые окна ................................................................... 128 5.5 Контрольные вопросы ............................................... 135 5.6 Лабораторная работа №5. ......................................... 135

ГЛАВА 6. ПРОСТЕЙШИЕ КЛАССЫ ..................................... 137 6.1 Основные понятия ..................................................... 137 6.2 Реализация класса ...................................................... 139

6.2.1 Описание класса и его спецификаторы ............ 139

Page 4: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

5

6.2.2 Данные класса ..................................................... 140 6.2.3 Методы класса .................................................... 142 6.2.4 Ключевое слово this ........................................... 146 6.2.5 Конструкторы ..................................................... 146 6.2.6 Свойства .............................................................. 149

6.3 Контрольные вопросы ............................................... 151 6.4 Лабораторная работа №6 ......................................... 151

ГЛАВА 7. СТРУКТУРЫ И ПЕРЕЧИСЛЕНИЯ .................... 154 7.1 Структуры .................................................................. 154 7.2 Перечисления ............................................................... 156

7.2.1 Создание и работа с перечислениями ................. 156 7.2.2 Класс System.Enum ............................................... 159

7.3 Контрольные вопросы .................................................... 160 7.4 Лабораторная работа № 7 ........................................ 160

ГЛАВА 8. ПОДРОБНОСТИ О КЛАССАХ ............................ 164 8.1 Реализация полиморфизма в классах .......................... 164 8.2 Рекурсивные методы ................................................... 166 8.3 Индексаторы ................................................................. 167 8.4 Операции класса ....................................................... 170

8.4.1 Общие сведения о перегрузке операций .............. 170 8.4.2 Перегрузка унарных операций .......................... 170 8.4.3 Перегрузка бинарных операций ........................ 172

8.5 Реализация наследования ........................................... 174 8.5.1 Общая информация о наследовании классов ... 174 8.5.2 Виртуальные методы ................................................ 177

8.6 Абстрактные классы...................................................... 179 8.7 Контрольные вопросы .............................................. 181 8.8 Лабораторная работа № 8 ........................................... 181

Используемая литература ....................................................... 184

Page 5: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

6

ГЛАВА 1 ОСНОВЫ ЯЗЫКА 1.1 Основные понятия

1.1.1 Состав языка

Изучение языка программирования можно сравнить с изучением любого иностранного языка, который имеет свои правила, жесткие принципы и способы построения фраз. Поэтому изучение языка C# следует начинать аналогично изучению иностранного языка: от алфавита к возможности выражать свои мысли с помощью языка (рис.1.1)

Рис 1.1 Состав языка C#

Все тексты языка пишутся с помощью его алфавита. Алфавит языка включает в себя:

1. Буквы (латинские и буквы национальных алфавитов) и символ подчеркивания (_), который приравнивается к буквенным символам. В С# используется кодировка символов UNICODE. Универсальный набор символов задаёт однозначное соответствие символов кодам — элементам кодового пространства, представляющим неотрицательные целые числа. Коды в стандарте Юникод разделены на несколько областей. Область с кодами от U+0000 до U+007F содержит символы набора ASCII с соответствующими кодами. Далее расположены области знаков различных письменностей, знаки пунктуации и технические символы. Часть кодов зарезервирована для использования в будущем. Под символы кириллицы выделены области знаков с кодами от

Page 6: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

7

U+0400 до U+052F, от U+2DE0 до U+2DFF, от U+A640 до U+A69F [1]. Использование символов национальных алфавитов делает программный код более удобным для чтения и редактирования.

2. Цифры. 3. Специальные символы. 4. Пробел и знаки табуляции. 5. Символы перевода строки.

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

Директива препроцессора - это наследия языка C++, перешедшее в язык C#. Под препроцессором понимается здесь начальная стадия компиляции. Директивы позволяют про-граммисту повлиять на процесс компиляции, «включив» или «выключив» части программного кода. Основные директивы препроцессора представлены в таблице 1.1

Таблица 1.1 Наиболее используемые директивы препроцессора Директива Пояснение

#endif компиляция кода между двумя директивами выполняется только в том случае, еслиопределен указанный символ

#else позволяет создать сложную условную ди-рективу

#unde f позволяет отменить определение символа,который, при его использовании в качествевыражения, переданного директиве #if

#define позволяет определить символ.#warning позволяет создавать предупреждение из

определенного места в коде #error позволяет создавать ошибку из определен-

ного места в коде

Page 7: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

8

#region#endregion позволяет указать блок кода, который можно

разворачивать и сворачивать с помощью функции структурирования в редакторе кода

Комментарии предназначены для записи пояснений к программе. Правильно оформленные комментарии игнорируются компилятором, то есть эта часть программного кода доступна только программисту для отладки и пояснений. Комментарии в языке C# бывают двух видов: однострочные и многострочные. Однострочные комментарии при записи начинаются с двух косых черт (//) и заканчиваются символом перехода на новую строку. Многострочные комментарии начинаются с последовательности символов вида /* и заканчиваются последовательностью символов */. Все символы, расположенные между началом и завершением комментария не анализируются компилятором и не участвуют в процессе сборки программы. Особый вид комментариев в языке - комментарии, начинающиеся с трех косых черт (///). Данный вид комментариев позволяет форматировать документацию к программе в формате XML. Компилятор извлекает данные комментарии из программного кода, проверяет их корректность и записывает в отдельный файл.

Лексема - это минимальная значащая единица языка. Проводя аналогию между языком программирования и естест-венным языком, можно сказать, что лексема - это аналог слова естественного языка. Можно выделить следующие виды лексем:

1. Идентификаторы, 2. ключевые слова, 3. знаки операций, 4. разделители, 5. константы.

В C# идентификатор представляет собой имя, присваи-ваемое методу, переменной или любому другому определяе

Page 8: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

9

мому пользователем элементу программы. Рассмотрим основные принципы задания идентификатора:

1. первым символом идентификатора может быть буква, знак подчеркивания, но не цифра;

2. длина идентификатора не ограничена; 3. пробелы внутри имени идентификатора не допускают

ся; 4. язык C# является чувствительным к регистру (иденти-

фикаторы XYZ, xyz, Xyz - это три разных имени); 5. в языке C# помимо латинских символов разрешено ис-

пользовать кириллицу; 6. идентификатор не должен совпадать с ключевыми сло-

вами (полный список ключевых слов приведен в таблице 3);

7. для облегчения работы с программным кодом рекомен-дуется создавать осмысленные идентификаторы, которые помогают понять назначение переменной, метода или класса.

Понятные и согласованные с логикой идентификаторы - это признак хорошего стиля программирования. Существует несколько нотаций - правил задания идентификаторов. Нотации и созданные по их правилам идентификаторы приведены в таблице 1.2.

Таблица 1.2 Нотации для задания идентификаторов Нотация Правила задания Пример иденти-

фикатора Нотация Паскаля Каждое слово, входящее

в название иден-тификатора, начинаетсяс большой буквы

MaxLengthMyFirstWord

Венгерская но-тация

Идентификатор начи-нается с префикса, со-ответствующего типу

iMaxLength sMyFirstWord

Page 9: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

10

величины. Дальнейшееопределение со-ответствует нотацииПаскаля

Нотация Camel В данной нотации спрописной буквы на-чинается каждое слово,кроме первого

maxLengthmyFirstWord

Помимо вышеназванных нотаций существует традиция разделять слова, составляющие идентификатор, знаками ниж-него подчеркивания, начиная каждое слово с маленькой буквы (например, max_length, my_first_word).

Использование единой нотации задания идентификато - ров является основой хорошего стиля программирования.

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

Таблица 1.3 Ключевые слова языка abstract as base bool break explicit case catch char checked class const continue decimal default delegate do double else enum event byte extern false finally fixed float for foreach goto implicit if switch interface params

internal is lock namespace long typeof null obj ect operator outoverride int private protected public readonly ref return sbyte sealed

Page 10: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

11

stackalloc try short static string struct in this throw true sizeof new ushort unchecked ulong unsafe uint using virtual volatile void while

Помимо указанных ключевых слов выделим 13 контек - стных ключевых слов, представленных в табл. 1.4, которые имеют значение в определенном контексте. Они могут быть использованы в качестве имен переменных, однако этого делать не рекомендуются для избегания путаницы в программном коде.

Таблица 1.4 Контекстные ключевые слова from get group into join let orderby partial select set value where yield

Знаки операций и разделители - еще один вид лексем. Под знаками операций и разделителями будем понимать один или более символов, определяющих действие над операндами. Внутри знака операции пробелы и иные разделители не до-пускаются. Разделители используются для разделения или группировки элементов.

Далее приведен полный список разделителей в языке C#: { } [ ] ( ) . , : ; + - * / % & | Л ! ~ = < > ? ++ -- && || « » — != <= >= += -= *= /= °%= &= |= л= <<= >> = - >.

Константы так же являются лексемами. Более подробно о константах рассказывается в разделе 1.2.2 главы 1.

Из лексем составляются сложные конструкции языка - выражения и операторы. Выражение - это правило вычисления некоторого значения. Оператор задает законченное описа

Page 11: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

12

ние некоторого действия. Более подробно выражения и опера-торы рассмотрены в разделе 1.2.4 главы 1.

1.1.2 Типы данных

Типы данных имеют особенное значение в C#, поскольку это строго типизированный язык. Это означает, что все операции подвергаются строгому контролю со стороны компилятора на соответствие типов, причем недопустимые операции не компилируются. Следовательно, строгий контроль типов позволяет исключить ошибки и повысить надежность программ. Для обеспечения контроля типов все переменные, выражения и значения должны принадлежать к определенному типу.

Тип данных однозначно определяет внутреннее пред-ставление данных, множество допустимых значений и допус-тимые действия над данными.

Компилятор использует информацию о типе при проверке допустимости описанных в программе действий.

Типы данных языка C# классифицируются по способу хранения элементов на типы-значения и ссылочные типы. Ти-пы-значения представляют собой последовательность битов в памяти, необходимый объем определяется компилятором. Ве-личина ссылочного типа хранит не сами данные, а ссылку на них.

Типы- значения в свою очередь подразделяются на: 1. целочисленные типы, 2. типы с плавающей запятой, 3. символы, 4. логический тип, 5. финансовый тип. В С # определены 8 целочисленных типов: byte, sbyte,

short, ushort, int, uint, long и ulong. Все целочисленные типы подразделяются на знаковые и беззнако-вые. Старший бит числа интерпретируется как знаковый. Чис

Page 12: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

13

ло считается положительным, если флаг знака равен 0, и отри-цательным, если он равен 1. Целочисленные типы и диапазон допустимых значений представлен в таблице 1.5.

Таблица 1.5 Целочисленные типы языка

Тип Тип CTS

Разряд ность в битах

Диапазон

byte System.Byte 8 0:255sbyte System.SByte 8 -128:127 short System.Int16 16 -32768 : 32767ushor t

System.UIntl6 16 0:65535

int System.Int32 32 -2147483648 : 2147483647

uint System.UInt32 32 0 : 4294967295

long System.Int64 64 -9223372036854775808 : 9223372036854775807

ulong System.UInt64 64 0:18446744073709551615

Самым распространенным в программировании цело-численным типом является тип int. Переменные типа int используются для управления циклами, индексирования массивов и математических расчетов общего назначения. Когда же требуется целочисленное значение с большим диапазоном представления чисел, чем у типа int, то для этой цели имеется целый ряд других целочисленных типов. Если значение нужно сохранить без знака, то для него можно выбрать тип uint, для больших значений со знаком — тип long, а для больших значений без знака — тип ulong.

Вещественные типы хранятся в памяти иначе, чем це-лочисленные. Внутреннее представление вещественного числа состоит из двух частей: мантиссы и порядка. Длина мантиссы

Page 13: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

14

определяет точность числа, а длина порядка - диапазон. В C# имеются две разновидности типов данных с плавающей точкой: float и double. Они представляют числовые значения с одинарной и двойной точностью соответственно. Так, разряд-ность типа float составляет 32 бита, что соответствует диа-пазону чисел от 5E-45 до 3,4E+38. А разрядность типа double составляет 64 бита, что соответствует диапазону чисел от 5E- 324 до 1,7Е+308.

Тип данных float предназначен для меньших значений с плавающей точкой, для которых требуется меньшая точность. Тип данных double больше, чем float, и предлагает более высокую степень точности (15 разрядов).

Чаще всего в программах используется тип double, ко-торый позволяет решать большинство задач, поставленных перед программистом.

Если ошибки округления критичны, то следует исполь-зовать тип, предназначенный для денежных вычислений - тип decimal. Величины типа decimal хранят до 29 десятичных разрядов (для сравнения, тип float хранит до 7 разрядов, тип double - до 16). Не смотря на внешнюю схожесть типа decimal с вещественными типами, их внутреннее представление различно.

Вещественные, финансовые и целочисленные типы данных могут содержать суффиксы, которые позволяют в явном виде сообщить компилятору о том объеме памяти, который должен быть выделен. Язык C# позволяет использовать следующие суффиксы:

• L, l - длинное целое (long), • U, и - беззнаковое целое (unsigned), • F, f - вещественное с одинарной точностью (float), • D, d - вещественное с двойной точностью (double), • M, m - финансовое десятичного типа (decimal).

Для всех названных типов данных встроенная библиотека C# определяет набор стандартных методов и полей. С их

Page 14: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

15

помощью можно получить максимальное, минимальное значение для каждого типа (например, double.MaxValue и int.MinValue), преобразовать число в соответствующее строковое представление c помощью метода ToString() и т.д.

Помимо типов , хранящих числовые значения , к типам - значениям относят логический тип данных. Тип bool (логи-ческий тип) принимает одно из двух возможных значений, со-относящихся с зарезервированными словами “true” и “false”. Помимо зарезервированных слов для работы с логическим типом можно использовать числовые значения. В этом случае 1 будет соответствовать истинному значению, 0 - ложному.

Символьному типу в C# соответствует зарезервированное слово char. Для хранения одного символа, представленного, как было сказано ранее, в кодировке UNICODE выделяется 16 бит. Символьный тип предназначен чаще всего дня хранения одного символа, заключенного в апострофы, например, к символьному типу относят ‘z', ‘x' и т.д.

Ссылочные типы делятся на объекты и строки. Строки, в отличие от символьного типа, используются для хранения последовательности символов. В данном случае, показателем строкового типа данных будет ключевое слово string, а сама хранимая строка заключается в кавычки, например, «Привет». Строка представляет собой одномерный массив, попускает работу с символами строки, как с элементами массива. Подробнее строковый тип данных рассмотрен в разделе 4.3.1 главы 4.

В C# предусмотрен специальный тип данных object, который неявно считается базовым классом для всех остальных классов и типов, включая и типы значений. Иными словами, все остальные типы являются производными от object. Это, в частности, означает, что переменная ссылочного типа object может ссылаться на объект любого другого типа. Можно сказать, что тип object имеет возможность хранить данные произвольных типов.

Page 15: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

16

Помимо вышеназванных типов данных существуют пользовательские типы данных, например массивы, структуры, перечисления, классы, интерфейсы, делегаты. Подробнее данные типы данных рассмотрены в главах 3, 6, 7.

1.1.3 Преобразование встроенных типов данных

При вычислении выражений может возникнуть проблема совместимости типов данных или появиться вопрос о возмож-ности совершения операции над определенным типом данных в принципе.

Здесь следует помнить несколько важных правил. 1. Если операнды, входящие в выражение, одного типа и

операция для этого типа определена, то результат вы-ражения будет иметь тот же тип.

2. Если операнды разного типа и/или операция для этого типа не определена, то перед вычислением будет проведено автоматическое преобразование типов данных по правилу: от более коротких типов к более длинным для сохранения точности.

3. Если неявного преобразования одного типа в другой не существует, то необходимо задать явное преобразование типов с помощью операции совместимости типов.

Операция явного преобразования типов имеет вид: (тип) выражение

Здесь тип - имя того типа, в который осуществляется преобразование, выражение чаще всего представляется как имя переменной. В данном случае, используя операцию явного преобразования типа, программист сообщает компилятору, что он берет на себя все возможные последствия, связанные с потерей точности информации. Общая схема, иллюстрирующая приводимость типов, приведена на рис. 1.2.

Page 16: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

17

Рис. 1.2 Приводимость типов данных в C# Если приведение типов приводит к сужающему преобра-

зованию, то часть информации может быть потеряна. Например, в результате приведения типа long к типу int часть информации потеряется, если значение типа long окажется больше диапазона представления чисел для типа int, поскольку старшие разряды этого числового значения отбрасываются. Когда же значение с плавающей точкой приводится к целочисленному, то в результате усечения теряется дробная часть этого числового значения. Так, если присвоить значение 1,23 целочисленной переменной, то в результате в ней останется лишь целая часть исходного числа (1), а дробная его часть (0,23) будет потеряна.

Помимо явного преобразования типов, в языке существует класс, определенный в пространстве имен System. Методы класса Convert поддерживают общий способ выполнения преобразований между типами. Класс Convert содержит 15 статичских методов вида To <Type>(ToBoolean(),.ToUInt64()),

Page 17: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

18

где Type может принимать значения от Boolean до UInt64 для всех встроенных типов

1.1.4 Контрольные вопросы

1. Дайте определение алфавита языка. 2. Что входит в алфавит языка С#? 3. Какая кодировка используется в языке? Назовите ее

преимущества. 4. Каково назначение директив препроцессора? 5. Что такое идентификатор и каковы правила его зада

ния? 6. Укажите НЕВЕРНЫЕ идентификаторы: • Привет;

• 1adk:

• _MyProgram;

• My1program;

• @Period.

7. Приведите классификацию типов данных и назовите основные типы-значения.

8. Зачем необходимо преобразование типов данных?

Page 18: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

19

1.2 Переменные, константы, операции 1.2.1 Переменные

Переменная - это именованная область памяти, которая используется для хранения данных определенного типа. Во время работы программы значение переменной можно изменять. Для того, чтобы объявить переменную в программе используется оператор описания, который имеет следующий вид: Тип переменной имя переменной [= начальное значе-

ние переменной]; Возможности переменной определяются ее типом. Например,

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

Рассмотрим примеры объявления переменных разных типов. int I; // Объявили целочисленную переменную bool OK, Flag; // объявили две логических перемен

ных Язык C# предоставляет возможность инициализировать

переменную при ее объявлении. Для этого после имени переменной указывается знак равенства (=) и присваиваемое значение. Если две или более переменные одного и того же типа объявляются списком, разделяемым запятыми, то этим переменным можно задать, например, начальное значение.

int i = 10; /* задаем целочисленной переменной i значение 10*/

char symb = 'Z'; /*инициализируем переменную symb буквенным значением Z*/

float f = 15.7F; /* переменная f инициализируется числовым значением 15.7 */

Page 19: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

20

int x = 5, y = 10, z = 12; /* инициализируем несколько переменных одного типа*/

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

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

Например, int i =10, b =4; int result = i*b+10;

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

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

Неявно типизированная переменная объявляется с помощью ключевого слова var и должна быть непременно инициализирована. Для определения типа этой переменной компилятору служит тип ее инициализатора, т.е. значения, которым она инициализируется. Например,

var i = 12; /* переменная i инициализируется целочисленным литералом */

var d = 12.3; /* переменная d инициализируется литералом с плавающей точкой, имеющим тип double*/

Page 20: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

21

var f = 0.34F; /* переменная f теперь имеет тип float */

Как только этот тип данных определен, он закрепляется за переменной до конца ее существования.

1.2.2 Константы

Константы, в отличие от переменных, - это неизменяемые величины. Они остаются неизменными в течение всей жизни программы, любая попытка изменить значение константы приведет к ошибке. Язык C# не поддерживает методы, свойства и события с ключевым словом const. Константы обязательно должны быть проинициализированы!

Синтаксис задания констант в языке C# следующий: const Тип данных константы Имя константы = Значение константы;

Например, const int p = 10; const float pi = 3.14, e = 2.57; /* слово const в

данном случае распространяется на обе константы */ Подобно переменным, константы могут быть различных

типов данных. Типы данных констант представлены в табл. 1.6.

Табл. 1.6 Константы языка C# Кон станта

Описание Примеры

Логиче- Может иметь одно из двух значе- true ская ний: true (истина) и false (ложь) false

Целая Два типа целочисленных констант: 8 -десятичная: последовательность 13780 десятичных цифр (0,1 ...9), за кото- 8u рой может следовать суффикс) 0x6

Page 21: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

22

- шестнадцатеричная: символы 0х или0Х, за которыми следуют шест-надцатеричные цифры (0,1 ...9, A, B, C, D, E, F) и суффиксы

0XAu

Вещест венная

Два типа вещественных констант: -константа с фиксированной точкой задается следующим образом: [цифры] [.][цифры] [суффикс] -константа с порядком задается сле-дующим образом: [цифры] [. ] [цифры] {E|e}[+/- ] [цифры] [суффикс]

5.7 .002 5.7F

0.3E7 .11e-4

Сим вольная

Символ, заключенный в апострофы,пустая символьная константа недо-пустима

‘g', ‘\n'

Строко вая

Последовательность символов, за-ключенная в кавычки. Может бытьпустой

“Привет” “С:\temp”

Кон станта null

Ссылка, которая не указывает ни на какой объект

null

Суффиксы, используемые в задании констант, рассмотрены в разделе 1.1.2.

Наиболее интересными константами являются символьные константы. Они могут быть представлены в одной из трех наиболее распространенных возможных форм:

• символ, имеющий графическое представление (кроме апострофа и символа перевода строки),- ‘F', ‘*',

• символ в виде шестнадцатеричного кода начинается с префикса \0x, за которым следует код символа, - ‘\xF',

• управляющая последовательность - ‘\0', ‘\n'. Управляющая последовательность интерпретируется как одиночный символ и используется для представле

Page 22: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

23

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

• Таблица 1.7 Управляющие последовательности языка С#

• вид Комментарий \а Звуковой сигнал\b Возврат на один шаг назад \f Перевод страницы \n Перевод строки\r Возврат каретки \t Г оризонтальная табуляция\v Вертикальная табуляция \\ Обратная косая черта\' Апостроф \” Кавычка \0 Нуль-символ

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

Например, строковая константа следующего вида “Язык программирования С#\пнаше все!” . Эта константа на выводе будет иметь вид

Язык программирования C# наше все! Помимо форматированного вывода управляющие после-

довательности позволяют выводить на экран такие символы, как апостроф, обратная косая черта и кавычки. Например, в примере “Цитаты оформляются кавычками \” “, использование управляющей последовательности дает возможность

Page 23: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

24

компилятору «отличить» кавычки, которые необходимо напечатать на экране от кавычек, которые ограничивают строку.

1.2.3 Простейшие операции ввода/вывода

Любая даже самая простейшая программа при вводе исходных данных или демонстрации результата коммуници- рует с внешними устройствами. К стандартным устройствам ввода/ вывода относят клавиатуру и экран. С точки зрения среды разработки совокупность стандартных устройств представляет собой консоль.

Для обмена данными с консолью используются стандартные объекты ввода/вывода. В частности, в языке определен класс Console в пространстве имен System. Данный класс содержит в себе стандартные методы Write и WriteLine для записи, Read и ReadLine для чтения.

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

Для того, чтобы вывести информацию на экран, используем методы Write (если хотим остаться на этой же строке) и WriteLine (если хотим перейти на новую строку). Все текстовые сообщения, которые выводятся на экран любым из двух предложенных методов, должны заключаться в кавычки! Например,

Console. WriteLine (“Привет!”);

Если необходимо вывести только число, метод WriteLine или Write будет работать корректно, например,

int c = 10; Console. WriteLine (c);

Однако, при возникновении необходимости вывести в одной строке и сообщение, и число, необходимо преобразовать число в строковый тип данных (метод ToString()), а за

Page 24: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

25

тем выполнить конкатенацию полученных строк (оператор +). Например,

int c = 10; Console.WriteLine("Наше чис- ло”+с.ToString()); Для того, чтобы ввести информацию, используются методы

Read и ReadLine. Информация, которая вводится в консоль, имеет строковый тип данных и при необходимости должна быть конвертирована с помощью класса Convert. Например,

string buffer = “”; /*создали пустую строку, для того, чтобы прочитать символы, введенные пользователем с клавиатуры*/

buffer = Console.ReadLine(); // прочитали строку, которую ввел пользователь

int num = 0; // переменная, в которую будет произведена конвертация строки

num = Convert.ToInt32(buffer); /* произвели конвертацию, теперь в программе можно использовать число, введенное пользователем с клавиатуры*/

1.2.4 Операции и выражения

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

По числу участвующих в операции операндов операции можно разделить на унарные, бинарные, тернарные.

По выполняемому действию операции делятся на первичные, мультипликативные, аддитивные, операции сдвига, операции проверки типа, операции отношения, логические, операции присваивания.

Все операции языка C# представлены в таблице 1.8. Таблица

1.8 Операции языка С#

Page 25: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

26

Категория Знак опе-рации

Название Описа ние

Первичные Доступ к элементу Стр.139 Х () Вызов метода или

делегата Стр. 142

Х[] Доступ к элементу Стр.70 Х+ + Постфиксный ин-

кремент Стр.26

Х-- Постфиксный дек-ремент

Стр.26

new Выделение памяти Стр.138 checked Проверяемый код Стр.54 un checked

Непроверяемый код Стр.54

Унарные + Унарный плюс Стр.27 - Унарный минус Стр.27 ! Логическое отрица-

ние Стр.27

~ Поразрядное отри-цание

Стр.27

++х Префиксный ин кремент

Стр.26

--х Префиксный дек-ремент

Стр.26

( тип ) хПреобразование типа

Стр.14

Мультиплика тивные

* Умножение Стр.27 / Деление Стр.27 о Остаток от деления Стр.27

Аддитивные + Сложение Стр.27 - Вычитание Стр.27

Сдвиг < < Сдвиг влево Стр. 29 > > Сдвиг вправо Стр. 29

Page 26: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

27

Логические < Меньше Стр.30 > Больше Стр.30 < = Меньше или равно Стр.30 > = Больше или равно Стр.30 == Равно Стр.30 ! = Не равно Стр.30 & Поразрядная конъ-

юнкция (И) Стр. 31

Поразрядное ис ключающее ИЛИ

Стр. 31

| Поразрядная дизъ-юнкция (ИЛИ)

Стр. 31

&& Логическое И Стр. 31 || Логическое ИЛИ Стр. 31

Условная ? : Условная операция Стр. 31 Присваивание = Присваивание Стр. 26

*= Умножение с при-сваиванием

Стр.26

/ = Деление с присваи-ванием

Стр. 26

О, %=

Остаток от деления сприсваиванием

Стр. 26

+= Сложение с при-сваиванием

Стр. 26

-=

Вычитание с при-сваиванием

Стр. 26

<<= Сдвиг влево с при-сваиванием

Стр. 26

>>= Сдвиг вправо сприсваиванием

Стр. 26

&= Поразрядное И сприсваиванием

Стр. 26

= Поразрядное ис-ключающее ИЛИ с

Стр. 26

Page 27: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

28

присваиванием

|= Поразрядное ИЛИ с присваиванием

Стр. 26

Присваивание. Операции присваивания задают новое значение переменной.

Операция простого присваивания была рассмотрена в п.1.2.1. Механизм сложного присваивания (*=, += и т.д.) аналогично простому присваиванию. Сначала вычисляется выражение, его результат заносится по адресу переменной, которая находится слева от знака присваивания. То, что раньше хранилось по этому адресу, теряется.

То есть, операция, записанная как a*=b, является аналогом более длинной записи a=a*b. Для остальных операций сложного присваивания правила аналогичны приведенному примеру.

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

Инкремент и декремент. Операции инкремента (++) и декремента (--) представляют

собой операции увеличения и уменьшения на единицу. Операции имеют две формы: префиксную и постфиксную. В префиксной форме знак операции записывается перед операндом, в постфиксной - после операнда. Префиксная запись сначала изменяет операнд, значение которого потом становится результатом. Постфиксная запись в качестве результата предоставляет значение операнда, а потом изменяет его значение.

Например, static void Main() {

Page 28: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

29

int x = 5, y=5, z=5, q=5; Console.WriteLine(x++); /*полученный результат -

5*/ Console.WriteLine (y--); /*полученный результат -

5*/ Console.WriteLine (++z); /* полученный результат

-6*/ Console.WriteLine (--q); /* олученный результат -

4*/ } Отрицание. В языке выделяют несколько видов отрицания:

1. арифметическое отрицание (-): знак операнда меняется на противоположный. Операция арифметического отрицания определена не для всех типов данных. Она может быть использована только с типами int, long, float, double, decimal. Для других типов данных операция арифметического отрицания может быть применена только после приведения типов.

2. Логическое отрицание (!) определено для типа bool. Результат операции - значение false, если исходное значение операнда было true и наоборот в обратном случае.

3. Поразрядное отрицание (~) представляет собой по сути побитовое отрицание. Данная операция инвертирует каждый бит операнда. Операция поразрядного отрицания определена для типов int, uint, long, ulong.

Сложение, вычитание, умножение, деление, остаток от деления.

Операция умножения (*) возвращает результат перемножения двух операндов. Стандартная операция умножения определена для типов int, uint, long, ulong, float, double и decimal. К величинам других типов ее можно применять, если для них возможно неявное преобразование к этим типам. Тип результата операции равен «наибольшему» из типов операндов, но не менее int.

Page 29: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

30

Операция деления (/) вычисляет частное от деления первого операнда на второй. Стандартная операция деления определена для типов int,uint, long, ulong, float,double и decimal. К величинам других типов ее можно применять, если для них существует неявное преобразование к этим типам. Тип результата определяется правилами преобразования, но не меньше int. Если оба операнда целочисленные, результат операции, округляется вниз до ближайшего целого числа. Если делитель равен нулю, генерируется исключение.

Если хотя бы один из операндов вещественный, дробная часть результата деления не отбрасывается. Если результат слишком велик для представления с помощью заданного типа, он принимается равным значению «бесконечность», если слишком мал, он принимается за 0.

Операция остатка от деления (%) также интерпретируется по-разному для целых, вещественных величин. Если оба операнда целочисленные, результат операции вычисляется по формуле х - (х / у) * у. Если делитель равен нулю, генерируется исключение. Тип результата операции равен «наибольшему» из типов операндов, но не менее int. Если хотя бы один из операндов вещественный, результат операции вычисляется по формуле х - n * у, где n — наибольшее целое, меньшее или равное результату деления х на у.

Операция сложения (+) возвращает сумму двух операндов. Стандартная операция сложения определена для типов int, uint, long, ulong, float, double и decimal. К величинам других типов ее можно применять, если для них существует неявное преобразование к этим типам. Тип результата операции равен «наибольшему» из типов операндов, но не менее int.

Операция вычитания (-) возвращает разность двух операндов. Стандартная операция вычитания определена для типов int,uint, long, ulong, float, double и decimal. К величинам других типов ее можно применять, если для них

Page 30: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

31

существует неявное преобразование к этим типам. Тип результата операции равен «наибольшему» из типов операндов, но не менее int.

Операции сдвига. Операции сдвига (<<, >>) применяются только к цело-

численным операторам (типы int, uint, long, ulong). Они используют двоичное представление числа и сдвигают его вправо (влево) на количество двоичных разрядов, которые задаются вторым операндом.

Например, static void Main() { int a = 3; /*двоичное представление числа 3

- это 011*/ Console.WriteLine(a<<1); /* после сдвига на один

разряд влево переменная а = 6 ( или 110 в двоичной форме) */ }

При сдвиге вправо и влево освободившиеся разряды об-нуляются.

Логические операции. Логические операции можно условно поделить на несколько

групп. Первая группа - операции отношения (<, >, <=, >=, ==, !=), Данные операции сравнивают первый операнд со вторым. Обязательное условие: операнды должны быть арифметического типа. Результат применения операций отношения - это переменная логического типа, принимающая одно из двух возможных значений (true, false). Основные операции отношения приведены в табл. 1.9.

Таблица 1.9 Операции отношения в языке C# Операция Результат x

yИстина, если х равно у, иначе - ложь

X ! =y Истина, если х не равно у, иначе - ложь x<y Истина, если х меньше у, иначе - ложь

Page 31: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

32

x<=y Истина, если х меньше или равно у, иначе -ложь

x>y Истина, если х больше у, иначе - ложь x>=y Истина, если х больше или равно у, иначе -

ложь

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

К поразрядным логическим операциям относят операции поразрядной конъюнкции (&), поразрядной дизъюнкции (|), поразрядного исключающего ИЛИ (л). При выполнении операции происходит побитовое сопоставление операндов. Операции данного типа определены для int, uint, long, ulong.

Условные логические операции И (&&) и ИЛИ (||) приме-няются с логическими операндами, в качестве результата так же возвращают логическое значение -true или false.

Операция условное логическое И (&&) соответствует классической конъюнкции, вычисление результирующего значения происходит по правилам конъюнкции, операция условное логическое ИЛИ (||) соответствует дизъюнкции, результат вычисляется согласно ее правилам. Значение результата при использовании условных логических операций приведены в таблице 1.10.

Таблица 1.10 Условные логические операции Операнд 1 Операнд 2 && 1

false false false fa se false true false True true false false Truetrue true true true

Page 32: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

33

Наиболее сложной для понимания у неподготовленного программиста является тернарная операция языка - условная операция. Условная операция имеет следующую форму задания:

Операнд_1 ? операнд_2: операнд_3 Первый операнд - это выражение, которое неявно пре-

образуется компилятором к логическому типу. Если результат вычисления этого выражения равен true, то результатом условной операции будет операнд_2. В противном случае - опе- ранд_3. Например,

static void Main() { int a =10, b=7; int min = a<b ? a : b; Console.WriteLine(“min =“+min.ToString());

} 1.2.4 Математические функции

Математические функции, которые могут быть исполь-зованы в выражениях, реализованы в классе Math пространства имен System. Подробное описание математических функций приведено в таблице 1.11.

Таблица 1.11 Функции класса Math Имя Описание

Тип результатаПример

Abs Модуль В зависимости от типа аргумента

Abs(x)

Acos Арккосинус double Acos(double x)

Asin Арксинус double Asin(double x)

Atan Арктангенс double Atan(double x)

Page 33: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

34

BigMul Произведение long BigMul(int x, int y)

Ceiling Округление до большего целого

double Ceil-ing(double x)

Cos Косинус double Cos(double x) Cosh Г иперболиче-

ский косинус double

Cosh(double x) DivRem Деление и ос-

таток В зависимо-сти от типа аргумента

DivRem(x,y,rem)

E База натураль-ного логарифма (число е)

double 2,71828182845 905

Exp Экспонента double Exp (x) Floor Округление до

меньшего целогоdouble Floor(double x)

IEEERe-mainder

Остаток от де-ления

double IEEERemaind- er(double x, double y)

Log Логарифм double Log(x) Log10 Десятичный

логарифм double Log10(x)

Max Максимум В зависимо-сти от типа аргумента

Max (x, y)

Min Минимум В зависимо-сти от типа аргумента

Min(x,y)

PI Число п double 3,14159265355 8979

Pow Возведение в степень

double xy

Pow(x,y)

Round Округление В зависимо- Round (x)

Page 34: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

35

сти от типа аргумента

Sigh Знак числа int перегружен Sin Синус double

Sin (double x) Sqrt Корень числа double Sqrt (x) Tan Тангенс double Tan(double x) Tanh Г иперболиче-

ский тангенс double Tanh (double x)

1.3 Контрольные вопросы

1. Поясните, что такое переменная и как она инициализируется в программе.

2. Какие типы констант существуют? 3. Как осуществляется работа с консолью в языке? 4. Назовите основные математические функции и поясни

те механизм обращения к ним. 5. Что такое операция и чем она отличается от выраже

ния. 6. Приведите пример условной операции 7. Назовите логические операции. 8. Проведите сдвиг вправо и влево для числа 5.

1.4 Лабораторная работа №1

Общие рекомендации к задаче. Задача выполняется в консоли, с клавиатуры вводятся необходимые переменные. Для вычисления значений используется класс Math. Методы, не реализованные в классе, выразите через имеющиеся. В ре-зультате необходимо вывести результат вычисления двух функций. Необходим контроль корректности ввода данных, вывод информационных сообщений пользователю.

№ Функция z1 Функция z2

Page 35: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

36

1 cos x + sin x + cos 3x + sin 3x 115 - 4 ..n

2 sin2 x + sin 5x + cos3x + sin3x

cosx + 1 — 2sin2 x

2 sinx

3 sin2 x + sin 5x + cos3x + sin3x

cosx — cos3x + cos 5x

tg 3x

4 1 2 1 — —sin22x + cos2x

4

cos2x + cos4x

5 cosx + cos2x + cos6x + cos7x x 5 4cos — ! cos — x ! cos4x

2 26 2(3 x\ 2 11 x

cos2 " - ^ ----- # —cos2 (— n------------+ —)

42 x —sin- 2 2

7 x2 + 2x — 3 + (x + 1)4x2 — 9

x + 3 x2 — 2x — 3 + (x — 1)4x2 — 9 x — 3

8 (' — 1)^m — (n — 1)4n

4m(n + nm + m2 —m 4m — 4n

m 9 )2* + 24*2 — 4

4*2 — 4 + * + 2

1

4*+ 2

10 (cosx — cos+)2 — (sinx — sin+)2 2x — + —4sin2 —2—cos (x + +)

Page 36: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

37

Рис.2.1 Структурная схема условного оператора

ГЛАВА 2 ОСНОВНЫЕ АЛГОРИТМИЧЕСКИЕ КОНСТРУКЦИИ 2.1 Операторы

2.1.1 Операторы ветвления

В языке определены два оператора ветвления: if и switch. Они, в зависимости от определенных значений и исходных условий, обеспечить выполнение определенных действий. Оператор if позволяет выбрать одну из двух ветвей вычислений, а оператор switch - на одну из произвольного числа ветвей.

Оператор if - наиболее известный оператор ветвления. Схема оператора представлена на рис. 2.1

полная форма неполная форма

Формат задания логического оператора следующий: if ( выражение ) { операторы _1;}

[else {операторы_2};]

Сначала компилятор вычислит значение логического вы-ражения, указанного после слова if. Если данное выражение имеет значение «истина», но выполняются операторы_1, если же значение логического выражения - «ложь», то операто- ры_2. При этом следует помнить, что существует неполная форма оператора if, которая предусматривает отсутствие ветки “else” и, как следствие, операторы_2.

Так же следует помнить, что операторы, содержащиеся в условном операторе, не должны содержать меток.

Page 37: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

38

Если необходимо проверить истинность нескольких ло-гических выражений в условии оператора if, их можно объе-динять между собой с помощью логических операции И / ИЛИ (&& / || соответственно). При этом каждое условие, истинность которого нужно проверить, должно заключаться в круглые скобки. Само выражение, проверяющееся в операторе if так же должно быть заключено в круглые скобки для корректной работы компилятора. Например,

if (num <= 0 ){x++;} /*пример условного оператора в его неполной форме*/

if ((num<0) && (num>10)) {x++;} else {x--;} /*пример полной формы оператора if*/

if (((num<0) || (x<0)) && (num>10)) {x++;} else {x--;} /*за счет применения логических операций возможно корректировать проверку истинности выражения. Например, в данном примере выражение будет иметь истинное значение, если выполнится одно из двух условий: num<0 и num >10 или x<0 и num >10*/

Рассмотрим пример поиска минимального элемента с использованием условного оператора if. static void Main() {

Console.WriteLine (“ Введите первое число”); string buf = Console.ReadLine(); int num_1 = Convert.ToInt32 (buf); Console.WriteLine (“ Введите второе число”); buf = Console.ReadLine(); int num_2 = Convert.ToInt32 (buf); if (num_1 == num_2) {Console.WriteLine (“ числа равны!”);} else { if (num_1<num_2) {Console.WriteLine (“ первое число меньше”);} else

Page 38: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

39

{Console.WriteLine (“ второе число мень - ше”);}

} }

Оператор выбора switch работает как переключатель и предназначен для разветвления процесса вычислений более чем на два направления. Схема оператора приведена на рис.2.2.

Рис.2.2 Структурная схема оператора switch Формат задания оператора имеет следующий вид:

switch (выражение) { case значение _1: {операторы _1;} case значение _2: {операторы _2;}

case значение _n: { операторы _n;} [default: операторы _ по _ умолчанию ;] }

Выполнение оператора выбора, аналогично оператору условия, начинается с вычисления выражения. Однако, если в условном операторе значением выражения могло быть одно из двух значение: истинное или ложное, то тип выражения оператора выбора может быть целочисленный, стоковый, символьный. Затем значение выражения по очереди сравнивается со значениями case. Если значение выражение равно значе

Page 39: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

40

(buf);

(“Это понедельник”);

(“Это вторник”);

(“Это среда”);

(“Это четверг”);

(“Это пятница”);

(“Это суббота”);

(“Это воскресенье”);

нию, указанному в case-выражении, то выполняются операторы, указанные в теле соответствующего case.

Если совпадения не нашлось, то выполняются операторы, расположенные в ветви default. Если ветвь default не определена, но управление передается следующему по ходу оператору.

Каждая ветвь оператора выбора должна заканчиваться одним из операторов перехода: break, goto, return (гл. 2, раздел 2.1.3)

Рассмотрим задачу вывода названия дня недели по его порядковому номеру. static void Main() { Console.WriteLine (“Введите номер дня недели”); string buf = Console.ReadLine(); int day = Convert.ToInt32 switch (day) {

case 1: { Console.WriteLine break; }

case 2: { Console.WriteLine break; } case 3: { Console.WriteLine break; }

case 4: { Console.WriteLine break; }

case 5: { Console.WriteLine break; }

case 6: { Console.WriteLine break; }

case 7: { Console.WriteLine

Page 40: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

41

break; } default: {

Console.WriteLine (“Такого дня нет”); break; } }

} Оператор switch предпочтительней оператора if в тех

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

2.1.2 Операторы цикла

Циклы используются для того, чтобы оптимизировать действия, которые выполняются многократно. В языке опре-делены четыре типа циклов: цикл с предусловием, цикл с по-стусловием, цикл с фиксированным числом повторений, цикл перебора.

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

Цикл с фиксированным количеством повторений (цикл for) еще называется циклом с параметром. Цикл может быть описан блок-схемой, представленной на рис. 2.3

Page 41: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

42

Рис. 2.3. Структурная схема цикла for Синтаксис задания цикла с фиксированным количеством

повторений: for (инициализация; выражение; модификация)

{тело цикла} Инициализация необходима для установки начального

значения. В разделе инициализации можно указать одну или несколько переменных через запятую. Выражение может принять одно из двух возможных значений: «истина» или «ложь». Пока значение выражения равно true, цикл продолжает свою работу. Блок модификации выполняется после каждой итерации цикла и автоматизирует процесс изменения счетчика (или иных переменных) цикла на фиксированную величину.

Например, for (int i=0, j = 10; (i>6) && (j<0); i++, j-- )

{-}

В качестве иллюстрации работы цикла рассмотрим подсчет суммы чисел от 1 до 10. static void Main() {

Console.WriteLine (“ Подсчет суммы чисел от 1 до 10”);

int sum = 0;

Page 42: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

43

// переменная для хранения суммы for (int i= 1; i<=10; i++) {

sum = sum + i; } Console.WriteLine (“ Сумма чисел от 1 до 10 = ”

+ sum.ToString()); } Цикл с предусловием (цикл while) имеет следующую

логическую структуру (рис. 2.4)

Рис. 2.4. Структурная схема цикла while Формат оператора имеет следующий вид:

while (выражение) {операторы} Выражение должно быть логического типа. Если результат

вычисления данного выражения равен true, то компилятор переходит в тело цикла и исполняет операторы, указанные в теле. Если результат вычисления выражения равен false, то происходит выход из цикла. Управление передается на следующий за циклом оператор. Цикл while может не выполниться ни разу, если выражение изначально имеет ложное значение.

Page 43: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

44

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

В качестве примера рассмотрим задачу подсчета суммы чисел от 1 до 10. static void Main() {

Console.WriteLine (“ Подсчет суммы чисел от 1 до 10”);

int i= 1; /* установка начального значения параметра цикла

*/ int sum = 0; // переменная для хранения суммы while (i<=10) {

sum = sum + i; i++; // изменение значения параметра цикла

} Console.WriteLine (“ Сумма чисел от 1 до 10 = ”

+ sum.ToString()); } Для корректной работы цикла необходимо перед запуском

программы проконтролировать ряд вопросов: 1. присвоено ли параметру цикла начальное значение, 2. изменяется ли параметр цикла на каждой итерации, 3. верно ли записано выражение, определяющее условие

продолжения цикла. Цикл while позволяет создать конструкцию бесконечного

цикла с заголовком while (true) и принудительным выходом с помощью операторов перехода.

Цикл с постусловием (цикл do ... while) имеет сле-дующую структурную схему (рис.2.5).

Page 44: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

45

Рис. 2.5. Структурная схема цикла с постусловием Синтаксис задания цикла имеет следующий формат: do

{тело цикла} while (выражение) Сначала компилятор выполняет операторы, составляющие

тело цикла, а затем вычисляется значение выражения. Если выражение имеет значение «истина», то компилятор возвращается к телу цикла, если значением выражения будет «ложь», то управление передастся первому после цикла оператору.

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

В качестве примера рассмотрим задачу вычисления суммы чисел от 1 до 10 с помощью цикла с постусловием. static void Main() {

Console.WriteLine (“ Подсчет суммы чисел от 1 до 10”);

int i= 1;

Page 45: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

46

/* установка начального значения параметра цикла*/

int sum = 0; // переменная для хранения суммы do {

sum = sum + i; i++; // изменение значения параметра цикла

} while (i<10); Console.WriteLine (“ Сумма чисел от 1 до 10 = ”

+ sum.ToString()); } Все циклы являются взаимозаменяемыми и могут быть

приведены к один к другому. Помимо этого допускается су-ществование вложенных конструкций: циклов, операторов выбора и условия.

Цикл перебора foreach используется для перебора од-нотипных объектов, например, элементов массива, списка и будет рассмотрен в разделе 3.2.1 гл. 3.

2.1.3 Операторы передачи управления

В языке существует возможность передавать управление без соответствия с естественным порядком вычислений. Для этого используются следующие операторы:

• оператор перехода goto, • оператор выхода из логической конструкции break; • оператор перехода к следующей итерации цикла

continue; • оператор возврата из функции return.

Оператор перехода goto может иметь одну из трех возможных форм:

goto метка; goto case константное выражение;

Page 46: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

47

goto default; Для того, чтобы оператор сработал в теле функции должна

присутствовать одна конструкция вида: метка: оператор; Когда в программе встречается оператор goto, ее вы-

полнение переходит непосредственно к тому месту, на которое указывает этот оператор. Первая из предложенных форм оператора передает управление на маркированный оператор. Вторая форма записи оператора передает управление на соот-ветствующую константному выражению ветвь кода. Третья форма оператора используется, если необходимо выполнить часть действий по умолчанию.

Рассмотрим пример применения оператора goto. Однако, сразу хотелось бы заметить, что использование оператора не поощряется, поскольку он значительно усложняет читаемость кода. static void Main() {

// Обычный цикл for выводящий числа от 1 до 5 Console.WriteLine(" Обычный цикл for:"); for (int i = 1; i <= 5; i++) Console.Write("\t{0}",i); /* Реализуем то же самое с помощью оператора

goto */ Console.WriteLine("\n Используем goto:"); int j = 1; link1: Console.Write("\t{0}",j); j++; if (j <= 5) goto link1; Console.ReadLine(); } Оператор break используется внутри операторов цикла

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

Page 47: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

48

итерация цикла прерывается на моменте появления оператора break. Рассмотрим пример использования оператора для предыдущей задачи (сумма чисел от 1 до 5). static void Main() { /* В данном цикле выведутся числа от 1 до 5 вме сто 10*/

for (int i = 1; i < 10; i++) if (i <= 5) Console.WriteLine(i); else break;

Console.ReadLine(); } Если оператор break применяется в целом ряде вложенных

циклов, то он прерывает выполнение только самого внутреннего цикла.

Оператор перехода к следующей итерации continue пропускает все операторы, оставшиеся до завершения текущей итерации, и передает управление на начало следующей итерации цикла. Рассмотрим пример вывода чисел в диапазоне от 1 до 100, которые кратны 5, с помощью оператора continue. static void Main() {

// Выводим числа кратные 5 for (byte i = 1; i <= 100; i++)

{ if (i % 5 != 0) continue; Console.Write("\t{0}", i);

} Console.ReadLine(); }

Оператор возврата из функции return завершает выполнение функции и передает управление в точку ее вызова. Оператор имеет одну из двух форм:

return; return выражение;

Page 48: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

49

Первая форма применяется для завершения метода типа void, вторая - для возврата значения из метода в вызывающую часть программы. В этом случае тип выражения должен иметь возможность преобразования к типу функции. Все ветви кода должны возвращать значение, иначе возникает ошибка компиляции. Рассмотрим пример использования двух форм оператора return. class Program {

static void Main() { int result = Sum(230);

// вызываем функцию подсчета суммы Print(result); // метод печати результата Console.ReadLine(); }

// Метод , возвращающий сумму четных чисел // от 1 до s static int Sum(int s) {

int mySum = 0; for (int i = 1; i <= s; i++) {

if (i % 2 == 0) mySum += i; } return mySum;

/* метод имеет тип int, возвращает значение типа int*/

}

// Метод выводит информацию на экран и // ничего не возвращает // в главную функцию // поэтому он имеет тип void static void Print(int s) {

Page 49: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

50

Console.WriteLine(" Сумма четных чисел от 1 до 230 равна : " + s.ToString());

return; // возврат в вызывающую функцию

} } 2.1.4 Контрольные вопросы

1. назовите условные операторы языка. 2. какое значение имеет ветка default в операторе

switch? 3. Назовите основные отличия цикла с предусловием от

цикла с фиксированным числом повторений. 4. Синтаксис задания цикла с фиксированным числом по-

вторений. 5. Приведите пример использования условного оператора.

2.2 Обработка исключительных ситуаций 2.2.1 Понятие исключения и основные способы его

обработки

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

Подобные ситуации называются исключительными си-туациями или исключениями. Примерами исключений могут быть:

• деление на ноль; • конвертация некорректных данных из одного типа в

другой; • попытка открыть файл, которого не существует;

Page 50: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

51

• доступ к элементу вне рамок массива; • исчерпывание памяти программы; • другое.

Если в процессе работы программы возникла исключи-тельная ситуация, то система сигнализирует об этом, генерируя исключение. Каждый тип ошибки имеет закрепленный за ним код исключения. Все исключения, генерируемые приложением, имеют общего предка - класс Exception. Данный класс содержит ряд полезных свойств, использование которых позволяет получить максимум информации об исключении (табл. 2.1)

Таблица 2.1 Свойства класса Exception Свойство Описание

HelpLink URL файла с описанием ошибкиMessage Текстовое описание ошибки. Доступно

только для чтения Source

Имя объекта, который сгенерировал ошибкуStackTrace Последовательность вызовов, которые

привели к данной ошибке. Доступно толькодля чтения

Исключения позволяют логически разделить процесс вычислений на две составляющих: обнаружение исключительной ситуации и ее программная обработка. Обработка исключений - это описание реакции программы на подобные события (исключения) во время выполнения программы. Реакцией программы может быть корректное завершение работы программы, вывод информации об ошибке и запрос повторения действия (при вводе данных).

Существует ряд исключений, которые встречаются наи-более часто (табл.2.2)

Page 51: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

52

Таблица 2.2 Стандартные распространенные исключения Имя исключения Описание Arithmet icExcept ion

Ошибка в арифметической операции ArrayTypeMismatchException

Попытка сохранения в массиве элемента несовместимого типа

DivideByZeroExccept ion

Создается при попытке разделить целое число на ноль.

IndexOutOfRangeExce ption

Создается при попытке индексиро-вания массива, если индекс меньше нуля или выходит за границы массива.

NullReferenceExcept ion

Создается при попытке ссылки на объект, значение которого равно null.

OutOfMemoryExceptio n

Создается при неудаче попытки выделения памяти с помощью опе-ратора new. Это означает, что память, доступная для среды выполнения, уже исчерпана.

OverflowException Создается при переполнении ариф-метической операции в контексте checked.

StackOverflowExcept ion

Создается, когда стек выполнения переполнен за счет слишком боль-шого количества вызовов отложенных методов; обычно является признаком очень глубокой или бесконечной рекурсии.

2.2.2 Оператор обнаружения и обработки исключений

Принимая во внимание, что .NET Framework включает большое количество предопределенных классов исключений,

Page 52: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

53

разумно из использовать при перехвате возникающих ошибок. Для того чтобы справиться с прогнозируемыми ошибочными ситуациями в коде языка C#, в программу включаются блоки трех разных типов:

• Блоки try (или контролируемый блок) представляет собой составной оператор, включающий в себя те операторы программы, в которых может возникнуть исключительная ситуация.

• Блоки catch являются блоками-обработчиками исклю-чений, содержат в себе операторы, направленные на обработку исключений, возникших в блоках try.

• Блоки finally содержат код, очищающий ресурсы или выполняющий другие действия, которые обычно нужно выполнить в конце блоков try или catch. Этот блок выполняется независимо от того, будет сгенерировано и обработано исключение или нет.

Структурная схема оператора try имеет следующий вид (рис 2.6)

Рис. 2.6. Структурная схема оператора обработки исключений Синтаксис задания оператора try: try блок [блоки catch] [блоки finally]

Page 53: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

54

При этом могут отсутствовать либо блоки catch, либо блоки finally, но не оба типа блоков одновременно.

Обработка исключительных ситуаций происходит по следующему алгоритму:

1. Сигналом к обработке исключения является появление ошибки. Функция или операция, в которой произошла ошибка, генерирует исключение.

2. Выполнение текущего блока прекращается, в списке обработчиков отыскивается обработчик возникшего исключения. Этому обработчику передается управление.

3. Выполняется блок finally, если таковой присутствует. 4. Если пользовательский обработчик исключения не найдет,

вызывается стандартный обработчик, который выводит на экран информацию о возникновении ошибки и завершает работу программы.

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

catch (тип имя) {тело обработчика}; Данная форма применяется, когда имя параметра будет

использоваться в теле обработчика, например, для вывода со-общения пользователю.

catch (тип) {тело обработчика}; Данная форма не предполагает использования информации

об исключении в теле разработчика, программисту достаточно знать его тип.

catch {тело обработчика};

Данная форма применятся для перехвата всех типов ис-ключений. Поскольку обработчики рассматриваются компи

Page 54: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

55

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

Рассмотрим несколько примеров. Сначала рассмотрим пример, содержащий блок try и один блок catch, записанный во второй форме. static void Main() {

try{ int a=3; int b =0; int c =a/b; // Деление на ноль Console.WriteLine(c);

} catch(DivideByZeroException){ // сработает данный catch Console.WriteLine(" Деление на ноль !!!"); } Console.Read(); } Блок finally исполняется в любом случае (вне зави-

симости от того, были ли сгенерированы исключения), затем управление передается первому после try оператору. Например, static void Main() {

try{ int a=3; int b=0; Console.WriteLine(a/b);

} catch(DivideByZeroException e){ Console.WriteLine(" Деление на Ноль"); } finally{

Page 55: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

56

Console.WriteLine("Bye"); } Console.Read(); }

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

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

2.2.3 Защищенный код

В разделе о приведении типов данных было сказано, что в случае переполнения происходит урезание полученного значения. Однако, можно организовать проверку на переполнение с помощью ключевых слов checked и unchecked. Так , если требуется указать, что выражение будет проверяться на пере-полнение, следует использовать ключевое слово checked, а если требуется проигнорировать переполнение — ключевое слово unchecked. В данном случае результат усекается, чтобы не выйти за пределы диапазона представления чисел для целевого типа выражения.

Проверка с помощью checked может организовываться как для одного оператора, например,

a = checked (b+v); // проверка включена так и для группы операторов, например,

unchecked { a = b+v; // проверка проводиться не будет } Рассмотрим применение защищенного кода и операторов

обработки исключения в задаче. static void Main()

Page 56: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

57

");

try{

byte a, b, result; Console.Write("Введите количество опросов int i = int.Parse(Console.ReadLine()); for (int j = 1; j <= i; j++)

{

Console.Write("Введите a: "); //Используем unchecked в одном выжении a = uchecked((byte)int.Parse (Console.ReadLine())); Console.Write("Введите b: "); b = uchecked((byte)int.Parse (Console.ReadLine())); /* Используем checked для всего блока

операторов*/ checked {

result = (byte)(a + b); Console.WriteLine("a + b = " + result); result = (byte)(a * b); Console.WriteLine("a*b = " + result );

} } catch (OverflowException) {

Console.Write("Переполнение\п\п"); }

} Console.ReadLine(); } 2.2.4 Программирование под Windows: форма, кнопка,

текстовое поле

В основу Windows положен принцип событийного управления. Это значит, что система после запуска ожидает

Page 57: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

58

действий пользователя и реагирует на них тем способом, который был определен. К действиям пользователя относят нажатие клавиши на клавиатуре, нажатие кнопки мыши, перемещение указателя мыши. Все эти действия являются событиями. В общем случае можно сказать, что структура событийно управляемой программы имеет следующий вид (рис. 2.7)

Рис. 2.7. Структура событийно управляемого приложения Событие в приложениях Windows преобразуется в сооб-

щение, содержащее информацию о событии. Сообщения могут генерироваться не только пользователем приложения, но и системой, другими приложениями, приложением самим для себя. Сообщения формируют внутреннюю очередь. Каждое приложение содержит информацию приложении, предназна-ченном для обработки сообщения, а так же внутренний цикл сообщений, который позволяет обрабатывать сообщения по очереди.

Среда Visual Studio позволяет выполнить всю подготови-тельную работу по созданию приложения, определению заготовок для обработчиков событий, организацию цикла по обработке событий и т. д. То есть, приложение, написанное в данной среде, является событийно управляемым.

Page 58: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

59

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

Класс Form имеет ряд полезных свойств, методов и со-

бытий, которые представлены в табл. 2.3 -2.5 Таблица 2.3

Свойства класса Form

Свойство Описание

AutoScaleBaseSize Возвращает или задает базовый размер, используемый для автоматического масштабирования формы.

AutoScroll Возвращает или задает значение, оп-ределяющее, разрешена ли в форме автоматическая прокрутка.

BackColor Возвращает или задает цвет фона для элемента управления.

BackgroundImage Фоновое изображение для элемента управления.

CancelButton Возвращает или задает кнопку, которая срабатывает при нажатии клавиши ESC.

CanSelect Возвращает значение, указывающее, доступен ли элемент управления для выбора

Capture Возвращает или задает значение, ука-зывающее, была ли мышь захвачена элементом управления.

ContextMenu Меню быстрого доступа, отображаемое при щелчке правой кнопкой мыши по элементу управления.

DefaultCursor Возвращает или задает курсор по умолчанию для элемента управления.

Page 59: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

60

DefaultSize Получает размер элемента управления по умолчанию

Enabled У казывает, включен ли элемент управления.

Font Шрифт, используемый для отображения текста на элементе управления.

Height Высота данного элемента управления в пикселях.

HelpButton Возвращает или задаёт значение, по-казывающее, отображается ли кнопка справка в заголовке окна формы.

HorizontalScroll Получает характеристики, связанные с горизонтальной полосы прокрутки.

Icon Возвращает или задает значок для формы.

MaximizeBox Получает или задает значение, указы-вающее, отображается ли кнопка «Развернуть» в строке заголовка формы.

MaximumSize Возвращает максимальный размер, до которого может быть увеличена форма

MinimizeBox Получает или задает значение, указы-вающее, отображается ли кнопка «Свернуть» в строке заголовка формы.

MinimumSize Возвращает или задает минимальный размер, до которого может быть уменьшена форма.

Name Возвращает или задает имя элемента управления.

ShowInTaskbar Возвращает или задает значение, ука-зывающее, отображается ли форма в панели задач Windows.

ShowWithoutActiva tion

Возвращает значение, указывающее, будет ли окно активироваться при его

Page 60: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

61

отображении. Size Возвращает или задает размер формы.

Text Возвращает или задает текст, связанный с этим элементом управления.

Visible

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

VScroll Возвращает или задает значение, ука-зывающее, отображается ли верти-кальная полоса прокрутки.

Width Возвращает или задает ширину элемента управления.

WindowState Возвращает или задаёт значение, ука-зывающее на состояние формы: раз-вёрнутое, свернутое или обычное.

Таблица 2.4 Методы класса Form Метод Описание

Activate() Активизирует форму и присваивает ей фокус. Этот API поддерживает инфраструк-

CenterToScreen() туру продукт, и его не следует исполь-зовать напрямую из кода. Выравнивает форму по центру текущего экрана.

Close() OnDoubleClick()

Закрывает форму. Вызывает событие DoubleClick

OnFormClosed() OnHelpBut t onClick

Вызывает событие FormClosed Вызывает событие

ed () OnKeyPress()

HelpButtonClickedВызывает событие KeyPress

Page 61: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

62

OnMouseClick() Вызывает событие MouseClick

Refresh()

Принудительно создает условия, при которых элемент управления делает недоступной свою клиентскую область и немедленно перерисовывает себя и все дочерние элементы.

Show() Отображает элемент управления.

ShowDialog() Отображает форму как модальное диалоговое окно.

Update() Вызывает перерисовку элементом управления недопустимых областей клиентской области

Таблица 2.5 События класса Form

Событие Описание

Activated Происходит при активизации формы, определенной в коде или заданной пользователем.

Click Происходит при щелчке элемента управления.

Closed Происходит при закрытой форме.

Load Происходит до первоначального ото-бражения формы.

Resize Происходит при изменении размеров элемента управления.

Shown Происходит, когда форма начинает отображаться.

Элементы управления помещаются на форму с помощью панели элементов. Обычно они применяются для общения с пользователем.

Page 62: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

63

Самым простым является метка (label). Она предназна-чена для размещения текста на форме. Основные свойства меток представлены в табл. 2.6

Таблица 2.6 Основные свойства меток Свойство Описание

BackColor Возвращает или задает цвет фона для элемента управления.

Height Высота данного элемента управления в пикселях.

Font Шрифт, используемый для отображения текста на элементе управления.

FontHeight Возвращает или задает высоту шрифта элемента управления.

ForeColor Цвет переднего плана для отображе-ния текста в данном элементе управ-ления.

Name Возвращает или задает имя элемента управления.

Text Возвращает или задает текст, связанный с этим элементом управления.

Информация в метку не может вводится с клавиатуры пользователем.

Помимо меток на форму может быть помещена одна или несколько кнопок (button). Основное событие кнопки - это ее нажатие (Click). Однако, помимо простого нажатия, кнопка может реагировать на множество других событий. Основные свойства кнопки схожи со свойствами меток и совпадают с ними по названию.

Компонент для ввода строк текста (textBox) позволяет вводить, редактировать, выводить текст и сообщения. Основные свойства компонента совпадают со свойствами метки, од

Page 63: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

64

нако существуют свойства, характерные только для данного компонента (табл. 2.7)

Таблица 2.7 Особенные свойства компонента textBox Свойство Описание

Enabled Указывает, включен ли элемент управления

ReadOnly Возвращает или задает значение, ука-зывающее, является ли текст в тексто-вом поле доступно только для чтения

Multiline

Получает или задает значение, пока-зывающее, является ли данный элемент управления многострочным TextBox.

PasswordChar

Возвращает или задает символ, ис-пользуемый для символов маски пароля в однострочный TextBox элемента управления.

ScrollBars

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

WordWrap

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

Для работы с textBox удобно использовать методы очи-стки (Clear()), выделения (Select()), копирования в буфер (Copy()), вставки из буфера (Paste()), доступ к тексту осу-ществляется с помощью свойства Text.

Рассмотрим пример, который включает в себя все выше-описанные компоненты. Задача состоит в том, чтобы прочи

Page 64: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

65

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

Форма имеет внешний вид, представленный на рис. 2.8

Рис. 2.8 Окно приложения

Компоненты, присутствующие на форме, значение поля Name и выполняемые функции представлены в табл. 2.8

Таблица 2.8. Компоненты и их значения

Тип компонента

Name Функции

label info Содержит текст «Введите число»

label helper Содержит текст «Квадрат числа»

label res Содержит итоговое значение квадрата числа

button Print Кнопка «Узнать» button clear Кнопка «очистить»textBox PrintResult Поле ввода информации

Текст программы с комментариями приведен далее.

Page 65: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

66

public partial class Forml : Form {

public Form1() {

InitializeComponent(); }

private void print_Click(object sender, EventArgs e)

{ int num = 0; bool OK = true; /*сигнализирует о наличии

ошибки. False - нет ошибки */ try { num = Convert.ToInt32(PrintResult.Text); OK = false; // нет ошибки } catch {

res.Text = "Ошибка ввода"; //сообщение об ошибке } if (!OK) // если нет ошибки { num = num * num; res.Text = num.ToString(); //вывод результата }

}

private void clean_Click(object sender, EventArgs e)

{ res.Text = "";//очищаем метку PrintResult.Text = ""; //очищаем textBox PrintResult.Focus(); // устанавливаем курсор в textBox

Page 66: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

67

2.2.5 Диалоговые окна и сообщения об ошибке в приложениях под Windows

Кнопки часто используются в диалоговых окнах. Диало-говые окна запрашивают у пользователя информацию, которая уточняет ранее введенные данные. Такие формы обладают свойством модальности - дальнейшие действия будут недос-тупны, пока окно не будет закрыто с помощью кнопок, со-держащихся на данной форме. Возможные значения модальных кнопкок представлены в табл. 2.9

Таблица 2.9 Значения свойства DialogResult у модальной кнопки Значение Описание None Окно не закрыто OK Нажата кнопка OKCancel Нажата кнопка Cancel Abort Нажата кнопка Abort Ignore Нажата кнопка IgnoreYes Нажата кнопка Yes No Нажата кнопка NoRetry Нажата кнопка Retry

Для сохранения информации о том, нажатием какой из кнопок было закрыто окно, у кнопки оценивается свойство DialogResult.

Следует четко различать процесс создания формы - со-ответствующего объекта, принадлежащего классу Form или наследнику этого класса, - и процесс показа формы на экране. Для показа формы служит метод Show этого класса, вызываемый соответствующим объектом; для скрытия формы исполь

Page 67: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

68

зуется метод Hide. Реально методы Show и Hide изменяют свойство Visible объекта, так что вместо вызова этих методов можно менять значение этого свойства, устанавливая его либо в true, либо в false.

Любую обычную форму можно запустить как модальное окно, если вместо Show() использовать ShowDialog(). Пример запуска диалогового (модального) окна настройки, вызываемого из меню: private void SetupStripMenuItem_Click(object sender, EventArgs e) {

Program.form2.ShowDialog(); } Если после вызова Show() пользователь закроет вызванное

окно, то повторно вызвать Show() не получится, так как объект окна будет уничтожен, и его надо будет создавать заново. При каждом вызове Show() экземпляр класса окна нужно создавать заново в коде приложения. ShowDialog() работает по-другому: после закрытия пользователем окна экземпляр класса окна не будет уничтожен, поэтому не нужно перед каждым новым вызовом ShowDialog создавать экземпляр класса.

Помимо возможности запрашивать информации с помощью модальных форм существует возможность информировать пользователя об ошибке с помощью класса языка MessageBox. Данных класс отображает окно сообщения с текстом для пользователя. Это модальное окно, блокирующее другие действия в приложении, пока пользователь не закроет его. MessageBox может содержать текст, кнопки и символы, с помощью которых информируется и инструктируется пользо-ватель. Основной метод данного класса - Show(«TekCT со-общения»), который и выводит модальное окно пользователю. Например,

MessageBox.Show (“Ошибка”);

Page 68: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

69

Метод имеет ряд перегрузок, которые позволяют добав-лять на модальное окно несколько кнопок, параметры выбора или справку.

2.3 Контрольные вопросы

1. Что такое исключение? 2. Какой класс реализует исключения языка 3. Оператор try. Его основные характеристики. 4. Ветка finally и ее назначение. 5. Проверяемый код. 6. Пример использования оператора try ... catch. 7. Класс MessageBox и его применение. 8. Пользовательские приложения под Windows: понятие,

основные компоненты и свойства.

2.4 Лабораторная работа №2

Задачу из лабораторной работы №1 переписать для Widows, предусмотреть контроль ввода, вывод информационных сообщений, очистку формы.

Page 69: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

70

ГЛАВА 3 МАССИВЫ 3.1 Одномерный, двумерный и ступенчатый массив

3.1.1 Понятие массива

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

Элементы массива могут иметь любой из типов-значений и ссылочный тип (то есть, элементами массива могут быть массивы). Отличием между массивами, имеющими в качестве элементов типы-значения и ссылочные типы в том, что первые хранят непосредственно элементы, а вторые - ссылки на них.

Массив является примером ссылочного типа данных, то есть располагается в динамической области памяти. Поэтому процесс создания массива начинается с выделения памяти под элементы массива. Выделение память происходит с помощью операции new. Формат операции имеет следующий вид:

new тип {[аргументы]}; При вызове оператора new происходит сначала выделение

нужного объема памяти, а затем вызывается конструктор по умолчанию. По умолчанию элементам массива присваиваются начальные значения:

• для арифметических типов - 0, • для ссылочных типов - null, • для символов - пробел. • для логических - false Индекс первого элемента массива - 0, таким образом, при

длине массива в n элементов индекс последнего элемента будет (n-1). Структурная схема массива с элементами- значениями представлена на рис. 3.1

Page 70: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

71

Рис. 3.1. Массив элементов значимого типа

Структурная схема массива с элементами ссылочного типа представлена на рис. 3.2

Рис. 3.2. Структурная схема массива с элементами ссылочного типа

Количество элементов массива так же называют его раз-мерностью. Размерность определяет, какой объем памяти будет выделен для хранения элементов массива. Размерность определяется единожды при объявлении массива и не может быть изменена впоследствии. Размерность может быть задана не только константой, но и выражением, результат вычисления которого должен иметь тип int, uint, long. ulong.

Для корректной работы с массивами необходимо кон-тролировать нахождение в его границах. Если индекс выходит за границы массива, генерируется исключение IndexOutOfRangeException. Массивы одного типа могут

Page 71: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

72

тип[] имя ;

тип[] имя = new тип [размерность ]; тип[] имя = { списокинициализаторов };тип[] имя = new тип []{список инициализаторов};

тип[] имя = new тип [ размерность ] {

быть присвоены друг другу. При этом происходит не поэле-ментное присваивание, а присваивание ссылок.

Массивы в C# имеют общий базовый класс Array, опреде-ленный в пространстве имен System. Данный класс имеет множество полезных для работы методов, которые будут рас-смотрены далее.

3.1.2 Одномерный массив

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

инициализаторов}; Например, int[] ar_1; // описана только ссылка на массив, память под элементы не выделена int[] ar_2 = new int [10]; //массив из 10 элементов, заполненных по умолчанию int[] ar_3 = {1, 67, 2, 100}; //массив из 4 элементов int[] ar_4 = new int []{1, 67, 2, 100}; //размерность массива будет вычислена ком-пилятором

Для того, чтобы обратиться к элементу массива исполь-зуется номер элемента в квадратных скобках, например,

ar_2[4]; //обращаемся к 5 элементу ar_2 ar_3[0]; //обращаемся к 1 элементу ar_3 Как было сказано ранее, при выходе индекса элемента

формируется исключение IndexOutOfRangeException. Для того, чтобы обезопасить себя от данной ситуации, разумно будет включить блок обработки исключительной ситуации в те

Page 72: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

73

ло программы. Пример блоков try ... catch для обработки данного исключения приведен далее. for (int i=0; i<ar_2.Length; i++) {

try {

ar_2[i] = i; Console.WriteLine (ar_2[i]);

} catch {

Console.WriteLine(“Индекс ”+i.ToString() + “ за границами массива ”);

} } Рассмотрим задачу поиска максимального элемента в

одномерном массиве. static void Main() {

// Объявляем и инициализируем массив int[] cost = { 12, 15, 5, 19, 8, 20, 4, 13}; /* Переменная для хранения максимальной стои

мости */ int max = -1; // Цикл по всем элементам массива // От 0 до размера массива for (int i = 0; i < cost.Length; i++) {

/* Если максимальная стоимость меньше, либо равно текущей */

if (max <= cost[i]) { // Запоминаем новое максимальное значение

max = cost[i]; }

} Console.WriteLine("Максимальный элемент:

" + max.ToString());

Page 73: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

74

Console.WriteLine(" Нажмите любую клавишу для выхода...");

Console.ReadKey(); }

Помимо этого, следует помнить о том, что массив может быть передан как параметр в функцию. Например, class Program {

static void Print(int n, int[] a) //n - размерность массива,а - ссылка на массив {

for (int i = 0; i < n; i++) {

Console.Write("{0} ", a[i]); } Console.WriteLine();

}

static void Main() { int[] myArray = { 0, -1, -2, 3, 4, 5, -6, - 7,

8, -9 }; Print(10, myArray); } }

3.1.3 Прямоугольный массив

Прямоугольный массив имеет структуру, представленную на рис. 3.3

Page 74: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

75

0 12 S'* правый индекс

1эЫе[1 2|

Рис. 3.3 Структура прямоугольного массива Говоря в общем, прямоугольный массив не обязательно

имеет два измерения. Это массив, имеющий более одного из-мерения. Случай двумерного массива является самым распро-страненным.

Как и у массива одномерного, двумерный массив имеет несколько вариантов описания:

тип [,] имя ; тип [,] имя = new тип [ размерность _1, размер - ность_2]; тип[,] имя = {список инициализаторов }; тип [,] имя = new тип [,]{ список инициализато - ров}; тип [,] имя = new тип [ размерность _1, размер - ность_2]{список инициализаторов}; Например, int[,] ar_1; // описана только ссылка на массив, память под элементы не выделена int[,] ar_2 = new int [10,10]; // массив 10*10, заполненный по умолчанию int[,] ar_3 = {{1, 67}, {2, 100}}; // массив 2*2 int[,] ar_4 = new int [,]{{1, 67}, {2, 100}};

//размерность массива будет вычислена компилятором К двумерному массиву обращаются, указывая номер его строки и

столбца в единственных квадратных скобках.

Page 75: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

76

Строки и столбцы нумеруются с 0, т.е. первая строка имеет номер 0, первый столбец так же имеет номер 0.

ar_2[3,4] ; //обращение к элементу 3 строки, 5 столбца

Первый индекс в подобной записи всегда воспринимается компилятором, как номер строки!

Для двумерного массива так же необходимо контроли-ровать нахождение индексов элементов строки и столбца в границах массива во избежание возникновения исключений.

Рассмотрим пример задачи, использующей двумерные массивы. Необходимо узнать число положительных элементов в каждой строке таблицы. class Class1 {

static void Main() {

const int m = 3, n = 4; int[,] a = new int[m, n] {

{ 2,-2, 8, 9 }, {-4,-5, 6,-2 }, { 7, 0, 1, 1 }

}; Console.WriteLine( " Исходный массив:" ); for ( int i = 0; i < m; ++i ) { for ( int j = 0; j < n; ++j ) Console.Write( "\t" + a[i, j] );

Console.WriteLine(); } double sum = 0; int nPosEl; for ( int i = 0; i < m; ++i ) {

nPosEl = 0; for ( int j = 0; j < n; ++j ) {

sum += a[i, j]; if ( a[i, j] > 0 ) ++nPosEl;

Page 76: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

77

} Console.WriteLine( " В строке {0} {1}

положит-х элементов", i, nPosEl ); } Console.WriteLine( " Среднее арифметическое

всех элементов: " + sum / m / n ); } } Как было сказано выше, прямоугольные массивы не обя-

зательно ограничиваются двумя измерениями. Рассмотрим пример задания массива, имеющего три измерения. int[,,] myArr = new int[5,5,5]; for (int i = 0; i < 5; i++) {

for (int j = 0; j < 5; j++) {

for (int k = 0; k < 5; k++) {

myArr[i, j, k] = i + j + k; }

} } 3.1.4 Ступенчатый массив

В ступенчатых массивах число элементов в каждой строке может отличаться. Структурная схема ступенчатого массива представлена на рис. 3.4

Рис. 3.4 Структурная схема ступенчатого массива

Page 77: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

78

На рис. 3.4 видно, насколько отличается хранение сту-пенчатого массива от массива одномерного или прямоугольного. Он представляет из себя совокупность внутренних массивов, каждый из которых имеет свой размер.

Описывается ступенчатый массив следующим образом: тип [][] имя;

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

int[][] ar_1 = new int[3][]; // выделение памяти под ссылки на три столбца ar_1[0] = new int[6]; // выделение памяти под первую строку из 6 элементов ar_1[1] = new int[3]; // выделение памяти под вторую строку из 3 элементов ar_2[2] = new int[2]; // выделение памяти под третью строку из 2 элементов Поскольку ar_l [0], ar_l [1], ar_l [2] - это отдель-

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

ar_1[2][1]; //обращение ко второму элементу третьей строки

Пример работы со ступенчатым массивом приведен далее. static void Main(string[] args) {

int i = 0; // Объявляем ступенчатый массив int[][] myArr = new int[4][]; myArr[0] = new int[4]; myArr[1] = new int[6]; myArr[2] = new int[3]; myArr[3] = new int[4];

// Инициализируем ступенчатый массив

Page 78: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

79

}

Console.WriteLine(); for (i = 0; i < 3; i++) {

myArr[2][i] = i; Console.Write("{0}\t", myArr[2][i]); }

Console.WriteLine(); for (i = 0; i < 4; i++)

for (; i < 4; i++) { myArr[0][i] = i; Console.Write("{0}\t",myArr[0][i]); }

Console.WriteLine(); for (i = 0; i < 6; i++) {

myArr[1][i] = i;

Console.Write("{0}\t", myArr[1][i]);

myArr[3][i] = i; Console.Write("{0}\t", myArr[3][i]);

Console.ReadLine(); } 3.2 Встроенные операторы и классы для работы с

массивами 3.2.1 Оператор foreach

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

Page 79: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

80

Синтаксис задания оператора имеет следующий вид: foreach (тип имя in выражение) {тело цикла}

Page 80: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

81

В данной конструкции «имя » задает локальную по от-ношению к циклу переменную, которая будет принимать зна-чения из элемента «выражение». Из этого следует, что тип пе-ременной из конструкции «имя» должен быть сопоставим с типом элемента массива или иных сгруппированных данных. В качестве выражения применяется имя массива или иных сгруппированных данных. В теле цикла выполняется одно или несколько действий с переменной, указанной в поле «имя».

К примеру, пусть задан массив int[] ar_2 = {1, 4, 6, -2, 0, 10, 30}; Обработка данного массива с помощью цикла foreach

будет выглядеть следующим образом: foreach( int x in ar_2) { Console.WriteLine(x); } При каждой итерации цикла переменная х принимает

значение элементов массива, начиная с первого. Цикл автома-тически завершает работу, когда будут пройдены все элементы. Очевидно, что при использовании цикла foreach ошибка выхода за границу индекса не возникнет.

Для того, чтобы с помощью данного цикла выводить ступенчатые массивы, необходимо использовать конструкцию из вложенных циклов. Для ступенчатого массива ar_1, описанного в предыдущем разделе, перебор с помощью циклов foreach будет выглядеть следующим образом: foreach( int[] x in ar_1) {

foreach(int elem in x) {

Console.Write (“\t” + elem); } Console.WriteLine();

}

Page 81: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

82

Рассмотрим пример использования цикла foreach для решения задачи поиска максимального элемента и его индекса, описанной в разделе 3.1.2. static void Main() {

// Объявляем и инициализируем массив int[] cost={12, 15, 5, 1, 8, 20, 4, 13, 20 }; /* Переменная для хранения максимальной стои -

мости */ int max = -1; // Цикл по всем элементам массива // От 0 до размера массива foreach( int elem in cost) { /* Если максимальная стоимость меньше , либо

равна текущей */ if (max <= elem) { // Запоминаем новое максимальное значение max = elem;

} } Console.WriteLine("Максимальный элемент: " +

max.ToString()); Console.WriteLine("Нажмите любую клавишу для

выхода ..."); Console.ReadKey(); }

3.2.2 Класс System.Array

Как было сказано в начале главы, все массивы языка С# имеют единый базовый класс - System.Array. В данном классе реализован ряд полезных свойств и методов, которые существенно облегчают работу с массивами (табл.3.1)

Page 82: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

83

Таблица 3.1 Основные элементы класса System.Array Элемент Описание Свойства

Length Получает общее число элементов во всех измерениях массива Array.

Rank

Получает ранг (число измерений) массива Array. Например, одно-мерный массив возвращает 1, двухмерный массив возвращает 2 и т д

Методы

BinarySearch(Array, Object)

Выполняет поиск заданного эле-мента во всем отсортированном одномерном массиве

Clear(Array, Int32, Int32)

Присваивает элементам массива значение 0, false или null, в зави-симости от типа элементов

Copy(Array, Array, Int32)

Копирует диапазон элементов из массива Array, начиная с первого элемента, и вставляет его в другой массив Array, также начиная с первого элемента. Длина задается как 32-битовое целое число.

CopyTo(Array, Int32)

Копирует все элементы текущего одномерного массива в заданный одномерный массив начиная с указанного индекса в массиве на-значения. Индекс задается как 32-битовое целое число.

IndexOf(Array, Object)

Выполняет поиск указанного объ-екта внутри всего одномерного массива и возвращает индекс его

Page 83: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

84

первого вхождения.

LastIndexOf(Array, Object)

Выполняет поиск заданного объекта и возвращает индекс его последнего вхождения внутри всего одномерного массива Array.

Reverse(Array) Изменяет порядок элементов во всем одномерном массиве Array наобратный.

SetValue(Object, Int32)

Присваивает значение элементу, находящемуся в указанной позиции одномерного массива Array. Индекс задается как 32-битовое целое число.

Sort(Array) Сортирует элементы во всем од-номерном массиве Array.

Рассмотрим пример использования методов класса System.Array в задаче сортировки, печати массива и поиска по массиву. static void Main(string[] args) {

int[] myArr = { 4, 5, -18, 2, 3, 0, 2 ,-1 }; Console.WriteLine(" Исходный массив: "); foreach (int x in myArr) Console.Write("\t{0}",x); // Реализуем сортировку массива Con- sole.WriteLine("Отсортированный массив:"); Array.Sort(myArr); foreach (int x in myArr) Console.Write("\t{0}",x); // Организуем поиск числа 12 Console.WriteLine("\п\пПоиск числа:"); int search = Array.BinarySearch(myArr, 12); Console.WriteLine("Число 12 находится на {0}

позиции",search+1); Console.ReadLine();

Page 84: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

85

3.3 Класс System.Random

При работе с массивами удобно использовать средства языка, которые позволяют генерировать последовательность случайных чисел. Библиотека языка C# содержит встроенный класс Random, определенный в пространстве имен System.

Следует однако оговорить, что класс Random не является по сути своей истинным генератором случайных чисел, его точнее можно назвать генератором псевдослучайных чисел. Каждый экземпляр класса Random содержит некоторое внутреннее состояние, и при вызове метода Next данный метод использует это состояние для возврата числа, которое на первый взгляд будет казаться случайным. После этого внутреннее состояние меняется таким образом, чтобы при следующем вызове метода Next он возвратил другое так же кажущееся случайным число, не равное числу, которое было возвращено ранее.

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

Итерации в цикле по генерированию пройдут настолько быстро, что системное время не успеет измениться по их окончании; таким образом, все экземпляры Random получат в качестве начального состояния одинаковое значение и поэтому возвратят одинаковое псевдослучайное число.

Как было сказано, к использованию системного времени в качестве начального значения приводит конструктор без па-раметров, имеющий синтаксис следующего вида:

Random имя = new Random(); Можно в явном виде установить начальное значение для

последовательности с помощью конструктора второго типа: Random имя = new Random (начальное значение);

Page 85: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

86

Следует отметить, что установка одинакового начального значения приводит к одинаковым псевдослучайным после-довательностям.

Методы класса Random позволяют генерировать числа по определенным требованиям (табл.3.2)

Таблица 3.2. Методы класса Random Метод Описание

Next() Возвращает неотрицательное случайное целое число.

Next(Int32 Возвращает неотрицательное случайное целое число, которое меньше максимально допустимого значения.

Next(Int32, Int32)

Возвращает случайное целое число в указанном диапазоне.

NextDouble() Возвращает случайное число с пла-вающей запятой, которое больше или равно 0,0 и меньше 1,0.

Пример применения методов класса приведен далее. static void Main(string[] args) {

const int initRnd = 77; Random realRnd = new Random(); Random repeatRnd = new Random(initRnd); // Случайные числа в диапазоне [0, 1) Console.WriteLine(" случайные числа в диапазо

не[0,1)"); for(int i = 1; i <= 5; i++) {

Cosole.WriteLine(" Число " + i + "= " + realRnd.NextDouble());

} // Случайные числа в диапазоне [min, max] int min = -100, max = -10;

Page 86: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

87

Console.WriteLine(" случайные числа в диапазо не [" + min +"," + max + "]");

for(int i = 1; i <= 5; i++) {

Console.WriteLine("Число " + i + "= + realRnd.Next(min, max));

} // Случайный массив байтов byte[] bar = new byte[10]; repeatRnd.NextBytes(bar); Console.WriteLine("Maccue случайных чисел в диапазоне [0, 255]");

for(int i = 0; i < 10; i++) { Console.WriteLine("Число " + i + "= " + bar[i]); }

} 3.4 Программирование под Windows: меню, таблицы,

регулятор «вверх-вниз»

Для того, чтобы удобно организовать работу с массивами, необходимо рассмотреть еще несколько компонент, пре-доставленных средой Visual Studio.

В первую очередь поговорим о возможности создавать меню в приложении и основные правила его использования. Для того, чтобы разместить компонент «Главное меню» на форме, необходимо выбрать в панели инструментов пункт MainMenu. Каждый пункт меню имеет тип MenuItem, при за-полнении пункта меню автоматически меняется его свойство Text. Для удобной работы программы необходимо скоррек-тировать свойство Name каждого пункта меню.

Пункт меню может быть доступным или нет (свойство Enabled), видимым или нет (свойство Visible), отмечен или нет (свойство Checked). Каждое из этих свойств принимает значения true или false.

Page 87: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

88

Среда сама создает шаблон обработчика пункта меню при двойном клике на этот пункт.

Для вывода информации в табличном виде удобно ис-пользовать компонент DataGridView.

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

Таблица 3.3 Свойства компонента DataGridView Свойство Описание

BackgroundColor Получает или задает цвет фона для объекта DataGridView.

BorderStyle Получает или задает стиль границы для объекта DataGridView.

ColumnCount Получает или задает число столбцов, отображаемых в объекте DataGridView.

Columns Возвращает коллекцию, содержа-щую все столбцы элемента управ-ления.

CurrentRow Возвращает строку, содержащую текущую ячейку.

Enabled Указывает, включен ли элемент управления.

Font Получает или задает шрифт текста, отображаемого объектом DataGridView.

Height Высота данного элемента управления в пикселях.

Item[Int32, Int32]

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

Page 88: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

89

Name Возвращает или задает имя элемента управления.

ReadOnly

Получает или задает значение, ука-зывающее, может ли пользователь изменять ячейки элемента управ-ления DataGridView.

RowCount Получает или задает число строк, отображаемых в элементе управления DataGridView.

Rows Получает коллекцию, содержащую все строки в элементе управления DataGridView.

Visible

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

Width Возвращает или задает ширину элемента управления.

Поскольку от данного компонента требуется только хра-нить и получать информацию, данных свойств будет достаточно.

Из методов хотелось бы выделить методы, связанные с подбором оптимальной ширины и высоты столбцов. Это методы AutoResizeColumn (номер строки) и AutoResizeRow (номер столбца).

Для того, чтобы устанавливать целочисленные значения в некотором диапазоне используется компонент NumericUpDown. Для того, чтобы работать с этим компонентом, достаточно установить его максимальное значение (свойство Maximum), минимальное значение (свойство Minimum). Для доступа к текущему значению используется свойство Value.

Page 89: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

90

Рассмотрим пример, который включает в себя все выше-описанные компоненты. Задача состоит в том, чтобы ввести двумерный массив одним из двух способов: случайным образом или с клавиатуры. Необходимо задать размерность массива. Если размерность не указана, по умолчанию будет сгенерирован массив 5*5. Задача состоит в поиске максимального элемента массива. Так же приложении должно давать возможность очистки всех полей и закрытия формы при выборе пункта меню.

Форма имеет внешний вид, представленный на рис. 3.5

Рис. 3.5 Окно приложения

Компоненты, присутствующие на форме, значение поля Name и

выполняемые функции представлены в табл. 3.4 Таблица 3.4

Компоненты и их значения Тип компонента Name Функции label Info 1 Содержит текст «Число

строк» label Info 2 Содержит текст «Число

Page 90: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

91

столбцов» label res Содержит итоговое

значение квадрата числа

DataGridView myArray Поле для ввода/вывода массива

Nume r i cUpDowncol Задает число строк Nume r i cUpDownrow Задает число столбцов MainMenu Ввести размер-

ность Позволяет считать зна-чения из полей col и rowи отрисовывает таблицу

сгенерировать Г енерирует матрицу случайным образом

выполнить Ищет максимальный элемент

выход Закрывает окно прило-жения

Очистить все Очищает все поля в окнеприложения

Текст программы с комментариями приведен далее. namespace primer2 {

public partial class Forml : Form { public Form1() {

InitializeComponent(); }

static int colCount = 5, rowCount = 5; // число строк и столбцов по умолчанию

private void очиститьВсеToolStripMenuItem_Click (object sender, EventArgs e) //выбран пункт меню «Очистить все»

Page 91: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

92

myArray.Rows.Clear(); //очистка myArray.Columns.Clear(); row.Value = 1; // значения для списка «вверх/вниз» col.Value = 1; вычислитьToolStripMenuItem.Enabled = false; //пока не введен массив, обработка недоступна

}

private void ввестиРазмерностьToolStripMenuItem_Click

(object sender, EventArgs e) {

colCount = (int) col.Value; // узнаем число строк и столбцов rowCount = (int)row.Value; myArray.RowCount = colCount; // устанавливаем эти значения myArray.ColumnCount = rowCount; myArray.Width = panel1.Width; for (int i = 0;i<myArray.Columns.Count; i++) /* перерисовываем таблицу в соответствии с полученными значениями*/ {

myArray.AutoResizeColumn(i); } вычислитьToolStripMenuItem.Enabled = true; // обработка становится доступна

}

private void сгенерироватьToolStripMenuItem_Click

(object sender, EventArgs e) {

myArray.RowCount = colCount; myArray.ColumnCount = rowCount; Random rand = new Random();

Page 92: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

93

// создаем генератор случайных чисел for (int i = 0; i<myArray.Columns.Count; i++) //перерисовываем таблицу {

myArray.AutoResizeColumn(i); } for (int i = 0; i<myArray.Columns.Count; i++) {

for (int j=0; j<myArray.RowCount; j++) { myArray[i, j].Value = rand.Next(0, 10); //заполняем таблицу

} } вычислитьToolStripMenuItem.Enabled = true; myArray.ReadOnly = true; //нет возможности менять таблицу вручную

}

private void вычислитьToolStripMenuItem_Click (object sender, EventArgs e)

{ // найдем максимальный элемент в массиве

int max = Convert.ToInt32(myArray[0,0].Value); int nextNum = 0; for (int i = 0; i<myArray.Columns.Count; i++) {

for (int j = 0; j < myArray.RowCount; j++) { nextNum = Convert.ToInt32

(myArray[i,j].Value); if (max <= nextNum) {

max = nextNum; //запоминаем максимум } }

} MessageBox.Show("максимальный элемент " +

max.ToString()); //вывод с помощью MessageBox

Page 93: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

94

private void Form1_Load (object sender, EventArgs e)

{ Bbi4ucnuTbToolStripMenuItem.Enabled = false;

}

private void 3akpbiTbToolStripMenuItem_Click (object sender, EventArgs e)

{ Close(); //закрываем окно приложения

} } }

3.5 Контрольные вопросы

1. Дайте определение массива и поясните его. 2. Чем ступенчатый массив отличается от двумерного? От

одномерного? 3. Сколько размерностей может иметь массив? 4. С помощью какого класса можно реализовать работу с

массивами? 5. Назовите основную проблему класса Random и пред-

ложите пути ее решения. 6. Приведите пример работы с четырехмерным массивом.

3.6 Лабораторная работа №3

Реализуйте работу с одномерным массивом. Массив вво-дится с клавиатуры в поле textBox или генерируется случайным образом. Размерность массива - 10 элементов. В случае некорректного ввода информировать пользователя об ошибке. Лишить пользователя возможности изменять сгенерированный массив. В текстовые поля или в метки вывести результа

Page 94: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

95

ты работы программы. Предусмотреть возможность очистки всех полей формы. Продублировать все функции с использованием класса Array. Дополнительные массивы заводить запрещено.

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

2. В массиве из вещественных элементов найти сумму положительных элементов, произведение между мак-симальным и минимальным элементами. Отсортировать массив по убыванию.

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

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

5. В массиве из целочисленных элементов найти номер минимального элемента, сумму элементов перед первым и последним нулевыми элементами. Преобразовать массив так, чтобы в его начале были расположены элементы, большие 0, а в конце - меньшие 0 в порядке их следования в исходном массиве.

6. В массиве из вещественных элементов найти номер минимального по модулю элемента, сумму модулей элементов массива, расположенных перед первым и последним отрицательными элементами. Удалить из массива все элементы, лежащие в диапазоне [a,b]. Диа-пазон вводится пользователем.

Page 95: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

96

7. В массиве из целочисленных элементов найти номер максимального по модулю элемента, сумму элементов массива, в диапазоне [a,b]. Диапазон вводится пользо-вателем. Преобразовать массив так, чтобы все нули были вынесены в начало массива, а остальные элементы располагались за нулевыми в порядке их следования в исходном массиве.

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

9. В массиве из вещественных элементов найти количество элементов больших С (вводится пользователем), сумму элементов массива, расположенных перед первым и последним отрицательными элементами. Упорядочить массив по возрастанию модулей

10. В массиве из вещественных элементов произведение элементов, расположенных на четных местах, сумму элементов массива, расположенных до минимального в массиве. Отсортировать отдельно четные и нечетные элементы.

3.7 Лабораторная работа №4

Пользуясь примером из п. 3.4 реализовать работу с дву-мерным массивом.

1. Дана целочисленная матрица. Определить, сколько строк не содержат ни одного нуля, сколько чисел встречаются в матрице более одного раза.

2. Дана целочисленная матрица. Определить, сколько столбцов содержат нулевые элементы, номер строки с максимальным числом одинаковых элементов.

3. Дана целочисленная матрица. Найти произведение эле-ментов в тех строках, которые не содержат нулей, мак

Page 96: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

97

симальный элемент в столбце, содержащем минимум по всей матрице

4. Дана целочисленная матрица. Найти сумму элементов в тех столбцах, которые не содержат ни одного нуля, сумму элементов, расположенных выше главной диагонали.

5. Дана целочисленная матрица. Найти количество строк, среднее арифметическое которых больше заданного, номер строки, имеющей максимальный элемент.

6. Дана целочисленная матрица. Найти номер первой строки, содержащей более одного нуля, сумму элементов строк, содержащих только один отрицательный элемент.

7. Дана целочисленная матрица. Осуществить циклический сдвиг на n элементов вправо или влево.

8. Дана целочисленная матрица. Найти номер столбца с самой длинной возрастающей серией элементов, номер строки, сумма элементов в которой не превосходит k.

9. Дана целочисленная матрица. Найти минимум среди элементов диагоналей, произведение элементов, распо-ложенных ниже побочной диагонали.

10. Дана целочисленная матрица. Найти количество отри-цательных элементов в строках, которые содержат не более 2 нулей, номер первого столбца, содержащего минимальных по матрице элемент.

Page 97: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

98

ГЛАВА 4 СТРОКИ И СИМВОЛЫ 4.1 Типы данных для хранения текстовой информации

4.1.1 Символьный тип

Символьный тип данных, тип char, предназначен для хранения отдельных символов в кодировке UNICODE. Подробно представление символов рассматривалось в главе 1, разделе 1.2.2. Символьному типу соответствует класс Char пространства имен System. Данный класс содержит ряд методов, удобных для работы с символами (табл. 4.1)

Таблица 4.1 Основные методы класса Char Методы Описание

Equals(Char) Возвращает значение, указывающее, равен ли данный экземпляр указанному объекту Char.

IsDigit(Char) Показывает, относится ли указанный символ Юникода к категории деся-тичных цифр.

IsLetter(Char) Показывает, относится ли указанный символ Юникода к категории букв Юникода.

IsLower(Char) Показывает, относится ли указанный символ Юникода к категории букв нижнего регистра.

IsNumber(Char) Показывает, относится ли указанный символ Юникода к категории цифр.

IsPunctuation(Cha r)

Показывает, относится ли указанный символ Юникода к категории знаков препинания.

IsSeparator(Char) Показывает, относится ли указанный символ Юникода к категории знаков- разделителей.

Page 98: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

99

IsUpper(Char) Показывает, относится ли указанный символ Юникода к категории букв верхнего регистра.

ToLower(Char) Преобразует значение символа Юни-кода в его эквивалент в нижнем реги-стре.

ToString() Преобразует значение этого экземпляра в эквивалентное ему строковое представление.

ToUpper(Char) Преобразует значение символа Юникода в эквивалентный символ верхнего регистра.

С помощью представленных методов удобно ограничить ввод только чисел, только букв, только знаков препинания и т.д. Рассмотрим пример ввода только чисел. На рис. 4.1 приведены коды символов. Красным выделены те коды, которые не являются кодами чисел, зеленым - коды чисел.

Page 99: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

100

Рис. 4.1 Коды символов в кодировке языка Таким образом, обработка вводимых символов и ввод

только чисел будет определяться следующим кодом: if ((e.KeyChar<=47||e.KeyChar>=58)&& e.KeyChar!=8) {

e.Handled = true; } Следует так же помнить, что конкатенация нескольких

символов дает строку, например, string str = ‘д' + ‘o'+'m'; // результирующая строка имеет значение «дом»

Рассмотрим пример использования типа char решении задачи. public static void Main() {

char chA = 'A'; char ch1 = '1';

Page 100: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

101

string str = "test string"; Console.WriteLine(chA.CompareTo('B')); /* Результат : "-1" ( означает 'A' is 1 less

than 'B')*/ Console.WriteLine(chA.Equals('A')); // Результат : "True" Con-

sole.WriteLine(Char.GetNumericValue(ch1)); // Результат :"1" Console.WriteLine(Char.IsControl('\t')); // Результат : "True" Console.WriteLine(Char.IsDigit(ch1)); // Результат : "True" Console.WriteLine(Char.IsLetter(',')); // Результат : "False" Console.WriteLine(Char.IsLower('u')); // Результат : "True" Console.WriteLine(Char.IsNumber(ch1)); // Результат : "True" Console.WriteLine(Char.IsPunctuation('.')); // Результат : "True" Console.WriteLine(Char.IsSeparator(str, 4)); // Результат : "True" Console.WriteLine(Char.IsSymbol('+')); // Результат : "True" Console.WriteLine(Char.IsWhiteSpace(str,

4)); // Результат: "True Console.WriteLine(Char.Parse("S")); // Результат : "S" Console.WriteLine(Char.ToLower('M')); // Результат : "m" Console.WriteLine('x'.ToString()); // Результат :"x" }

4.1.2 Массивы символов

Отдельные символы можно объединить в массив, поскольку последовательность символов удовлетворяет всем

Page 101: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

102

признаками массива. Как и любой другой массив, массив сим-волов строится на основе базового класса System.Array. class Class1 {

static viod Main() {

char[] a = {‘a','r','r','a','y'}; // непосредственная инициализация char[] b = “My array”.ToCharArray(); /* применение метода, который разбивает строку на символы*/ print(“ массив а”,а); Array.Reverse(a); print(“ массив b”,b); print(“ измененный массив а”,а);

}

public static void print(srting info,Array ar)

{ Console.WriteLine (info); foreach (object x in ar) {

Console.WriteLine (x); } Console.WriteLine (“\n”);

} } 4.1.3 Тип string

Тип string предназначен для работы со строками, представляющими собой совокупность символов, представ-ленный в кодировке UNICODE. Данному типу данных соот-ветствует базовый класс System.String.

Описывать строковые переменные можно одним из приведенных ниже способов: string s1;

Page 102: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

103

/* объявлена переменная , которая пока в себе не содержит ничего */

string s2 = “my string”; // строка объявлена и проинициализирована string s3 = new string(‘ ‘, 20); /* строк проинициализирована последователь -

ностью из 20 пробелов */ char[] ar={‘f','r','f'}; /* массив , необходимый для инициализации

строки */ string s4 = new string (ar); /* строка проинициализирована как массив

символов*/ Со строками можно совершать арифметические операции,

такие как присваивание (=), проверка на равенство (==), проверка на неравенство (!=), обращение к элементу строки по его индексу ([ ]), конкатенация строк (+). Как было сказано в разделе «Типы данных», строки относятся к ссылочному типу данных, однако в случае строк на равенство проверяются не ссылки, а значения строковых переменных.

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

Как было сказано выше, типу данных string соответ-ствует класс String пространства имен System. В данном классе реализован ряд методов, полезных при работе со строками (табл.4.2)

Таблица 4.2 Элементы класса System.Srting Название Описание Compare(string strA, string strB)

Статический метод, сравнивает строку strA со строкой strB.

Page 103: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

104

Возвращает положительное зна-чение, если строка strA больше строки strB; отрицательное зна-чение, если строка strA меньше строки strB; и нуль, если строки strA и strB равны. Сравнение выполняется с учетом регистра

Equals(string value) Возвращает логическое значение true, если вызывающая строка со-держит ту же последовательность символов, что и строка value. Выполняется порядковое сравнение с учетом регистра

Concat(string str0, string str1); Комбинирует отдельные экземпляры

строк в одну строку (конкатенация) Contains(string value)Метод, который позволяет опре-

делить, содержится ли в строке определенная подстрока (value)

StartsWith(string value)

Возвращает логическое значение true, если вызывающая строка на-чинается с подстроки value. В противном случае возвращается логическое значение false.

EndsWith(string value)

Возвращает логическое значение true, если вызывающая строка оканчивается подстрокой value. В противном случае возвращает логическое значение false.

IndexOf(string value)

Находит первое вхождение заданной подстроки или символа в строке. Если искомый символ или подстрока не обнаружены, то возвращается значение -1

Page 104: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

105

LastIndexOf(stringvalue)

Находит последнее вхождение за-данной подстроки или символа в строке. Если искомый символ или подстрока не обнаружены, то воз-вращается значение -1

Split(params char[] separator)

Вызывающая строка разделяется на составные части. В итоге воз-вращается массив, содержащий подстроки, полученные из вызы-вающей строки. Символы, ограни-чивающие эти подстроки, переда-ются в массиве separator. Если массив separator пуст или ссы-лается на пустую строку, то в ка-честве разделителя подстрок ис-пользуется пробел.

Trim() Из вызывающей строки удаляются начальные и конечные пробелы.

Insert(int startln- dex, string value)

Используется для вставки одной строки в другую, где value обо-значает строку, вставляемую в вы-зывающую строку по индексу startIndex. Метод возвращает получившуюся в итоге строку.

Remove(int startIn-dex, int count)

Из строки удаляется количество символов, определяемое параметром count, начиная с места, ука-зываемого по индексу startIndex.

Replace(string old- Value, string newVa- lue)

Все вхождения строки oldValue в вызывающей строке заменяются строкой newValue

ToUpper() Делает заглавными все буквы в вызывающей строке.

Page 105: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

106

ToLower() Делает строчными все буквы в вы-зывающей строке.

Substring(int star- tIndex, int length)

Извлекается подстрока, состоящая из количества символов, определяемых параметром length, начиная с места, обозначаемого параметром startlndex.

Пример использования методов приведен далее . static void Main(string[] args) {

// Сравним первые две строки string s1 = " это строка";

string s2 = " это текст , а это строка "; if (String.CompareOrdinal(s1, s2) != 0)

{ Console.WriteLine(" Строки s1 и s2 не равны "); }

if (String.Compare(s1, 0, s2, 13, 10, true)==0) { Console.WriteLine(" При этом в них есть оди-

наковый текст"); } // Конкатенация строк Console.WriteLine(String.Concat("\n" + " Один,

два ","три, четыре")); // Поиск в строке // Первое вхождение подстроки if (s2.IndexOf(" это ") != -1) {

Console.WriteLine(" Слово \"это\" найдено в строке, оно "+ "находится на: {0} позиции", s2.IndexOf("это"));

} // Последнее вхождение подстроки if (s2.LastIndexOf(" это") != -1) {

Page 106: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

107

Console.WriteLine(" Последнее вхождение слова \"это\" находится" + "на {0} позиции", s2.LastIndexOf("это"));

} // Поиск из массива символов char[] myCh = {'Ы','х','т'}; if (s2.IndexOfAny(myCh) != -1) { Console.WriteLine("OguH из символов из массива ch

"+ "найден в текущей строке на позиции {0}",s2.IndexOfAny(myCh));

} /* Определяем начинается ли строка с заданной

подстроки */ if (s2.StartsWith("это текст") == true) {

Console.WriteLine("Подстрока найдена!"); } // Определяем содержится ли в строке подстрока // на примере определения ОС пользователя string myOS = Environment.OSVersion.ToString(); if (myOS.Contains("NT 5.1")

{ Console.WriteLine("Ваша операционная система

Windows XP"); }

else {

if {

myOS.Contains("NT 6.1")) } Console.WriteLine("Ваша операционная

система Windows 7"); }

Console.ReadLine(); }

Page 107: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

108

Очень удобным в использовании является метод Split, который разделяет строку, формируя из одной строки массив типа string[]. Например, char[] separators = new

char[] {' ', ',', '.'};

// сформировали массив разделителей string[] words = text.Split(separators); /* сформировали массив строк, каждый следую

щий элемент массива формируется после встречи любого из разделителей массива separator */

4.2 Строки типа StringBuilder

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

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

Для того, чтобы использовать класс StringBuilder, необходимо создать экземпляр класса одним из способ, при-веденных далее.

StringBuilder sb1 = new StringBuilder(); // создается пустая строка длиной 16 байт StringBuilder sb2 = new StringBuild- er(“Hi!”);

Page 108: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

109

/* выделяется объем для хранения строки из 3 символов, строка проинициализирована */

StringBuilder sb1 = new StringBuilder(100); /* выделяется объем для хранения строки из100 символов, строка не проинициализирова- на*/ StringBuilder sb1 = new StringBuilder(“HI!”,

100); /* выделяется объем для хранения строки из 100

символов, первые 3 символов строки проинициа- лизированы */

StringBuilder sb1 = new StringBuild- er((“Hello!”,1,4, 100);

// выделяется объем для хранения строки из 100 символов, строка заполняется с первого символа подстрокой из из 4 символов: «ello»

Наиболее важные свойства класса StringBuilder - Length (показывает длину строки, содержащуюся в объекте в данный момент) и Capacity (показывает максимальную длину строки, которая может поместиться в выделенную для объекта память).

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

В дополнение к тому объему памяти, выделяемому изна-чально, StringBuilder имеет свойство удваивать свою емкость, когда происходит переполнение, а новое значение емкости не установлено явно.

Максимальная эффективность класса StringBuilder становится очевидна, когда рассматриваются методы работы с текстом (табл.4.3)

Page 109: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

110

Таблица 4.3 Методы для работы с текстом класса StringBuilder Метод Описание Append() Добавляет строку к текущей строке

AppendFormat() Добавляет строку, сформированную всоответствии со спецификаторомформата

Insert() Вставляет подстроку в строку Remove() Удаляет символ из текущей строки

Replace() Заменяет все вхождения символадругим символом или вхожденияподстроки другой подстрокой

ToString() Возвращает текущую строку в видеобъекта System. String

Рассмотрим пример использования экземпляра класса StringBuilder. static void Main(string[] args) {

StringBuilder sb = new StringBuilder("Привет мир"); sb.Append("!"); sb.Insert(7, "компьютерный "); Console.WriteLine(sb); // заменяем слово sb.Replace(" мир", "world"); Console.WriteLine(sb); // удаляем 13 символов, начиная с 7-го sb.Remove(7, 13); Console.WriteLine(sb); // получаем строку из объекта StringBuilder string s = sb.ToString(); Console.WriteLine(s); }

Page 110: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

111

ГЛАВА 5 ФАЙЛЫ 5.1 Понятие файла

Файл - это именованная информация на внешнем носителе. Файл имеет имя и расширение. Расширение позволяет идентифицировать, какие данные и в каком формате хранятся в файле. Под работой с файлами подразумевается:

• создание файлов; • удаление файлов; • чтение (ввод) данных - передача данных с внешнего

устройства в оперативную память; • запись (вывод) данных - передача данных из оперативной

памяти на внешнее устройство; • изменение параметров файла (имя, расширение'...); • другое. Обмен данными между файлами и оперативной памятью

реализуется в помощью подсистем ввода-вывода и классов библиотеки .NET. Обмен осуществляется с помощью потоков. Под потоком пока будем понимать передачу данных от источника к приемнику. Использование потоков позволяет сделать работу более надежной вне зависимости от передаваемых типов данных. Логически поток представляет собой последовательность бит, синтаксис работы с потоком не зависит от типа устройства, с которым происходит обмен.

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

Page 111: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

112

Рис. 5.1. Работа с буфером оперативной памяти при записи в файл Операцию чтения из файла отличает от операции записи

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

Page 112: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

113

в случае, если программист забудет закрыть файл при осуще-ствлении записи, информация, попавшая в буфер, при условии что тот не до конца заполнился при финальной итерации про-цедуры записи, может быть потеряна.

Для поддержки работы потоков библиотека .NET со-держит иерархию классов, определенных в пространстве System.IO. Классы позволяют работать с файлами в разнооб-разных режимах. Краткая информация о классах пространства System.IO приведена в табл.5.2

Таблица 5.2 Классы пространства имен System.IO Класс Описание

BinaryReader / BinaryWriter

Считывает / записывает примитивные типы данных как двоичные значения в заданной кодировке.

Directory

Предоставляет статические методы для создания, перемещения и пере-числения в каталогах и вложенных каталогах.

DirectoryInfo

Предоставляет методы экземпляра класса для создания, перемещения и перечисления в каталогах и подката-логах

FileStream Предоставляет Stream в файле, поддерживая синхронные и асин-хронные операции чтения и записи.

StreamReader / StreamWriter

Реализует объект TextReader / TextWriter, который считывает / записывает символы из потока байтов в определенной кодировке.

StringReader / StringWriter

Реализует TextReader / TextWriter считывает / записывает данные из строки.

Page 113: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

114

Наибольшее распространение получил обмен данными между внешним устройством и оперативной памятью в формах:

• двоичного представления данных (BinaryReader / BinaryWriter),

• байтов (FileStream), • символов (StreamReader / StreamWriter). Формат доступа к файлам так же может быть различным.

Доступ считается последовательным, если очередной элемент можно прочитать (записать) только после завершения анало-гичной операции с предыдущим элементом.

Доступ называется произвольным, когда выполняется чтение (запись) произвольного элемента в файле по заданному адресу.

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

Для того, чтобы начать обсуждение разных типов файлов и особенностей взаимодействия с ними, рассмотрим простейший алгоритм работы, общий для всех файлов. Он условно может быть поделен на 3 шага

1. создание потока и связывание его с определенным фай-лом:

2. обмен данными, 3. закрытие файла. Объекты каждого из классов могут быть созданы в разных

режимах в соответствии со способами работы с ними. Режимы доступа к файлу определяются перечислением FileAccess, определенном в пространстве имен System.IO.

Возможные значения перечислены в табл. 5.3

Page 114: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

115

Таблица 5.3 Значения перечисления FileAccess Значение Описание Read Файл открывается только для чтения Write Файл открывается только для записи ReadWrite Файл открывается для чтения и записи

Возможные режимы открытия файла определяются пе-речисление FileMode, определенном в пространстве имен System.IO, и приведены в табл. 5.4

Таблица 5.4 Возможные значения перечисления FileMode

Значение Описание Append Открыть файл, если он существует. Ус-

тановить указатель на конец файла. Еслифайла с таким именем нет, создать новый.Режим может быть использован только сFileAccess .Write

Create Создать новый файл. Если файл с такимименем существует, стереть его

CreateNew Создать новый файл. Если файл с такимименем существует, сгенерировать ис-ключение IOException

Open Открыть файл.OpenOrCreate

Открыть файл, если он существует. Еслифайла с таким именем нет, создать новый

Truncate Открыть файл. После открытия файл будетобрезан до нулевой длины.

Режимы совместного использования файлов определяются перечислением FileShare, определенном в пространстве имен System.IO, и приведены в табл. 5.5.

Page 115: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

116

Таблица 5.5 Возможные значения перечисления FileShare Значение Описание None Отклоняет совместное использование

текущего файла. Любой запрос на открытиефайла (данным процессом или другимпроцессом) не выполняется до тех пор, пока файл не будет закрыт

Read Разрешает открытие файла для чтениянескольким пользователям

Write Разрешает открытие файла для записинескольким пользователям

ReadWrite Разрешает открытие файла для чтения изаписи нескольким пользователям

5.2 Работа с файлами 5.2.1 Потоки байтов

Ввод-вывод информации в файлы на уровне байтов осу-ществляется с помощью класса FileStream и определяет набор операций над потоками. Для того, чтобы приложение могло использовать данный класс, обязательно нужно подключить пространство имен System.IO. Основные элементы класса приведены в табл. 5.6

Таблица 5.6 Элементы класса FileStream Элемент Описание BeginRead() / BeginWrite()

Начать ввод/вывод

Close() Закрывает текущий поток и отключает всересурсы

EndRead() / EndWrite()

Ожидание окончания ввода/вывода

Read (Byte [] , Выполняет чтение блока байтов из пото-

Page 116: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

117

Int32, Int32) ка и запись данных в заданный буфер. Write (Byte [],Int32, Int32) Записывает блок байтов в файловый поток. Seek(Int64, SeekOrigin)

Устанавливает текущее положение этогопотока на заданное значение.

CanRead Возвращает значение, определяющее в текущем потоке наличие поддержки опе-раций чтения.

CanSeek Возвращает значение, определяющее втекущем потоке наличие поддержки опе-раций поиска.

CanWrite Возвращает значение, определяющее втекущем потоке наличие поддержки опе-раций записи.

Length Возвращает длину потока в байтах.

SetLength(Int64 )Устанавливает длину этого потока на за-данное значение.

Для определения режимов доступа к файлу, способа ра-боты с файлом используются перечисления, приведенные вы-ше.

Рассмотрим пример работы с файлами с помощью класса FileStream.

class Test { public static void Main() { // определяем файлы для чтения и записи string

pathSource = @"c:\tests\source.txt"; string pathNew = @"c:\tests\newfile.txt"; try { using (FileStream fsSource = new File- Stream(pathSource, FileMode.Open, FileAc- cess.Read))

Page 117: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

118

// читаем исходный файл в массив байтов byte[] bytes = new byte[fsSource.Length]; int numBytesToRead = (int)fsSource.Length; int numBytesRead = 0;

while (numBytesToRead > 0) { /* при чтении возвращаем число от 0 до

numBytesToRead*/ int n = fsSource.Read(bytes, numBytesRead,

numBytesToRead); // Прекращаем , когда достигли конца файла if (n

== 0) break; numBytesRead += n; numBytesToRead -= n; }

numBytesToRead = bytes.Length; /* записываем последовательность байтов в

другой FileStream.*/ using (FileStream fsNew = new File- Stream(pathNew, FileMode.Create, FileAc- cess.Write))

{ fsNew.Write(bytes, 0, numBytesToRead);

} } }

catch (FileNotFoundException ioEx) { Console.WriteLine(ioEx.Message); }

} 5.2.2 Потоки символов

Для того, чтобы организовать работу с текстовыми файлами удобно использовать потоки StreamReader и StreamWriter. Классы, реализующие работу с данными потоками, обеспечивают достаточную функциональность и на

Page 118: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

119

ходятся в пространстве имен System.IO. Табл. 5.7 содержит основные элементы для работы с классом StreamWriter.

Таблица 5.7 Основные элементы для работы с классом StreamWriter Элемент Описание

NewLine Возвращает или задает признак конца строки, по умолчанию данным признаком является (\r\n)

Close() Закрывает текущий StreamWriter объекта и основной поток.

Flush() Очищает все буферы для текущего средства записи и вызывает запись всех данных буфера в основной поток.

Write( тип дан-ных)

Записывает в поток представление типа данных, указанного в скобках

WriteLine( тип данных)

Записывает в поток представление типа данных, указанного в скобках, за которым следует признак конца строки

Табл. 5.8 содержит основные элементы для работы с классом StreamReader.

Таблица 5.8. Основные элементы для работы с классом StreamReader Элемент Описание

Close()

Закрывает объект StreamReader и ос-новной поток и освобождает все системные ресурсы, связанные с устройством чтения

Peek() Возвращает следующий доступный символ, но не использует его.

Read() Выполняет чтение следующего символа из входного потока и перемещает положение

Page 119: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

120

символа на одну позицию вперед.

ReadBlock(Char [], Int32, Int32)

Считывает указанное максимальное коли-чество символов из текущего потока и за-писывает данные в буфер, начиная с за-данного индекса.

ReadLine() Выполняет чтение строки символов из те-кущего потока и возвращает данные в виде строки.

ReadToEnd() Считывает все символы, начиная с текущей позиции до конца потока.

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

исполняемый файл. В большинстве случаев это каталог ...\bin\Debug данного проекта.

Рассмотрим пример, в котором происходит чтение файла с помощью StreamReader и вывод содержимого на экран. class Test {

public static void Main() { try { // создаем StreamReader чтобы читать из файла . StreamReader sr = new StreamRead- er("TestFile.txt"); {

string line; // Чтение и вывод содержимого файла // пока не дойдем до конца файла while ((line = sr.ReadLine()) != null) {

Console.WriteLine(line); }

Page 120: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

121

} catch (Exception e)

{ // сообщаем об ошибке

Console.WriteLine("The file could not be read:"); Console.WriteLine(e.Message); } } }

Следующий пример иллюстрирует запись информации в текстовый файл. namespace StreamReadWrite {

class Program { static void Main(string[] args) { // создаем SreamWriter для записи в файл StreamWriter sw = new StreamWri- ter("CDriveDirs.txt"); sw.WriteLine(“Hello!”); sw.Close();

// Читаем из файла , который создали только что string line = ""; using (StreamReader sr = new StreamRead-

er("CDriveDirs.txt")) {

while ((line = sr.ReadLine()) != null) {

Console.WriteLine(line); } }

} } }

Page 121: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

122

5.2.3 Двоичные потоки

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

Работа с файлами такого типа осуществляется с помощью классов BinaryReader и BinaryWriter. Они так же определены в пространстве имен System.IO.

Наиболее значимые элементы класса BinaryReader приведены в табл.5.9

Таблица 5.9 Элементы класса BinaryReader Элемент Описание Close() закрывает поток и освобождает ресурсы

ReadBoolean() считывает значение bool и перемещает указатель на один байт

ReadByte() считывает один байт и перемещает ука-затель на один байт

ReadChar() считывает значение char, то есть один символ, и перемещает указатель на столькобайтов, сколько занимает символ в текущей кодировке

ReadDecimal() считывает значение decimal и перемещает указатель на 16 байт

ReadDouble() считывает значение double и перемещает указатель на 8 байт

ReadInt16() считывает значение short и перемещает указатель на 2 байта

ReadInt32() считывает значение int и перемещает указатель на 4 байта

Page 122: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

123

ReadInt64() считывает значение long и перемещает указатель на 8 байт

ReadSingle() считывает значение float и перемещает указатель на 4 байта

ReadString() считывает значение string. Каждая строка предваряется значением длиныстроки, которое представляет 7-битное целое число

PeekChar() Возвратить следующий символ без пе-ремещения указателя в потоке.

Read(массив) Считать поток байтов, сохранить в массиве, который передается как параметр

Класс BinaryWriter так же содержит ряд полезных ме-

тодов, приведенных в табл. 5.10 Таблица 5.10 Методы класса

BinaryWriter

Метод Описание Close() закрывает поток и освобождает ресурсы Flush() очищает буфер, дописывая из него ос-

тавшиеся данные в файл Seek () устанавливает позицию в потоке Write() записывает данные в поток

Рассмотрим пример использования двоичных потоков для работы с бинарными файлами. static void Main() {

BinaryWriter dataOut; int i = 10; double d = 1023.56; bool b = true; string str = " Это текст "; // Открыть файл для ввода try

Page 123: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

124

{ dataOut = new BinaryWriter(new File- Stream("C:/testData",FileMode.Create));

} catch (IOException ex) {

Console.WriteLine(" Ошибка открытия файла: " + ex.Message);

return; } // Записать данные в файл try {

Console.WriteLine(" Запись " + i); dataOut.Write(i); Console.WriteLine(" Запись " + d); dataOut.Write(d); Console.WriteLine(" Запись "+b); dataOut.Write(b); Console.WriteLine(" Запись "+str); dataOut.Write(str);

catch (IOException ex)

Console.WriteLine(" Ошибка ввода -вывода: " + ex.Message);

return; } finally {

dataOut.Close(); }

} }

Page 124: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

5.3 Работа с каталогами

Для работы с каталогами в пространстве имен System.IO предназначены сразу два класса: Directory и DirectoryInfo.

Начнем рассмотрение данных классов с класса Directory. Он предоставляет ряд методов для управления каталогами. Наиболее полезные методы приведены в табл. 5.11

Таблица 5.11 Методы класса Directory Метод Описание

CreateDirectory(path) создание каталог по указанномупути path

Delete(path) удаление каталог по указанномупути path

Exists(path) определение, существует ли каталогпо указанному пути path. Еслисуществует, возвращается true,если не существует, то false

GetDirectories(path) получение список каталогов в ка-талоге path

GetFiles(path) получение список файлов в каталогеpath

Move(sourceDirName, destDirName)

перемещение каталог

GetParent(path)

получение родительского каталога

Класс DirectoryInfo по своему функционалу схож с классом Directory, однако для работы с классом DirectoryInfo требуется создать экземпляр класса и вызывать требуемые методы через него. Элементы класса DirectoryInfo приведены в табл.5.12

124

Page 125: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

125

Таблица 5.12 Элементы класса DirectoryInfo Элементы описание Create () создание каталогCreateSubdirectory(p ath)

создание подкаталог по указанному пути path

Delete() Удаление каталог Exists Получение информации о том,

существует ли каталог GetDirectories() Получение списка каталогов GetFiles() Получение списка файловMoveTo(destDirName) перемещение каталог Parent получение родительского каталога Root получение корневого каталога

Рассмотрим на примерах использование этих классов. Далее приведен пример получения списка файлов и подкаталогов, расположенных на диске C. static void Main() {

string dirName = "C:\\"; if (Directory.Exists(dirName)) { Console.WriteLine(" Подкаталоги :"); string[] dirs = Directory.GetDirectories (dirName); foreach (string s in dirs) {

Console.WriteLine(s); } Console.WriteLine(); Console.WriteLine(" Файлы:"); string[] files = Directo-

ry.GetFiles(dirName); foreach (string s in files) {

Page 126: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

126

Console.WriteLine(s);

} Поскольку символ ‘\' в языке играет довольно разнооб-

разные роли, необходимо правильно использовать его при об-ращении к какой-либо директории. Для корректной работы возможен один из двух вариантов:

• либо использование двойного слеша: "C: \ \", • либо использование ординарного слеша, но тогда перед

всем путем должен ставиться знак @, например, @"C:\Program Files"

Рассмотрим пример, иллюстрирующий создание каталога. static void Main() {

string path = @"C:\SomeDir"; string subpath = @"program\myProg"; DirectoryInfo dirInfo = new DirectoryIn- fo(path); if (!dirInfo.Exists) // проверяем, нет ли такой директории // если директория существует,

// то будет сгенерировано сообщение об ошибке {

dirInfo.Create(); } dirInfo.CreateSubdirectory(subpath); } Для того, чтобы получить информацию о каталоге, вос-

пользуемся классом DirectoryInfo. static void Main() {

string dirName = "C:\\Program Files"; DirectoryInfo dirInfo = new DirectoryIn- fo(dirName);

Page 127: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

127

Console.WriteLine("Название каталога: {0}", dirInfo.Name); Console.WriteLine("Полное название каталога: {0}", dirInfo.FullName); Console.WriteLine("Время создания каталога: {0}", dirInfo.CreationTime); Console.WriteLine("Корневой каталог: {0}", dirInfo.Root); } Удаление каталога с помощью стандартного метода Delete

сопряжено с возможной ошибкой: Если мы просто применим метод Delete к непустой папке, в которой есть какие-нибудь файлы или подкаталоги, то приложение нам выбросит ошибку.

Для решения существует перегруженный вариант метода Delete , который принимает логическую переменную и по-зволяет удалить непустой каталог.

dirInfo.Delete (true); Рассмотрим пример удаления каталога.

static void Main() { string dirName = @"C:\SomeFolder";

try { DirectoryInfo dirInfo = new DirectoryIn- fo(dirName); dirInfo.Delete(true); }

catch (Exception ex) { Console.WriteLine(ex.Message); }

} Для того, чтобы переместить каталог, удобно использовать

методы класса DirectoryInfo. При перемещении каталога важно помнить, что перемещение будет возможно, если новый каталог не существует!

Page 128: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

128

static void Main() {

string oldPath = @"C:\SomeFolder"; string newPath = @"C:\SomeDir"; DirectoryInfo dirInfo = new DirectoryIn- fo(oldPath); if (dirInfo.Exists && Directory.Exists(newPath) == false) {

dirInfo.MoveTo(newPath); } }

5.4 Программирование под Windows: richTextBox, диалоговые окна

Работа с файлами предусматривает необходимость их открытия, сохранения, а работа с текстовыми файлами допол-нительно требует менять шрифт, размер, цвет шрифта в файлах.

Помимо этого, для вывод текстового файла требуется поле, большее, чем классический textbox. Этот компонент существует и называется richTextBox.

Рассмотрим сначала использование компонента для вывода текста.

Класс richTextBox определен в пространстве имен System и имеет ряд методов и свойств, которые позволяют облегчить работу с ними программиста (табл.5.13)

Таблица 5.13 Элементы класса richTextBox Элемент Описание

Enabled Указывает, включен ли элемент управления.

Fon Шрифт, используемый для отобра-жения текста на элементе управле-ния

Page 129: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

129

Lines Возвращает или задает строки текста в текстовом поле.

MaxLength

Возвращает или задает максимальное количество символов, можно вводить или вставлять в элемент управления поле форматированного текста

ReadOnly

Возвращает или задает значение, указывающее, является ли текст в текстовом поле доступно только для чтения

Text Возвращает или задает текущий текст в поле форматированного текста.

Visible

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

AppendText(String) Добавляет текст в конец текущего текста в текстовом поле.

Clear() Удаляет весь текст из элемента управления текстовым полем.

LoadFile(String)

Загружает текст в формате RTF (RTF) или стандартный текстовый файл ASCII в RichTextBox элемента управления.

Refresh()

Принудительно создает условия, при которых элемент управления делает недоступной свою клиентскую область и немедленно перерисовывает себя и все дочерние элементы.

SaveFile(String) Сохраняет содержимое RichTextBox в формате RTF файл форматированного текста.

Show() Отображает элемент управления.

Page 130: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

130

RichTextBox предоставляет методы, которые предос-тавляют функциональные возможности для открытия и сохра-нения файлов. LoadFile Метод позволяет загружать в элемент управления существующий текстовый файл формата RTF или ASCII. Данные можно также загрузить из уже открытого потока данных. SaveFile Позволяет сохранить файл в формате RTF или ASCII текст.

Для того, чтобы организовать сохранение, открытие файла, изменение шрифта, цвета, загрузку изображений, используются диалоги. Всего выделяют 6 видов диалогов:

• класс ColorDialog - представляет общее диалоговое окно, в котором отображаются доступные цвета и эле-менты управления, позволяющие пользователю опре-делять собственные цвета ,

• класс FontDialog - предлагает выбрать шрифт среди шрифтов, установленных на локальном компьютере,

• класс OpenFileDialog - отображает диалоговое окно, позволяющее пользователю открыть файл,

• класс PageSetupDialog - позволяет изменять параметры печати для страницы, включая поля и ориентацию бумаги,

• класс PrintDialog - позволяет выбирать принтер и определять, какие разделы документа должны быть на-печатаны из приложения,

• класс SaveFileDialog - запрашивает у пользователя местоположение для сохранения файла.

На данный момент необходимо узнать, каким образом приложение будет осуществлять вызов требуемого диалога. Для этого достаточно использовать метод ShowDialog, опре-деленный у всех диалогов, приведенных выше. ShowDialog позволяет трансформировать окно в окно модального типа (то есть, пользователь обязан совершить действие для закрытия данного диалогового окна). О возможных значениях

Page 131: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

131

DialogResult подробно рассказывалось в главе 2 разделе 2.2.5. Иными словами, синтаксис вызова диалога имеет сле-

дующий вид if ( имя диалога.ShowDialog() == DialogRe- sult. требуемое значение) {операторы;}

Для OpenFileDialog и SaveFileDialog необходимо за-поминать имя файла, которое указал пользователь для сохранения или открытия. Имя выбранного файла хранится в свойстве FileName, определенном у данных диалогов.

Рассмотрим пример, который включает в себя все выше-описанные компоненты. Задача состоит в том, чтобы заполнить richTextBox из файла или ввести вручную, создать диалоги для выбора шрифта и цвета, скопировать в другой richTextBox только четные строки исходного текста, сохранить результат в текстовом файле.

Форма имеет внешний вид, представленный на рис. 5.2.

Рис. 5.2 Окно приложения Компоненты, присутствующие на форме, значение поля

Name и выполняемые функции представлены в табл. 5.14

Page 132: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

132

Таблица 5.14 Компоненты и их значения Тип компо нента

Name Функции

RichTextBox input Ввод текста с клавиа-туры или чтение из текстового файла

RichTextBox output Хранение обработан-ного текста

ColorDialog colorDialog1 Выбор цвета в input OpenFileDialog openFileDialog1 Открытие файла SaveFileDialog saveFileDialog1 Сохранение файла из

output FontDialog fontDialog1 Выбор шрифта для

input MainMenu создать Делает input дос-

тупным для ввода текста

открыть Вызов openFileDialog1

сохранить Вызов saveFileDialog1

выход Закрытие приложения Задача1 Обработка текста из

input Изменить цвет Вызов colorDialog1 Изменить шрифт Вызов fontDialog1

Текст программы с комментариями приведен далее. namespace primer3 {

public partial class Forml : Form { public Form1() {

InitializeComponent();

Page 133: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

133

}

private void BbixogToolStripMenuItem_Click (object sender, EventArgs e) {

Close(); }

private void co3gaTbToolStripMenuItem_Click (object sender, EventArgs e)

{ input.ReadOnly = false; input.Clear(); // очистили, если что-то было output.Clear();

}

private void открытьToolStripMenuItem_Click (object sender, EventArgs e)

{ input.Clear(); /*очистили для того, чтобы ввести в чистое поле */ output.Clear(); if (openFileDialog1.ShowDialog() == DialogResult.OK) { string fName = openFileDia- log1.FileName; input.Text = Sys- tem.IO.File.ReadAllText(fName); // загрузили }

}

private void сохранитьToolStripMenuItem_Click

Page 134: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

134

(object sender, EventArgs e) { if (saveFileDialog1.ShowDialog() == Di- alogResult.OK)

{ string fName = openFileDia- log1.FileName; System.IO.File.WriteAllText(fName, output.Text); // записали }

}

private void задача1ToolStripMenuItem_Click (object sender, EventArgs e)

{ int n = input.Lines.Count(); int j =1; for (int i = 0; i <n; i++) { if (i % 2 == 0) // если строка четная

{ output.AppendText(input.Lines [i]);

// переписали ее output j++;

output.AppendText("\n"); // перешли на новую строку в output }

} }

private void изменитьЦветToolStripMenuItem_Click (object sender, EventArgs e)

{ if (colorDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) {

Page 135: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

135

input.ForeColor = colorDia- logl.Color; // выбрали цвет }

}

private void изменитьШрифтToolStripMenuItem_Click (object sender, EventArgs e)

{ if (fontDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)

{ input.Font = fontDialog1.Font; //выбрали шрифт }

} }

} 5.5 Контрольные вопросы

1. Поясните принцип работы буфера при работе с файлами. 2. Какой класс осуществляет работу с двоичными потоками? 3. Для чего определен класс BinaryReader? 4. Какие особенности имеет работа с символьными файлами? 5. Приведите алгоритм работы с файлом любого типа. 6. Проиллюстрируйте принцип работы с каталогами. На

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

5.6 Лабораторная работа №5

Приложение считывает текстовый файл, выводит его в неизменном виде в одно окно. Измененный вариант текста выводится во второе окно. Предоставить возможность откры

Page 136: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

136

вать исходный файл, сохранять измененный файл, менять шрифт, цвет текста с помощью диалоговых окон.

1. Написать программу, которая читает текст из файла, выводит его на экран, меняя местами два соседних слова.

2. Написать программу, которая читает текст из файла и определяет, сколько слов состоят более чем из 5 букв.

3. Написать программу, которая читает текст из файла и выводит на экран только цитаты, заключенные в кавычки.

4. Написать программу, которая читает текст из файла, выводит его на экран, заменяя числа от 0 до 9 словами «ноль»... «девять», начиная каждое предложение с новой строки.

5. Написать программу, которая читает текст из файла, находит там самое длинное слово и определяет, сколько раз данное слово встречается в тексте.

6. Написать программу, которая читает текст из файла и выводит на экран только те предложения, которые состоят из заданного количества слов.

7. Написать программу, которая читает текст из файла, выводит сначала вопросительные, затем восклицательные сообщения.

8. Написать программу, которая читает текст из файла и выводит на экран сообщения в обратном порядке.

9. Написать программу, которая читает текст из файла, выводит на экран предложения в порядке уменьшения знаков пунктуации в предложении.

10. Написать программу, которая читает текст из файла и меняет все гласные буквы на прописные.

Page 137: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

137

ГЛАВА 6 ПРОСТЕЙШИЕ КЛАССЫ

6.1 Основные понятия

Класс - это тип данных, определяемый пользователем. Класс как правило является моделью реального объекта или процесса, то есть он представляет собой логически связанную структуру. Элементы класса - это данные и функции, которые эти данные обрабатывают.

Класс - это обобщенное понятие, определяющее харак-теристики и поведение некоторого множества объектов. Для того, чтобы работать с классом, необходимо выделить отдельные объекты или экземпляры класса. Для каждого объекта выделяется область памяти, необходимая для хранения всех полей (данный) этого объекта. Кроме того, в классе могут присутствовать статические элементы, определенные в единственном экземпляре. Для всех экземпляров класса. Статические данные - это данные класса, все остальные поля - данные экземпляра класса.

Все функциональные элементы класса хранятся в един-ственном экземпляре. Для работы с данными в классе должны быть определены методы класса, экземпляры класса содержат методы экземпляра.

Помимо методов в состав класса могут входить следующие элементы:

1. константы - предназначены для хранения неизменяемых значений класса,

2. поля - предназначены для хранения данных класса, 3. методы - предназначены для реализации вычислений или

иных действий класса или экземпляра класса, 4. свойства - предназначены для определения характеристик

класса по способам получения данных и возможности их чтения,

5. конструкторы -предназначены для инициализации эк-земпляров класса,

Page 138: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

138

6. деструкторы - определяют действия, которые выпол-няются при уничтожении экземпляров класса,

7. индексаторы - обеспечивают возможность доступа к элементам класса по порядковому номеру,

8. операции - задают операции над объектами с помощью стандартных знаков операции,

9. события - предназначены для определения уведомлений, генерируемых классом,

10. типы - внутренние для класса типы данных. Написание и использование классов напрямую связано с

понятием объектно-ориентированного программирования и его постулатами.

Объектно-ориентированное программирование (ООП) — подход к программированию, при котором основными кон-цепциями являются понятия объектов и классов.

Ключевыми чертами ООП являются: 1. Инкапсуляция — это принцип, согласно которому любой

класс должен рассматриваться как чёрный ящик — пользователь класса должен видеть и использовать только интерфейсную часть класса (т. е. список декларируемых свойств и методов класса) и не вникать в его внутреннюю реализацию. Поэтому данные принято инкапсулировать в классе таким образом, чтобы доступ к ним по чтению или записи осуществлялся не напрямую, а с помощью методов. Принцип инкапсуляции (теоретически) позволяет минимизировать число связей между классами и, соответственно, упростить независимую реализацию и модификацию классов.

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

Page 139: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

139

вые свойства и методы. Набор классов, связанных от-ношением наследования, называют иерархией.

3. Полиморфизм — это явление, при котором функции (методу) с одним и тем же именем соответствует разный программный код (полиморфный код) в зависимости от того, в каком контексте он вызывается (объектами какого класса или с какими параметрами).

6.2 Реализация класса 6.2.1 Описание класса и его спецификаторы

Описание класса имеет следующий вид: [спецификаторы] class имя_класса [:предки] {тело класса;}

Спецификаторы необходимы для определения свойств класса и доступности класса для других частей программы. Спецификаторы приведены в табл. 6.1

Таблица 6.1 Спецификаторы языка Спецификатор Описание

public Доступ не ограничен protected Доступ только для вложенных классов и

наследников данного класса private

Доступ запрещен. При использовании вовложенных классах, доступ возможен толькоэлементам класса, в который вложен данный

internal Доступ только из данной программы илисборки

abstract Указывает на то, что класс предназначентолько для использования в качестве ба-зового класса других классов.

sealed Указывает на то, что класс не может на-следоваться.

Page 140: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

140

static Объявляет член, который относится к типу, ане к конкретному объекту.

Спецификаторы public, protected, internal, private еще называют спецификаторами доступа. Если спе-цификатор перед классом или его элементом не указан, класс автоматически считается закрытым, а его элементы - недос-тупными извне (то есть, имеют спецификатор internal).

Например, опишем класс «Студент»: public class Student () {}

Для того, чтобы создать экземпляр класса, используется операция new, например Student vasya = new Student(); //создали экземпляр класса

6.2.2 Данные класса

Данные, которые содержатся в классе, могут быть двух типов: переменные или константы. Правила их задания анало-гичны правилам задания переменных и констант, описанным ранее в гл. 1 разделах 1.2.1 и 1.2.2. Переменные, описанные в классе, еще называют полями класса. При описании полей и констант используются спецификаторы, которые определяют особые характеристики полей и констант. Синтаксис задания элемента класса имеет следующий вид: [спецификаторы] [const] тип имя [ = начальное

значение] Список возможных атрибутов приведен в табл. 6.2 Таблица

6.2 Спецификаторы полей и констант

Спецификаторы Описание public private

Задает уровень доступа к типам и их членам.

Page 141: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

141

internal protected

new Явно скрывает член, унаследованный от базового класса.

readonly

Объявляет поле, которому можно при-сваивать значения только в рамках объ-явления или в конструкторе этого же класса.

static

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

volatile

Указывает на то, что поле может быть изменено в программе операционной системой, оборудованием, параллельным потоком и т. д.

При этом следует помнить, что список, приведенный в табл. 6.2, определяет спецификаторы для полей. Для констант список спецификаторов чуть уже: к константам могут приме-няться только спецификаторы public, private, internal, protected, new.

По умолчанию все поля и константы класса считаются закрытыми, то есть по умолчанию они все имеют спецификатор доступа private, если не указано иное.

Доступ к полям класса осуществляется с помощью опе-рации доступа (операция точка). Слева от точки ставится имя экземпляра класса для обычных полей и имя класса для стати-ческих (со спецификатором static). Справа от точки - имя элемента класса. Расширим класс «Студент», описанный ранее. Добавим в него поля и константы, рассмотрим порядок доступа к ним. class Student

{ public string Name = "Noname"; //ФИО

Page 142: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

142

public const string University = "ВГУ"; public int Group = 0; //группа public int Kurs = 1; //Курс double Marks = 0; //средний балл, закрытое поле public static string Faculty = "ПММ"; // статическое поле

} class Class1 {

static void Main() { Student vasya = new Student(); //создали экземпляр класса Console.WriteLine (vasya.Name); // обращение к полю класса Console.WriteLine (Student.University); // обращение к константе ^nsole.WriteLine (Student.Faculty) ; // обращение к статическому полю }

} В примере все поля классы были проинициализированы. В

том случае, если у поля отсутсвует начальное значение, по умолчению компилятор проинициализирует эти поля нулями. Поля со спецификатором readonly преназначены только для чтения и могут быть проинициализированы либо в конструкторе, либо при описании.

6.2.3 Методы класса

Метод - это основной функциональный элемент класса. Именно метод реализует вычисления и любые другие действия, реализуемые классом и его экземплярами. Метод - это за-конченный фрагмент кода, который имеет имя и может вызы-ваться столько раз, сколько будет необходимо. Метод может принимать данные извне, обрабатывать их и возвращать зна

Page 143: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

143

чение назад с помощью оператора return. Синтаксис метода имеет следующий вид:

[спецификаторы] тип имя_метода ([параметры]) {тело метода}

При описании методов возможно использование сле-дующих спецификаторов: public, private, internal, protected, new, static. Помимо этого, методы имеют свои собственные спецификаторы, определяющие в дальнейшем механизмы наследования и полиморфизма. Эти спецификаторы приведены в табл. 6.3

Таблица 6.3 Спецификаторы методов Спецификатор Описание

virtual

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

sealed Указывает на то, что класс не может насле-доваться.

override Обеспечивает новую реализацию виртуаль-ного члена, унаследованного от базовогокласса.

abstract Указывает на то, что класс предназначентолько для использования в качестве базового класса других классов.

extern Указывает на то, что метод имеет внешнюю реализацию.

Чаще всего для методов используется спецификатор public, поскольку пользователь должен иметь возможность работать с классом и его экземплярами в полной мере. Стати-ческие методы, по аналогии со статическими полями, не требуют создания экземпляра класса и могут быть вызваны непо-средственно.

Page 144: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

144

Тип метода определяет тип возвращаемого значения, то есть, переменная какого типа будет вычисляться с помощью данного метода. Если метод не возвращает никакого значение, используется тип void.

Общая схема вызова метода приведена на рис. 6.1

Вызывающая функция передаем

Метод данные

получаем return ... Вызов метода результат

Рис. 6.1. Вызов метода

Вызывающая функция общается с методом с помощью параметров. Область видимости параметра - весь метод. Па-раметры, описанные в заголовке метода, определяют множество значений аргументов, которые необходимо передавать в метод. Для того, чтобы вызвать метод, необходимо использовать операцию вызова (операция выглядит как круглые скобки). Например,

имя_метода ([список параметров]); Пара: имя метода и список параметров задают сигнатуру

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

Рассширим класс «Студент», добавив в него методы по-лучения и заполнения поля со средним баллом (оно защищено от обращения к нему напрямую) class Student

{ public string Name = "Noname"; //ФИО

Page 145: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

145

public const string University = "ВГУ"; public int Group = 0; //группа public int Kurs = 1; //Курс double Marks = 0; //средний балл, закрытое поле public static string Faculty = "ПММ"; // статическое поле

public double GetMarks() {

//метод возвращает поле типа double, // поэтому он имеет тип double return Marks;

}

public void SetMarks(double newMarks) {

// метод устанавливает значение, // поэтому имеет тип void Marks = newMarks;

} }

class Class1 { static void Main() { Student Vasya = new Student(); //создали экземпляр класса Vasya.SetMarks(4.5); // заполнили защищенное поле // с помощью метода SetMarks insole . WriteLine (Vasya. GetMarks ()); // вывели значения поля Marks }

}

Page 146: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

146

6.2.4 Ключевое слово this

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

Например, изменим метод SetMarks, включив в него клю-чевое слово this. public void SetMarks(double Marks)

{ // параметр, передаваемый в метод, //имеет то же имя, // что и поле класса this.Marks = Marks;

} 6.2.5 Конструкторы

Конструкторы предназначены для инициализации объекта. Они вызываются автоматически при вызове операции new. Имя конструктора совпадает с именем класса.

• Конструктор отличается от метода по следующим па-раметрам:

• Конструктор не возвращает значений (даже значений типа void),

• Класс может иметь несколько конструкторов, которые отличаются друг от друга набором параметров.

• Класс может не иметь ни одного конструктора. В этом случае компилятором будет вызван конструктор по умолчанию, который присвоит полям, которые не были инициализированы значение 0 (для типов-значений) и null (для ссылочных типов).

Конструктор без параметров считается конструктором по умолчанию.

Page 147: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

147

Расширим класс «Студент», включив в него несколько конструкторов:

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

Student {

public string Name = "Noname"; //ФИО public const string University = "ВГУ"; public int Group = 0; //группа public int Kurs = 1; //Курс double Marks = 0;

//средний балл, закрытое поле public static string Faculty = "ПММ";

// статическое поле

public Student() // конструктор по умолчанию { // поскольку все поля заполнены //значениями по умолчанию, //данный конструктор имеет пустое тело

} public Student(string Name, int Group) {

// заполнили часть полей this.Name = Name; this.Group = Group;

} public Student(string Name, int Group, int

Kurs) {

// заполнили все поля this.Name = Name; this.Group = Group; this.Kurs = Kurs;

} public double GetMarks()

Page 148: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

148

{ return Marks;

} public void SetMarks(double Marks) {

this.Marks = Marks; }

} class Classl {

static void Main() { Student Vasya = new Student();

//конструктор по умолчанию Console.WriteLine (Vasya.Name); Student Masha = new Student(“Маша", 4);

//заполним часть полей Console.WriteLine (Masha.Name); Student Petya = new Student(“neTH", 1,

24); // заполним все поля Console.WriteLine (Petya.Name); } }

Очевидно, что все конструкторы должны иметь разные сигнатуры. Существует возможность вызвать конструктор внутри конструктора. Например, public Student(string Name, int Group, int Kurs):this (Name, Group) {

// заполнили все поля this.Kurs = Kurs;

} После двоеточия находится конструкция-инициализатор.

Инициализатор всегда выполняется раньше тела конструктора. То есть, сначала будет вызван конструктор, заполняющий поля «Имя» и «Группа», а потом будет заполнено поле «Курс».

Page 149: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

149

6.2.6 Свойства

Свойства служат для организации доступа к полям класса. Как правило, свойства определяются для закрытых полей

класса и имеют следующий синтаксис: [спецификаторы] тип имя_свойства {

[get код _ доступа ] [set код _ доступа ] }

Значения спецификаторов свойства аналогичны специ-фикаторам класса. Однако, ввиду основного назначения свойств, они чаще всего используются со спецификатором public.

Код доступа представляет собой блоки операторов, которые выполняются при получении (код доступа get) или установке (код доступа set) свойства. Свойство может иметь одну и ветвей (get или set). Если не определено свойство get, то поле называется полем только для записи, если не определено свойство set, то поле называется полем только для записи. Перепишем методы GetMarks и SetMarks класса «Студент », используя свойства. class Student

{ public string Name = "Noname"; //ФИО public const string University = "ВГУ"; public int Group = 0; //группа public int Kurs = 1; //Курс double Marks = 0;

//средний балл, закрытое поле public static string Faculty = "ПММ"; // статическое поле

public Student() // конструктор по умолчанию { }

Page 150: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

150

public Student(string Name, int Group) {

// заполнили часть полей this.Name = Name; this.Group = Group;

}

public Student(string Name, int Group, int Kurs)

{ // заполнили все поля this.Name = Name; this.Group = Group; this.Kurs = Kurs;

}

public double marks { get {

return Marks; } set {

Marks = value; }

} }

class Class1 { static void Main() { Student Petya = new Student(“neT4", 1, 24); // заполним все поля Console.WriteLine (Petya.Name); Petya.marks = 2.6; //воспользовались свойством }

Page 151: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

151

6.3 Контрольные вопросы

1. Каковы постулаты объектно-опиентированного про-граммирования?

2. Что такое класс и чем класс отличается от экземпляра класса?

3. Какое назначение имеет спецификатор static? 4. Назовите и поясните уровни доступаи модификаторы,

которые их определяют. 5. Что такое свойство? Какие проблемы программирования

решаются с помощью ствойств? 6. Что такое метод? Приведите синтаксис задания метода и

опишите алгоритм вызова метода.

6.4 Лабораторная работа №6

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

1. Описать класс, реализующий десятичный счетчик, ко-торый может увеличивать или уменьшать свое значение на единицу в заданном диапазоне. Предусмотреть инициализацию счетчика значениями по умолчанию и произвольными значениями. Счетчик имеет два метода: увеличения и уменьшения, — и свойство, позволяющее получить его текущее состояние. При выходе за границы диапазона выбрасываются исключения. Написать программу, демонстрирующую все разработанные эле-менты класса.

2. Описать класс, представляющий треугольник. Преду-смотреть методы для создания объектов, перемещения на плоскости, изменения размеров и вращения на за

Page 152: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

152

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

3. Построить описание класса, содержащего информацию о почтовом адресе организации . Предусмотреть воз - можность раздельного изменения составных частей адреса и проверки допустимости вводимых значений. В случае недопустимых значений полей выбрасываются исключения. Написать программу, демонстрирующую все разработанные элементы класса.

4. Составить описание класса для вектора, заданного ко-ординатами его концов в трехмерном пространстве. Обеспечить операции сложения и вычитания векторов с получением нового вектора (суммы или разности), вычисления скалярного произведения двух векторов, длины вектора, косинуса угла между векторами. Написать программу, демонстрирующую все разработанные элементы класса.

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

6. Составить описание класса для представления времени. Предусмотреть возможности установки времени и из-менения его отдельных полей (час, минута, секунда) проверкой допустимости вводимых значений. В случае недопустимых значений полей выбрасываются исклю-чения. Создать методы изменения времени на заданное

Page 153: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

153

количество часов, минут и секунд. Написать программу, демонстрирующую все разработанные элементы класса.

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

8. Описать класс «файл», содержащий сведения об имени, дате создания и длине файла. Предусмотреть инициа-лизацию с проверкой допустимости значений полей. В случае недопустимых значений полей выбрасываются исключения. Описать метод добавления информации в конец файла и свойства для получения состояния файла. Написать программу, демонстрирующую все разра-ботанные элементы класса.

9. Описать класс «комната», содержащий сведения о мет-раже, высоте потолков и количестве окон. Предусмотреть инициализацию с проверкой допустимости значений полей. В случае недопустимых значений полей вы-брасываются исключения. Описать методы вычисления площади и объема комнаты и свойства для получения состояния объекта. Написать программу, демонстри-рующую все разработанные элементы класса.

10. Описать класс «цветная точка». Для точки задаются координаты и цвет. Цвет описывается с помощью трех составляющих (красный, зеленый, синий). Предусмотреть различные методы инициализации объекта с проверкой допустимости значений. Допустимым диапазоном для каждой составляющей является [0, 255]. В случае недопустимых значений полей выбрасываются ис-ключения. Описать свойства для получения состояния объекта и метод изменения цвета. Написать программу,

Page 154: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

154

демонстрирующую все разработанные элементы класса.

ГЛАВА 7 СТРУКТУРЫ И ПЕРЕЧИСЛЕНИЯ

7.1 Структуры

Структура - это тип данных, соответствующий группе типов-значений, то есть структура предназначена для непо-средственного хранения значений элементов, а не ссылок на них.

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

Характерные особенности структуры обуславливают на-правленность ее использования: в структурах, как правило, объявляется небольшое количество полей, с которыми удобно работать, как со значениями, что, в свою очередь, позволяет избавиться от затрат ресурсов на динамическое выделение па-мяти.

Для того чтобы описать структуру, используется сле-дующий синтаксис:

[атрибуты] [спецификаторы] struct имя_структуры [:интерфейсы]

{тело структуры} Спецификаторы определяют свойства структуры и ее

доступность для других элементов программы. В качестве

спецификаторов, определяющих работу со структурой, ис-

пользуются спецификаторы, представленные в табл. 7.1 Таблица

7.1 Спецификаторы для работы со структурой

Спецификаторы Описание protected Доступ только из данной структуры internal Доступ только из данной программы private Только для вложенных структур, доступ

Page 155: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

155

только для структур, вложенных в данную

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

Структуры не могут быть абстрактными и по умолчанию все структуры бесплодны.

При описании структуры нельзя задавать значения полей по умолчанию (компилятор присваивает значимым полям структуры нулевые значения, а ссылочным - значения null).

Рассмотрим пример создания структуры. namespace ConsoleApplication1 {

// Создадим структуру struct UserInfo {

public string Name; public byte Age;

public UserInfo(string Name, byte Age) {

this.Name = Name; this.Age = Age;

}

public void WriteUserInfo() {

Console.WriteLine(" Имя: {0}, возраст: {1}",Name,Age);

} }

class Program { static void Main() { UserInfo user1 = new UserInfo("Alex", 26); Console.Write("user1: ");

Page 156: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

156

user1.WriteUserInfo(); UserInfo user2 = new UserInfo("Elena",22); Console.Write("user2: "); user2.WriteUserInfo(); Console.ReadLine(); }

} } Наибольшие преимущества можно получить, если работать

со структурами, организованными в виде массива, поскольку структуры относятся к типам-значениям и, как следствие, их представление в виде массива позволяет работать не с группой ссылок, а с массивом, как единственным объектом. Например, UserInfo[] users = new UserInfo[10]; // создали массив типа UserInfo из 10 элементов string name = “”; for (int i=0; i<10: i++) {

name = “ Пользователь” + i.ToSring(); users[i].Name = name; users[i].Age = i*10; }

Помимо стандартных циклов: с фиксированным числом повторений, с постусловием, с предусловием, существует возможность для массива структур применять цикл foreach, например, foreach (UserInfo us in users) {

us.WriteUserInfo (); } 7.2 Перечисления

7.2.1 Создание и работа с перечислениями

Если в ходе написания программы возникает необходимость определить несколько несвязанных констант, то удоб

Page 157: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

157

ней всего использовать средство языка - перечисления. При создании перечисления компилятору не важны значения име-нованных констант, выходящих в него. Для задания перечисления используется следующий синтаксис: [спецификаторы] enum имя_перечисления [:базовый тип]

{тело перечисления;} Например,

enum Menu {Open, Save, Exit}; enum Палитра {красный, зеленый, желтый, синий};

Для каждой из констант, входящих в перечисление, соз-дается персональный идентификатор который для компилятора является ее символическим именем. По умолчанию в роли данного идентификатора выступает порядковый номер типа int, начиная с 0. Но программист может самостоятельно определить данный идентификатор, например, enum Палитра {красный =3 , зеленый, желтый, синий = красный + 6};

В данном случае, константа «красный» имеет идентифи-катор 3, «зеленый» и «желтый» - 4 и 5 соответственно, «синий» - 9. Таким образом, символическое имя каждой следующей именованной константы вычисляется путем прибавления единицы к символическому имени предыдущей константы, если не указано иное. Имена констант внутри перечисления не могут совпадать, а значения идентификаторов могут совпадать.

Спецификаторы перечисления по смыслу аналогичны спецификаторам класса. В качестве спецификаторов могут ис-пользоваться: public, protected, internal, private. По умолчанию в качестве спецификатора доступа используется спецификатор public.

Базовый тип - это тип элементов, на основе которых по-строено перечисление. По умолчанию используется тип int, однако существует возможность задать перечисление иного типа (кроме char), например, byte, short, uint, long,

Page 158: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

158

ulong. Тело перечисления, как было показано ранее, состоит из именованных констант и их символических имен.

Рассмотрим пример перечисления и его использования.

namespace ConsoleApplication10 {

struct Боец { public enum Воинское_Звание {

Рядовой, Сержант, Лейтенант, Майор,

Полковник, Генерал }

public string Фамилия; public Воинское_Звание Звание; }

class Program { static void Main(string[] args) {

Боец; x.Фамилия = "Иванов"; x. Звание = Боец. Воинское_Звание. Сержант; for(int i = 1976; i < 2006; i += 5) {

if(x. Звание <Боец. Воинское_Звание. Генерал) {

++x. Звание; } Console.WriteLine(" Год: {0} {1} {2}", i, x. Звание, x. Фамилия); }

Console.ReadKey(); }

Page 159: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

159

} }

Page 160: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

160

7.2.2 Класс System.Enum

Все перечисления в языке C# являются потомками базового класса System.Enum, который предоставляет ряд полезных методов (табл. 7.2)

Таблица 7.2 Методы класса System.Enum Метод Описание GetName(Type, Object)

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

GetNames(Type) Возвращает массив имен констант в указанном перечислении.

GetValues(Type) Возвращает массив значений констант в указанном перечислении.

IsDefined(Type, Object)

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

GetUnderlyingTyp e(Type)

Возвращает базовый тип заданного пе-речисления.

Например, public class Program {

enum Days {Понедельник, Вторник, Среда, Четверг, Пятница, Суббота, Воскресенье}; public static void Main() {

Type weekdays = typeof(Days); Days wd = Days.Пятница; Console.WriteLine("Члены перечисления Days и их значения:"); foreach(string s in Enum.GetNames(weekdays) ) // получим массив имен констант пере-числения Console.WriteLine( "{0,-12}= {1}", s,

Page 161: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

161

// вывод базового типа Console.WriteLine("Базовый тип членов: {0}\n", Enum.GetUnderlyingType(weekdays)); Console.ReadLine(); }

} 7.3 Контрольные вопросы

1. Расскажите о назначении перечислений и способах ра-боты с ними.

2. Дайте понятие структуры и опишите ее характерные черты.

3. Приведите синтаксис задания структуры. 4. Приведите синтаксис задания перечисления. 5. Какие спецификаторы доступа допустимы в структу

рах? 6. Что такое символическое имя в перечислении и как оно

задается?

7.4 Лабораторная работа № 7

Комментарии к оформлению 1. Создать структуру «Студент», содержащую поля:

• Фамилия и инициалы, • Номер группы • Успеваемость (массив из 5 элементов)

Написать программу, позволяющую выполнять следующие действия:

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Студент», упорядочен по возрастанию номера группы.

• Вывод на экран информации обо всех студентах, если средний балл больше 4,0. Если таких студентов нет, вывести сообщение.

2. Создать структуру «Студент», содержащую поля:

Page 162: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

162

• Фамилия и инициалы, • Номер группы • Успеваемость (массив из 5 элементов)

Написать программу, позволяющую выполнять следующие действия:

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Студент», упорядочен по возрастанию среднего балла.

• Вывод на экран информации обо всех студентах, имеющих оценки 4 или 5. Если таких студентов нет, вывести сообщение.

3. Создать структуру «Студент», содержащую поля: • Фамилия и инициалы, • Номер группы • Успеваемость (массив из 5 элементов)

Написать программу, позволяющую выполнять следующие действия:

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Студент», упорядочен по алфавиту.

• Вывод на экран информации обо всех студентах, имеющих хотя бы одну оценку 2. Если таких сту-дентов нет, вывести сообщение.

4. Создать структуру «Сотрудник», содержащую поля: • Фамилия и инициалы, • Занимаемая должность, • Год поступления на работу.

Написать программу, позволяющую выполнять следующие действия:

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Сотрудник», упорядочен по алфавиту.

Page 163: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

163

• Вывод на экран фамилий работников, стаж которых превышает значение, введенное с клавиатуры. Если таких сотрудников нет, вывести сообщение.

5. Создать структуру «Поезд», содержащую поля: • Название пункта назначения, • Номер поезда, • Время отправления.

Написать программу, позволяющую выполнять следующие действия:

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Поезд», упорядочен по времени отправления.

• Вывод на экран информации о поездах, отправляю-щихся в пункт назначения, введенный с клавиатуры. Если таких поездов нет, вывести сообщение.

6. Создать структуру «Поезд», содержащую поля: • Название пункта назначения, • Номер поезда, • Время отправления.

Написать программу, позволяющую выполнять следующие действия:

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Поезд», упорядочен по номерам поезда.

• Вывод на экран информации о поездах, отправляю-щихся не позже времени, введенного с клавиатуры. Если таких поездов нет, вывести сообщение.

7. Создать структуру «Маршрут», содержащую поля: • Название пункта назначения, • Название начального пункта, • Номер маршрута.

Написать программу, позволяющую выполнять следующие действия:

Page 164: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

164

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Маршрут», упорядочен по номеру маршрута.

• Вывод на экран информации маршрутах, оканчи-вающихся или начинающихся в пункте, введенном с клавиатуры.. Если таких маршрутов нет, вывести сообщение.

8. Создать структуру «Маршрут», содержащую поля: • Название пункта назначения, • Название начального пункта, • Номер маршрута.

Написать программу, позволяющую выполнять следующие действия:

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Маршрут», упорядочен по названию пункта назначения.

• Вывод на экран информации маршрутах, имеющих номер, равный номеру, введенному с клавиатуры. Если таких маршрутов нет, вывести сообщение.

9. Создать структуру «Заметка», содержащую поля: • Фамилия и имя, • Дата рождения, • Номер телефона.

Написать программу, позволяющую выполнять следующие действия:

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Заметка», упорядочен по дате рождения.

• Вывод на экран информацию о владельцах, чьи но-мера телефонов совпадают полностью или частично с номером, введенным с клавиатуры. Если таких номеров нет, вывести сообщение.

10. Создать структуру «Заметка», содержащую поля: • Фамилия и имя,

Page 165: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

165

• Дата рождения, • Номер телефона.

Написать программу, позволяющую выполнять следующие действия:

• Ввод данных в массив с клавиатуры. Массив состоит из 10 элементов типа «Заметка», упорядочен по фамилии.

• Вывод на экран информацию о людях, которые ро-дились не ранее даты, введенной с клавиатуры. Если таких людей нет, вывести сообщение.

ГЛАВА 8. ПОДРОБНОСТИ О КЛАССАХ 8.1 Реализация полиморфизма в классах

Для того чтобы сделать программный код более удобным для восприятия, логично назвать методы по логике заложенных в них алгоритмов. Если класс содержит несколько методов, реализующих одинаковую логику, имена методов могут быть одинаковыми. Это делает программный код более осмысленным. Данная возможность (давать одно и то же имя разным методам класса) называется перегрузкой методов.

Компилятор различает методы один от другого по их сигнатуре (списку параметров). Процесс определения кон-кретного метода называется резолюцией перегрузки. В процессе резолюции участвуют только параметры метода, тип метода при этом не имеет значения. Механизм резолюции можно описать следующим образом:

1. просматривается набор параметров, передаваемых вы-зывающим методом,

2. просматриваются списки параметров методов, имеющих сходное имя,

3. из данных методов выбирается тот, который имеет мак-симальное соответствие по списку параметров,

Page 166: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

166

4. если ни один метод не подходит, генерируется сообщение об ошибке.

Вспомним класс «Студент», который был реализован в главе 6 «Простейшие классы» и дополним его методом работы со средним баллом. Причем создадим два метода с одинаковыми именами: первый метод сравнивает средний балл с заданным пользователем баллом, а второй - со средним баллом, определенным в методе. class Student

{ public string Name = "Noname"; //ФИО public const string University = "ВГУ"; public int Group = 0; //группа public int Kurs = 1; //Курс double Marks = 0;

//средний балл, закрытое поле public static string Faculty = "ПММ";

public double GetMarks() {

return Marks; }

public void SetMarks(double newMarks) {

Marks = newMarks; }

public string Info (double mark) {

if (mark>Marks) { return “Балл меньше заданного”;} else {return “Балл больше заданного”;}

}

public string Info () {

Page 167: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

167

if (4.5 >Marks) { return “Балл меньше 4.5 ”;} else {return “Балл больше 4.5 ”;}

} }

class Classl { static void Main() { Student Vasya = new Student(); //создали экземпляр класса Vasya.SetMarks(4.8); Console.WriteLine (Vasya.Info()); // балл сравнивается с 4,5 Console.WriteLine (Vasya.Info(3,2)); // балл сравнивается с 3,2 }

} Если точного соответствия не найдено, производится

неявное преобразование типов по общим правилам: • bool и char в int. • float в double и т.д. После преобразований выбирается «лучший» метод: тот

метод, который вызывается при наименьшем числе преобразо-ваний. Если путем преобразований не удается вызвать ни один из методов, генерируется сообщение об ошибке.

Перегрузка методов - это одно из наиболее ярких прояв-лений полиморфизма (см. раздел 6.1 главы 6)

8.2 Рекурсивные методы

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

Page 168: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

168

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

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

Рассмотрим пример рекурсивного метода на задаче поиска факториала числа n. В данном случае, ограничением глубины захода в рекурсию будет условие n = 1. long Fact (int n) {

if (n ==1 ) return 1; return (n *fact (n-1)); }

Достоинством рекурсивных методов является их ком-пактность и наглядность. Помимо этого, рекурсивные методы незаменимы при работе со структурами данных (например, с деревьями).

При этом описанная выше работа со стеком иллюстрирует недостаток рекурсивных методов: опасность переполнения стека и расход времени и памяти на повторные вызовы метода и извлечение информации из стека.

8.3 Индексаторы

Индексаторы - это разновидность свойств, рассмотренных в гл. 6. Индексаторы удобны для работы с массивами, описанными в классах и позволяют обращаться к элементам массива, используя имя массива и индекс его элемента в квадратных скобках.

Page 169: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

169

Поскольку индексаторы являются частным случаем свойства, синтаксис задания индексатора аналогичен синтаксису задания свойства. [спецификаторы ] тип this [ список параметров] {

get код доступа set код доступа }

Спецификаторы в задании индексаторов аналогичны спецификаторам свойств. Наиболее распространенный специ-фикатор для индексатора - public.При этом, спецификатор - это необязательный элемент синтаксиса и может отсутствовать.

Код доступа в теле индексатора - это последовательность операторов, которые выполняются при установке значения элемента массива или его получении. В теле индексатора могут присутствовать:

• ветви get и set, • только ветвь get (спецификатор доступен только для

записи), • только ветвь set (спецификатор доступен только для

чтения). Обе ветви в теле индексатора отсутствовать не могут. Список параметров определяет один или несколько ин-

дексов, по которым будет осуществляться обращение к элементам массива. Наиболее распространенным является использование одного индекса целого типа.

В классе «Студент» создадим массив оценок, доступ к которому настроим через индексатор. class Student

{ public string Name = "Noname"; //ФИО public const string University = "ВГУ"; public int Group = 0; //группа public int Kurs = 1; //Курс int[] marks = {2,2,2,2}

Page 170: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

170

//список оценок студента // закрытое поле public static string Faculty = "ПММ";

public int this [int i] {

get { if (i>=0 && i< marks.Length) return marks[i];}

set { if (i>=0 && i< marks.Length) marks[i] = value;

} }

class Class1 { static void Main() { Student Vasya = new Student(); //создали экземпляр класса

for (int i=0; i<4; i++) { Vasya[i] = 5; }

} } Язык дает возможность задавать многомерные индекса-

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

public int this [int i, int j] {...}

Page 171: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

171

8.4 Операции класса 8.4.1 Общие сведения о перегрузке операций

Язык C# позволяет переопределять большинство операций так, чтобы при применении этих операций к экземплярам класса, они выполняли заданные функции. Это дает возможность конструировать выражения из экземпляров пользовательских классов.

Определение собственных операций так же называют перегрузкой операций. Перегрузка операций похожа на обычный метод, рассмотренный в гл.6. Синтаксис перегрузки операции имеет вид: Спецификаторы operator операция {тело операции}

Для перегрузки операций могут использоваться специ-фикаторы static и public. Тело операции представляет собой блок, аналогичный блоку любого из методов.

8.4.2 Перегрузка унарных операций

В классе могут быть объявлены и перегружены следующие унарные операции: + - ! ++ -- true false

Для того, чтобы сообщить компилятору о перегруженной унарной операции используется следующий синтаксис: public static тип operator унарная_операция (параметр) {тело операции}

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

Таблица 8.1 Возвращаемые величины для унарных операций

Page 172: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

172

Операция Возвращаемая величина + Величина любого типа - !

+ + Величина типа того класса, для которогопереопределяется операция - -

False Величина типа bool true

Помимо этого следует помнить о ряде существующих ограничений:

1. операция не должна изменять значение передаваемого операнда,

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

В классе «Студент » добавим операцию, инкремента и декремента для курса студента. class Student {

public string Name = "Noname"; //ФИО public const string University = "ВГУ"; public int Group = 0; //группа public int Kurs = 1; //Курс int[] marks = {2,2,2,2}

//список оценок студента // закрытое поле public static string Faculty = "ПММ";

public Student(string Name, int Group) {

// заполнили все поля this.Name = Name; this.Group = Group;

}

Page 173: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

173

public static Student operator ++ (Student st) {

Student temp = new Student(st.Name, st.Group);

temp.Kurs = st.Kurs + 1 ; return temp

}

public static Student operator -- (Student st) {

Student temp = new Student(st.Name, st.Group);

temp.Kurs = st.Kurs - 1 ; return temp

} }

class Class1 { static void Main() { Student Vasya = new Student(Vasya, 21); // создали экземпляр класса Vasya++;

// поскольку по умолчанию курс для Vasya // был задан, как первый, то // операция инкремента позволила увеличить // его до 2

} } 8.4.3 Перегрузка бинарных операций

Язык позволяет переопределить в классе следующие би-нарные операции: + - * / & | л <<>>==!=><>=<=

Синтаксис объявления бинарной операции следующий: public static тип operator бинарная_операция (па- раметр_1, параметр_2)

Page 174: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

}

174

{тело операции}

Хотя бы один параметр, передаваемый в операцию, должен иметь тип класса, в котором переопределяется операция. Бинарная операция может возвращать величину любого типа. Для операций ==, !=, <, > ,<=, >= обычно возвращается логическое значение. Операции сравнения, проверки на равентство являются наиболее часто переопределяемыми, поскольку они могут обеспечить сравнение экземпляров класса.

В классе «Студент» переопределим операцию > для того, чтобы определить, кто из двух студентов старше. class Student {

public string Name = "Noname"; //ФИО public const string University = "ВГУ"; public int Group = 0; //группа public int Kurs = 1; //Курс int[] marks = {2,2,2,2} //список оценок студента // закрытое поле public static string Faculty = "ПММ";

public Student(string Name, int Group, int Kurs) {

// заполнили все поля this.Name = Name; this.Group = Group; this.Kurs = Kurs;

}

public static bool operator > (Student st1, Student st2) {

if (st1.Kurs > st2.Kurs) {return 1;} else {return 0;}

Page 175: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

175

class Classl { static void Main() { Student Vasya = new Student(Vasya, 21,1); // создали экземпляр класса Student Petya = new Student(Petya, 22,3); // создали экземпляр класса if (Petya > Vasya) // можем сравнить два экземпляра класса {Console.WriteLine (“Петя старше”);} else {Console.WriteLine (“ Вася старше”);}

} } 8.5 Реализация наследования

8.5.1 Общая информация о наследовании классов

Классы в С# могут иметь произвольное количество по-томков и единственного предка. Имя предка класса задается при его описании. Синтаксис задания класса имеет вид: [спецификаторы] class имя_класса [: предки] {тело класса}

Спецификаторы класса подробно были рассмотрены в гл. 6. Хочется заметить, что в качестве предков класса может быть не только класс-родитель, но и интерфейсы.

Создадим класс «Выпускник», который будет наследником класса «Студент», рассмотренного ранее. Экземпляр класса «Выпускник» обладает всем функционалом класса «Студент», но помимо этого реализует еще ряд методов class Student {

public string Name = "Noname"; //ФИО public const string University = "ВГУ";

Page 176: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

176

public int Group = 0; //группа public int Kurs = 1; //Курс double Marks = 0; //средний балл студента // закрытое поле public static string Faculty = "ПММ";

public Student(string Name, int Group) {

// заполнили все поля this.Name = Name; this.Group = Group;

}

public static Student operator ++ (Student st) {

Student temp = new Student(st.Name, st.Group); temp.Kurs = st.Kurs + 1 ;

return temp; }

}

class Graduate : Student { string boss = “”; // Имя научного руководителя, закрытое поле

public Graduate (string boss) {

this.boss = boss; this.Kurs = 4;

}

public Graduate (string boss, string Name, int Group) : base (Name, Group, 4) {

this.boss = boss;

Page 177: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

177

public void Info() {

Console.WriteLine (“Мой руководитель”, this.boss);

} }

class Class1 { static void Main() { Graduate Dima = new Graduate (“Дима”, 10, “Сидоров В.П.”); Dima.Info(); Dima--; //поскольку класс Graduate наследует // функционал класса Student, то все //перегруженные операции так же наследуются // К примеру, сейчас, Dima стал студентом // 3 курса } } Давайте рассмотрим приведенный код более подробно. В классе Graduate введено новое закрытое поле boss,

которое предназначано для хранения имени научного руково-дителя, и метод Info(), который позволяет выводить эту информацию.

Эземпляр класса Graduate использует как свои методы, так и методы, унаследованные от класса-родителя. Но следует помнить о том, что конструкторы в отличие от полей и методов не наследуются, поэтому класс-наследник должен иметь свои собственные конструкторы.

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

Page 178: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

178

При этом вызывается та версия конструктора класса-родителя, которая соответсвует списку передаваемых параметров.

Если возникает необходимость переопределить один из методов класса родителя, необходимо указать спецификатор new перед переопределением метода, а тело метода нужно начать на отсылку к методу класса-родителя с помощью слова base, например, new public void GetMarks() {

base.GetMarks();

} Поскольку работа с полями и методами класса напрямую

связана со спецификаторами доступа. Если в классе-родителе какие-то поля или методы были определены со спецификатором private, то они не будут видны в классе-потомке. Для того, чтобы сделать такие поля закрытыми от доступа извне, но доступными для наследников, следует пользоваться специ-фикатором protected.

8.5.2 Виртуальные методы

Для того чтобы одноименные методы у разных наследников имели разную реализацию, удобно использовать механизм задания виртуальных методов. В этом случае не происходит жесткого связывания между методом и его реализацией. Компилятор понимает, что один и тот же метод у разных на-следников будет обрабатываться по-разному. Для этого суще-ствует ключевое слово virtual, которое ставится перед заго-ловком метода базового класса, например, virtual public void Info() {...}

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

Page 179: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

179

ся механизмом позднего связывания и является средством реализации механизма полиморфизма в языке.

Если приложение содержит виртуальные методы, для его работы создается таблица виртуальных методов Virtual Method Table. Она хранит адреса виртуальных методов, для каждого класса создается своя VMT.

Компилятор осуществляет постоянный доступ к VMT для всех экземпляров класса в процессе работы приложения (компилятор помещает данную информацию автоматически в код компилятора).

Если в классе-наследнике требуется переопределить вир-туальный метод, используется ключевое слово override, на-пример, override public void Info() {...}

Переопределенный метод должен иметь ту же сигнатуру, что и метод виртуальный. Добавим в класс «Студент» метод, печатающий информацию о студенте, а в классе «Выпускник » переопределим его. class Student {

virtual public void Info() {

Console.WriteLine(“{0} \t курс {1}\t группа {2} \n”, Name, Kurs, Group);

} }

class Graduate : Student { override public void Info() { Console.WriteLine(“{0} \t курс {1}\t руководитель {2} \n”, Name, Kurs, boss);

} }

Page 180: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

180

}

class Classl { static void Main() { const int n=3; Graduate[] list_gr = new Graduate[n] ;

list_gr[0] = new Graduate(“Петя”, 12,“Петров В.А.”);

list gr[1] = new Graduate(“Вася”, 14,“Сидоров В.В.”);

list_gr[2] = new Graduate(“Оля”, 15,“Петров В.А.”); foreach (Graduate elem in list_gr) elem.Info(); Student st = new Student (“Маша”,21, 2); st.Info(); }

Результат работы приложения имеет следующий вид:

Петя группа12 руководитель Петров В.А. Вася группа14 руководитель Сидоров В.В Оля группа15 руководитель Петров В.А. Маша группа21 курс 2

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

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

8.6 Абстрактные классы

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

Page 181: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

181

ют смысла, поскольку им не соответствуют реальные объекты. Такие классы называют абстрактными.

Абстрактный класс ценен только теми потомками, которые от него можно породить. Как правило, такой класс содержит набор методов, переопределяемых в каждом из потомков.

Абстрактный класс задает принципы реализации всей иерархии, но сам по себе может не содержать никаких кон-кретных действий.

Если хотя бы один метод класса описан, как абстрактный, абстрактным является весь класс.

Создадим абстрактный класс «Человек », потомком кото-

рого является класс «Студент». abstract class Man {

public abstract void Info(); } class Student: Man {

override public void Info() {

Console.WriteLine(“{0} \t курс {l}\t группа {2} \n”, Name, Kurs, Group);

}

}

class Graduate : Student { override public void Info() {

Console.WriteLine(“{0} \t курс {1}\t руководитель {2} \n”, Name, Kurs, boss);

}

}

Page 182: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

182

Если класс-наследник абстрактного класса не переоп-ределяет все абстрактные методы, то он так же должен описы-ваться, как абстрактный.

8.7 Контрольные вопросы

1. Поясните, какими средствами в языке реализовавается полиформизм.

2. Поясните, какими средствами в языке реализовавается наследование.

3. Что такое абстрактный класс, каково его назначение? 4. Какие унарные операции могут быть переопределены в

классах? 5. Расскажите о виртуальных методах и принципах работы с

ними. 6. Каково назначение индексаторов? 7. Какие виды рекурсии вы знаете?

8.8 Лабораторная работа № 8

Каждый разрабатываемый класс должен содержать сле-дующие элементы: скрытые поля, конструкторы с параметрами и без, методы, свойства, индексаторы, перегруженные операции. Класс должен обеспечивать полный, непротиворечивый интерфейс. При возникновении ошибок должны генерироваться соответствующие сообщения.

1. Описать класс для работы с одномерным массивом целых чисел. Необходимо обеспечивать доступ к отдельным элементам массива с контролем выхода за границы. Реализовать операции поэлементного сложения и вычитания массивов с одинаковой размерностью, опе-рацию умножения и деления массивов на скаляр. Пре-дусмотреть возможность вывода на экран целого массива, его элементов по заданному индексу.

Page 183: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

183

2. Описать класс для работы с одномерным массивом строк фиксированной длины. Необходимо обеспечивать доступ к отдельной строке массива с контролем выхода за границы. Реализовать операции поэлементного сцепления двух массивов с образованием нового массива, операции слияния двух массивов с исключением повторяющихся элементов. Предусмотреть возможность вывода на экран целого массива, его элементов по заданному индексу.

3. Описать класс многочленов от одной переменной, за-даваемый с помощью степени многочлена и массива его коэффициентов. Предусмотреть возможность сложения, вычитания, умножения многочленов с получением нового многочлена, получения коэффициента многочлена по степени переменной, вывода на экран многочлена.

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

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

6. Описать класс «Словарь », позволяющий хранить не-сколько вариантов перевода каждого слова, реализовать доступ по английскому слову, предусмотреть возможность разноформатного вывода.

7. Описать класс «Предметный указатель». Каждый ком-понент указателя состоит из слова и номеров страниц, на которых встречается данное слово. Количество номеров страниц, относящихся к одному слову, может варьироваться от 1 до 10. Предусмотреть возможность

Page 184: МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ПРАКТИЧЕСКИМ ОП obespechenie... · 2018-11-06 · ОП.11 Объектно-ориентированное моделирование

184

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

8. Описать класс «Комплексное число», представляющий комплексное число как комбинацию вещественной и мнимой частей. Предусмотреть возможность сложения, вычитания, умножения, деления нескольких чисел, воз-ведения числа в степень, вывода только вещественной или только мнимой части числа.

9. Описать класс «Колода карт», включающий закрытый массив карт. Карта описывается как пара: номер и масть. Обеспечить возможность вывода карты по номеру, вывода всех карт, выдачи 6 случайных карт.

10. Описать класс, описывающий шестнадцатеричное число, которое хранится в памяти как строка. Реализовать операции сравнения, преобразования в десятичное число, сложения двух восьмеричных чисел с формированием нового числа