Программирование на C# для начинающих. Основные сведения 9785040925193

Первая часть самоучителя по C#, написанного известным российским автором учебников по программированию Алексеем Васильев

181 68 9MB

Russian Pages 592 [586] Year 2023

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

Программирование на C# для начинающих. Основные сведения
 9785040925193

Table of contents :
Оглавление
Введение Язык С# и технология .Net Framework
История создания языка С#
Особенности языка С#
Программное обеспечение
Собственно о книге
Обратная связь
Благодарности
Об авторе
Глава 1 Знакомство с языком С#
Структура программы
Первая программа
Использование среды разработки
Пространство имен
Программа с диалоговым окном
Настройка вида диалогового окна
Окно с полем ввода
Консольный ввод
Считывание чисел
Форматированный вывод
Резюме
Задания для самостоятельной работы
Глава 2 Базовые типы и операторы
Переменные и базовые типы данных
Литералы
Управляющие символы
Преобразование типов
Объявление переменных
Арифметические операторы
Операторы сравнения
Логические операторы
Побитовые операторы и двоичные коды
Оператор присваивания
Сокращенные формы операции присваивания
Тернарный оператор
Приоритет операторов
Примеры программ
Резюме
Задания для самостоятельной работы
Глава 3 Управляющие инструкции
Условный оператор if
Вложенные условные операторы
Оператор выбора switch
Оператор цикла while
Оператор цикла do-while
Оператор цикла for
Инструкция безусловного перехода goto
Перехват исключений
Резюме
Задания для самостоятельной работы
Глава 4 Массивы
Одномерные массивы
Инициализация массива
Операции с массивами
Цикл по массиву
Двумерные массивы
Многомерные массивы
Массив со строками разной длины
Массив объектных ссылок
Параметры командной строки
Резюме
Задания для самостоятельной работы
Глава 5 Статические методы
Знакомство со статическими методами
Перегрузка статических методов
Массив как аргумент метода
Массив как результат метода
Механизмы передачи аргументов методу
Рекурсия
Методы с произвольным количествомаргументов
Главный метод программы
Резюме
Задания для самостоятельной работы
Глава 6 Знакомство с классами и объектами
Базовые принципы ООП
Классы и объекты
Описание класса и создание объекта
Использование объектов
Закрытые члены класса и перегрузка методов
Конструктор
Деструктор
Статические члены класса
Ключевое слово this
Резюме
Задания для самостоятельной работы
Глава 7 Работа с текстом
Класс String
Создание текстового объекта
Операции с текстовыми объектами
Методы для работы с текстом
Метод ToString ()
Резюме
Задания для самостоятельной работы
Глава 8 Перегрузка операторов
Операторные методы
Перегрузка арифметическихи побитовых операторов
Перегрузка операторов сравнения
Перегрузка операторов true и false
Перегрузка логических операторов
Перегрузка операторов приведения типов
Команды присваиванияи перегрузка операторов
Резюме
Задания для самостоятельной работы
Глава 9 Свойства и индексаторы
Знакомство со свойствами
Использование свойств
Знакомство с индексаторами
Использование индексаторов
Двумерные индексаторы
Многомерные индексаторы
Перегрузка индексаторов
Резюме
Задания для самостоятельной работы
Глава 10 Наследование
Знакомство с наследованием
Наследование и уровни доступа
Наследование и конструкторы
Объектные переменные базовых классов
Замещение членов при наследовании
Переопределение виртуальных методов
Переопределение и замещение методов
Переопределение и перегрузка методов
Наследование свойств и индексаторов
Резюме
Задания для самостоятельной работы
Заключение Что будет дальше
Предметный указатель

Citation preview

Васильев А.Н.

ПРОГРАММИРОВАНИЕ

НА

ОСНОВНЫЕ СВЕДЕНИЯ РОССИЙСКИЙ КОМПЬЮТЕРНЫЙ БЕСТСЕЛЛЕР

Москва 2023

УДК 004.43 ББК 32.973.26-018.1 В19

В19

Васильев, Алексей. Программирование на C# для начинающих. Основные сведения / Алексей Васильев. — Москва : Эксмо, 2023. — 592 с. — (Российский компьютерный бестселлер). ISBN 978-5-04-092519-3

В этой книге Алексей Васильев, доктор физико-математических наук и автор популярных российских самоучителей по программированию, приглашает читателей ознакомиться с основами языка C#. Прочитав ее, вы узнаете историю языка, его структуру, ознакомитесь с типами данных и переменными, операторами, циклами и множеством другой полезной информации, необходимой для работы с этим языком. УДК 004.43 ББК 32.973.26-018.1

ISBN 978-5-04-092519-3

© Оформление. ООО «Издательство «Эксмо», 2023

Оглавление

Введение. Язык С# и технология .Net Framework . История создания языка С# . . . . . . . . . . . . Особенности языка С# . . . . . . . . . . . . . . . Программное обеспечение . . . . . . . . . . . . . Собственно о книге . . . . . . . . . . . . . . . . . Обратная связь . . . . . . . . . . . . . . . . . . . . Благодарности . . . . . . . . . . . . . . . . . . . . Об авторе . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. 7 . 7 . 9 12 17 19 19 20

Глава 1. Знакомство с языком С# . . . . . . Структура программы . . . . . . . . . . Первая программа . . . . . . . . . . . . . Использование среды разработки . . . Пространство имен . . . . . . . . . . . . Программа с диалоговым окном . . . . Настройка вида диалогового окна . . . Окно с полем ввода . . . . . . . . . . . . Консольный ввод . . . . . . . . . . . . . . Считывание чисел . . . . . . . . . . . . . Форматированный вывод . . . . . . . . Резюме . . . . . . . . . . . . . . . . . . . . Задания для самостоятельной работы

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

21 22 25 27 31 33 42 45 50 54 57 59 60

Глава 2. Базовые типы и операторы . . . . . . . . . . Переменные и базовые типы данных . . . . . . Литералы . . . . . . . . . . . . . . . . . . . . . . . . Управляющие символы . . . . . . . . . . . . . . . Преобразование типов . . . . . . . . . . . . . . . Объявление переменных . . . . . . . . . . . . . . Арифметические операторы . . . . . . . . . . . . Операторы сравнения . . . . . . . . . . . . . . . . Логические операторы . . . . . . . . . . . . . . . Побитовые операторы и двоичные коды . . . . Оператор присваивания . . . . . . . . . . . . . . Сокращенные формы операции присваивания Тернарный оператор . . . . . . . . . . . . . . . . . Приоритет операторов . . . . . . . . . . . . . . . Примеры программ . . . . . . . . . . . . . . . . . Резюме . . . . . . . . . . . . . . . . . . . . . . . . . Задания для самостоятельной работы . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . .

. . . . . . . . . .

62 63 68 71 72 77 81 85 86 90 100 102 104 105 106 112 113

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

3

Оглавление

Глава 3. Управляющие инструкции . . . . . . Условный оператор if . . . . . . . . . . . . Вложенные условные операторы . . . . . Оператор выбора switch . . . . . . . . . . Оператор цикла while . . . . . . . . . . . . Оператор цикла do-while . . . . . . . . . . Оператор цикла for . . . . . . . . . . . . . Инструкция безусловного перехода goto Перехват исключений . . . . . . . . . . . . Резюме . . . . . . . . . . . . . . . . . . . . . Задания для самостоятельной работы .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

115 116 123 130 142 147 150 156 159 166 168

Глава 4. Массивы . . . . . . . . . . . . . . . . Одномерные массивы . . . . . . . . . . . Инициализация массива . . . . . . . . . Операции с массивами . . . . . . . . . . Цикл по массиву . . . . . . . . . . . . . . Двумерные массивы . . . . . . . . . . . . Многомерные массивы . . . . . . . . . . Массив со строками разной длины . . Массив объектных ссылок . . . . . . . . Параметры командной строки . . . . . Резюме . . . . . . . . . . . . . . . . . . . . Задания для самостоятельной работы

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

171 171 181 183 194 198 208 213 218 223 226 227

Глава 5. Статические методы . . . . . . . . . . . . . . . . . Знакомство со статическими методами . . . . . . . . Перегрузка статических методов . . . . . . . . . . . . Массив как аргумент метода . . . . . . . . . . . . . . Массив как результат метода . . . . . . . . . . . . . . Механизмы передачи аргументов методу . . . . . . Рекурсия . . . . . . . . . . . . . . . . . . . . . . . . . . . Методы с произвольным количеством аргументов Главный метод программы . . . . . . . . . . . . . . . . Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . Задания для самостоятельной работы . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

230 231 238 242 247 254 266 271 277 278 280

Глава 6. Знакомство с классами и объектами . . . . Базовые принципы ООП . . . . . . . . . . . . . . Классы и объекты . . . . . . . . . . . . . . . . . . Описание класса и создание объекта . . . . . . Использование объектов . . . . . . . . . . . . . . Закрытые члены класса и перегрузка методов Конструктор . . . . . . . . . . . . . . . . . . . . . . Деструктор . . . . . . . . . . . . . . . . . . . . . . . Статические члены класса . . . . . . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

282 282 286 289 294 299 303 309 314

4

. . . . . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

Оглавление

Ключевое слово this . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 Задания для самостоятельной работы . . . . . . . . . . . . . . . . . . 330 Глава 7. Работа с текстом . . . . . . . . . . . Класс String . . . . . . . . . . . . . . . . . Создание текстового объекта . . . . . . Операции с текстовыми объектами . . Методы для работы с текстом . . . . . . Метод ToString() . . . . . . . . . . . . Резюме . . . . . . . . . . . . . . . . . . . . Задания для самостоятельной работы

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

333 334 336 344 356 373 378 379

Глава 8. Перегрузка операторов . . . . . . . . . Операторные методы . . . . . . . . . . . . . Перегрузка арифметических и побитовых операторов . . . . . . . . . . . Перегрузка операторов сравнения . . . . . Перегрузка операторов true и false . . Перегрузка логических операторов . . . . Перегрузка операторов приведения типов Команды присваивания и перегрузка операторов . . . . . . . . . . . Резюме . . . . . . . . . . . . . . . . . . . . . . Задания для самостоятельной работы . .

. . . . . . . . . . . . . . . . 441 . . . . . . . . . . . . . . . . 443 . . . . . . . . . . . . . . . . 445

Глава 9. Свойства и индексаторы . . . . . . Знакомство со свойствами . . . . . . . . Использование свойств . . . . . . . . . . Знакомство с индексаторами . . . . . . Использование индексаторов . . . . . . Двумерные индексаторы . . . . . . . . . Многомерные индексаторы . . . . . . . Перегрузка индексаторов . . . . . . . . Резюме . . . . . . . . . . . . . . . . . . . . Задания для самостоятельной работы

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

448 448 456 475 481 493 506 510 518 520

Глава 10. Наследование . . . . . . . . . . . . . . Знакомство с наследованием . . . . . . . . Наследование и уровни доступа . . . . . . Наследование и конструкторы . . . . . . . Объектные переменные базовых классов Замещение членов при наследовании . . . Переопределение виртуальных методов . Переопределение и замещение методов . Переопределение и перегрузка методов .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

523 524 529 535 543 549 553 558 562

. . . . . . . . . .

. . . . . . . . . . . . . . . . 381 . . . . . . . . . . . . . . . . 381 . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

385 404 423 427 432

5

Оглавление

Наследование свойств и индексаторов . . . . . . . . . . . . . . . . . . 565 Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575 Задания для самостоятельной работы . . . . . . . . . . . . . . . . . . 576 Заключение. Что будет дальше . . . . . . . . . . . . . . . . . . . . . . . . . 580 Предметный указатель . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581

Вв ед ен и е ЯЗЫК С# И Т ЕХН ОЛОГИ Я .NET FRAMEWORK

Русская речь не сложнее других. Вон Марга­ дон - дикий человек - и то выучил.

из к/ф «Формула лю бви»

Язык С# уже многие годы неизменно входит в список языков програм­ мирования, самых востребованных среди разработчиков программного обеспечения. Язык является базовым для технологии .Net Framework, разработанной и поддерживаемой корпорацией Microsoft. Именно язы­ ку С# посвящена книга, которую читатель держит в руках.

И стория создания я з ы ка С# История , леденящая кровь. Под маской овцы скрывался лев.

из к/ф «Покровские ворота»

Язык С# создан инженерами компании Microsoft в 1998-2001 годах. Руководил группой разработчиков Андерс Хейлсберг, который до того трудился в фирме Borland над созданием компилятора для языка Pascal и участвовал в создании интегрированной среды разработки Delphi. Язык С# появился после языков программирования С++ и Java. Бога­ тый опыт их использования бьш во многом учтен разработчиками С#.

G)

Н А ЗАМ ЕТ КУ

Си нтаксис языка С# похож н а синтаксис языков С++ и Java. Но сход­ ство внешнее. У языка С# своя ун и кал ьная кон це п ция . В месте с тем м ногие управля ющие инструкци и в языке С# будут знакомы тем , кто п рограм м и рует в С++ и Java .

7

Вв едение Вообще же из трех язы ков п рогра м м и рования С++ , Java и С# исто­ рически первым поя вился язы к С++ . Затем на сцену вы шел язык Java. И уже после этого появился язы к п рограм м и рования С# . Для понимания места и роли языка С# на современном рынке про­ граммных технологий разумно начать с языка программирования С, ко­ торый в свое время стал мощным стимулом для развития программных технологий как таковых. Именно из языка С обычно выводят генеало­ гию языка С#. Мы тоже будем придерживаться классического подхода. Язык программирования С появился в 1 972 году, его разработал Де­ нис Ритчи. Язык С постепенно набирал популярность и в итоге стал одним из самых востребованных языков программирования. Этому способствовал ряд обстоятельств. В первую очередь, конечно, сыграл роль лаконичный и простой синтаксис языка. Да и общая концепция языка С оказалась исключительно удачной и живучей. Поэтому ког­ да встал вопрос о разработке нового языка, который бы поддерживал парадигму объектно ориентированного программирования (ООП), то выбор естественным образом пал на язык С: язык программирова­ ния С++, появившийся в 1 983 году, представлял собой расширенную версию языка С, адаптированную для написания программ с привлече­ нием классов, объектов и сопутствующих им технологий. В свою оче­ редь, при создании языка программирования Java отправной точкой стал язык С++. Идеология языкаjаvа отличается от идеологии языка

С++, но при всем этом базовые управляющие инструкции и операторы в обоих языках схожи.

G)

Н А ЗАМ ЕТ КУ

Язы к п рограм м и рования Java официально появился в 1 995 году и стал популярн ы м благодаря ун иверсал ьности п рограм м , нап и ­ санных на этом языке . Технология , испол ьзуемая в Java, позволяет п исать переноси м ы е п рограм м н ы е коды , что искл юч ител ьно важно при разработке п р ил ожени й для испол ьзован ия в lпternet. Нет ничего удивительного, что при создании языка программирова­ ния С# традиция была сохранена: синтаксис языка С# во многих мо­ ментах будет знаком тем, кто уже программирует на С++ и Java. Хотя такое сходство - внешнее. Языки очень разные, поэтому расслабляться не стоит. Да и базовые синтаксические конструкции в языке С# имеют свои особенности. Все это мы обсудим в книге.

8

Я зык С# и технология .Net Framework

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

из к/ф �Формула лю бви» Язык программирования С#

-

простой, красивый, эффективный и гибкий.

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

G)

Н А ЗАМ ЕТ КУ

Язык С# создавался после появления языков С++ и Java. В С# были учтен ы и по возможности устранены «недостатки » и «недоработки » , которые есть в С++ и Java. Иногда язык С # упоминается как усовер­ шенствованная версия языков С++ и Java, хотя концепции у них со­ вершенно разн ые, так что утверждение довол ьно поверхностно . Кроме собственно преимуществ языка С # , немаловажно и то, что язык поддерживается компанией Microsoft. Поэтому он идеально подходит, чтобы писать программы для выполнения под управлением операцион­ ной системы Windows.



ПОДРОБН ОСТИ

Операционной системой Windows и технологией . Net Framework ком ­ п а н и и Microsoft область применения языка С # не огран ичи вается . Существуют ал ьтернати вные п роекты (такие, например, как М опо ) , позволя ющие выпол нять п рограм м ы , написанные н а языке С#, под управлением операционных систем , отличных от Windows. Вместе с тем мы в кн и ге будем исходить из того , что испол ьзуются « родн ые» средства разработки и операционная система Windows. Как отмечалось выше, язык С# является неотъемлемой частью тех­ нологии (или платформы) .Net Framework. Основу платформы .Net Framework составляет среда исполнения CLR (сокращение от Common Language Runtime) и библиотека классов, которая используется при программировании на языке С#.

9

Вв едение

G)

Н А ЗАМ ЕТ КУ

Платформа .Net Framework позволяет испол ьзовать и иные языки программирования, а не только С# - нап ример, С++ или Visual Basic . Возможности платформы .Net Framework позволяют объединять «В одно целое» п рограммные коды , написанные на разных языках программирования. Это очень мощная технологи я , но для нас инте­ рес представляет написание програм мных кодов на языке С#. Имен­ но особенности и возможности языка С# м ы будем обсуждать в кн иге .

При компилировании программного кода, написанного н а языке С # , соз­ дается промежуточный код. Это промежуточный код реализован на языке M SIL (сокращение от Microsoft Intermediate Language ). Промежуточный код выполняется под управлением системы CLR. Система CLR запускает JIТ-компилятор (сокращение от Just In Time ), который, собственно, и пе­ реводит промежуточный код в исполняемые инструкции.



ПОДРОБН ОСТИ

Файл с программным кодом на языке С# сохраняется с расширени­ ем cs. После компиляции п рограм мы создается файл с расширени­ ем е х е . Но выполнить этот файл можно тол ько на комп ьютере, где установлена система .Net Framework. Такой код называется управля­ емым ( поскол ьку он выполняется под управлением системы CLR) . .

.

Описанная нетривиальная схема компилирования программ с привле­ чением промежуточного кода служит важной цели. Дело в том, что тех­ нология .Net Framework ориентирована на совместное использование программных кодов, написанных на разных языках программирования. Базируется эта технология на том, что программные коды с разных язы­ ков программирования «переводятся� (в процессе компиляции) в про­ межуточный код на общем универсальном языке. Проще говоря, коды на разных языках программирования приводятся «К общему знаменате­ лю�, которым является промежуточный язык M SIL.



ПОДРОБН ОСТИ

П рограм м ы , написанные на Java, тоже компилируются в промежуточ ­ ный байт- код. Байт- код выполняется под управлением ви ртуальной машины Java. Но по сравнени ю с языком С# имеется принци пиал ьное отличие. Байт- код, в который переводится при компиляции Jаvа- про­ грам ма, имеет при вязку к одному языку программирования - языку 10

Я зык С# и технология .Net Framework Java. И в Java схема с промежуточным кодом нужна для обеспечения универсальности программ , поскольку промежуточный байт- код не за­ висит от типа операционной системы (и поэтому переносим ) . Особен­ ность операционной системы учитывается той виртуальной машиной Java, которая установлена на компьютере и выполняет промежуточный байт- код. Промежуточный код, который испол ьзуется в технологии .Net Framework, не привязан к конкретному языку программирования. Например, что при компиляции программы на языке С# , что при ком­ пиляции программы на языке Visual Basic получаются наборы инструк­ ций на одном и том же промежуточном языке MSIL. И нужно это, еще раз подчеркнем , для обеспечения совместимости разных программ­ ных кодов, реализованных на разных языках.

Весь этот процесс для нас важен исключительно с познавательной точки зрения. Более принципиальными являются вопросы, касающиеся осо­ бенностей собственно языка С#. Первое, что стоит отметить: язык С# полностью объектно ориентиро­ ванный. Это означает, что даже самая маленькая программа на языке С# должна содержать описание хотя бы одного класса.

G)

Н А ЗАМ ЕТ КУ

Здесь есть методологическая проблема. Состоит она в том , что не­ подготовленному ч итател ю сложно восприни мать концепцию ООП сразу, без п редварител ьной подготовки . М ы найдем выход в том , чтобы испол ьзовать определенный шаблон п р и написании п ро­ грам м . Затем , по мере знакомства с языком С# , м ногие моменты станут просты м и и п онятн ы м и .

Как отмечалось выше, базовые синтаксические конструкции языка С # напоминают (или просто совпадают) соответствующие конструкции в языках С++ и/или Jаvа. Но, кроме них, язык С# содержит множество интересных и полезных особенностей, с которыми мы познакомимся в книге.



ПОДРОБН ОСТИ

Знакомым с языками п рограммирован ия С++ и/или Java будет полезно узнать, что в языке С# , как и в языке С++ , испол ьзуются п ространства имен , указатели , существует переопределение опе­ раторов. Также в С# , как и в Java, имеются и нтерфейсы , объекты реал изуются через ссыл ки , испол ьзуется система автоматической 11

Вв едение «уборки мусора » . А еще в С# испол ьзуются делегаты , кон цепция которых идеологически бл изка к концепции указателей на фун кци и в С++ . М ассивы в С# бол ьше напоми нают массивы Java , но вооб­ ще в С# они достаточ н о специфич н ы е . И ндексаторы в С# позво­ л я ют и ндексировать объекты - подобн ы й механ изм , основа н н ы й на переоп редел е н и и оператора « квадратн ые скобки » , есть в С++ . Свойства, которые испол ьзуются в С#, представл я ют собой нечто среднее между полем и методом , хотя , конеч н о , бол ьше напомина­ ют п ол е с особы м режи мом доступа .

Есть в языке С# и �классические� механизмы, характерные для боль­ шинства языков, поддерживающих парадигму ООП. Мы познакомим­ ся с тем, как на основе классов и объектов в языке С# реализуется ин­ капсуляция, узнаем, что такое наследование и как в С# используется полиморфизм. Будет много других тем и вопросов, которые мы изучим. Например, мы узнаем (во второй части книги), как в С# создаются при­ ложения с графическим интерфейсом, и познакомимся с основными подходами, используемыми при создании многопоточных приложений. Но обо всем этом - по порядку, тема за темой.

П рограммное обеспе ч ение Показывай свою гравицану. Если фирменная вещь - возьмем !

из к/ф -«Кин-дза-дза»

Для работы с языком программирования С# на компьютере должна быть установлена платформа .Net Framework. Компилятор языка С# входит в стандартный набор этой платформы. Поэтому, если на компью­ тере установлена платформа .Net Framework, этого достаточно для нача­ ла программирования в С#. Обычно дополнительно еще устанавливают среду разработки, благодаря которой процесс программирования на С# становится простым и приятным. Если мы хотим написать программу (на языке С#), сначала нам нужно набрать соответствующий программный код. Теоретически сделать это можно в обычном текстовом редакторе. В таком случае набираем в тек­ стовом редакторе код программы и сохраняем файл с расширением . c s (расширение для файлов с программами, написанными н а языке С#). 12

Я зык С# и технология .Net Framework После того как код программы набран и файл с программой сохранен, ее следует откомпилировать. Для этого используют программу-компи­ лятор c s c . ехе, которая устанавливается, как отмечено выше, при уста­ новке платформы .Net Framework.



ПОДРОБН ОСТИ

Ал горитм действи й тако й : в командной строке указывается назва­ ние п рограм м ы - ком пилятора csc.ехе , а затем через п робел ука­ зы вается название файла с п рограммой на языке С# . Допусти м , м ы записал и код п рограм м ы в файл MyProgram. cs. Тогда для ком ­ пиляции программы в командной строке испол ьзуем инструкци ю csc. ехе MyProgram. cs или csc MyProgram. cs ( расш ирение ехе ­ файла можно не указы вать ) . Есл и ком п ил я ция проходит нормально, то в резул ьтате получаем файл с расш ирением . ехе , а название файла совпадает с названием исходного файла с п рограммой ( в на­ шем случае это MyProgram. ехе ) . Полученный в резул ьтате ком п ил я ­ ци и ехе-файл запускают на выполнение. Файл csc.exe п о умолчан и ю находится в каталоге C : \ Window s \ Microsoft. NET\ Framework внутри папки с номером верси и - на­ пример, vЗ. 5 или v4. О. Также для ком п ил и рован ия п рограммы из командной строки п ридется , скорее всего , выпол н ить некоторые допол н ител ьные настройки - например, в переменных среды за­ дать путь для поиска ком п илятора csc. ехе .

Хотя такая консольная компиляция вполне рабочая, прибегают к ней редко. Причина в том, что не очень удобно набирать код в текстовом редакторе, затем компилировать программу через командную строку и запускать вручную исполнительный файл. Намного проще восполь­ зоваться специальной программой интегрированной средой разработ­ ки (ID E от Integrated Development Environment ). Среда разработки со­ держит в себе все наиболее важные «ингредиенты» , необходимые для «приготовления» такого «блюда», как программа на языке С#. При ра­ боте со средой разработки пользователь получает в одном комплекте ре­ дактор кодов, средства отладки, компилятор и ряд других эффективных утилит, значительно облегчающих работу с программными кодами. Мы тоже прибегнем к помощи среды разработки. Нам понадобится прило­ жение Microsoft Visual Studio. -

Загрузить установочные файлы можно с сайта компании Microsoft . m i c r o s o f t . сот (на сайте следует найти страницу загрузок).

www

13

Вв еде н ие После установки среды разработки мы получаем все, что нужно для успешной разработки приложений на языке С#.



ПОДРОБН ОСТИ

Приложение Microsoft Visual Studio я вляется ком мерчески м . Одна­ ко у него есть неком мерческая «уп рощенная» версия Visual Studio Express , которая впол н е подойдет для изучения языка п рогра м м и ­ рования С#.

G)

Н А ЗАМ ЕТ КУ

Кроме языка программ ирован ия С# среда разработки Visual Studio позволяет создавать п рограм м ы на языках Visual Basic и С++ . Часть настроек, вл ияющих на фун кциональность среды разработки , оп ре­ деляется в процессе установки .

Как выглядит окно приложения Visual Studio Express (версия 2 0 1 5), по­ казано на рис. В. 1 . og
� Юout WJYS we an optmzt our network а15 and background oPtr.llЬOn.s

#DocumentDB loves

Acqualnt

1- Down�d SoluЬon

Xamarln: Planet Scale МоЫlе Арр ln Ave steps Тh.1$ IS J specQI OUest post from tht

DcкumentOB tеащ wrtten Ьу Кd

G;мytyuk. К111 works •t мo:rosol't on the OOt•"""• N

w�

н.tр

� Anкh.

-

х



Discover what's new in Express 2015 for V futUtn�bprи. lSfOfV! Lwn•� Sн�in...... -.1he.NПfr•IN'WOl'll. Eapo1 ... ll\-tul 1 rlfWJn°I� �>IUdlo fцм S.М.:t1

�...iop

Rt:•dy to Cktud·powef your �е? Connect to Azure

�t·•

@

r..,

1tк.......

а

P...ctf'lll PtO]«Ь-6Solwoм ш

,...,....

Рис. 1 . 1 . Создание нового проекта в окне среды разработки Microsoft Visual Studio Express

27

Глава 1

G)

Н А ЗАМ ЕТ КУ

Для создания нового п роекта можно воспол ьзоваться п и ктограм­ мой на панел и инструментов или нажать комбинацию клавиш ++ . В результате появляется окно создания нового проекта, показанное на рис. 1 .2 .

S..tch lnsulltd ТempllttS (Cul • EJ Windows .tt.

Ttmplltti

"Vr.iш.IC• Clщн:D..i:top r

Ttst

V'wsual В.s1с



• \fr.sualC••

fotms Applt=, оператор сравнения «меньше» < , оператор сравнения «меньше или

.

равно » < =

7

Оператор сравнения «равно » ==, оператор сравнения «не равно» ! =

8

Оператор «побитовое и» & (также «логическое и» в полной форме)

9 10

Оператор «побитовое исключающее или» л (также «логическое исключаю ­

щее или»)

Оператор «побитовое или» 1 (также «логическое или» в полной форме)

1 05

Глава 2 11

Оператор «логическое и» в упрощенной форме & &

12

Оператор «логическое или» в упрощенной форме 1 1

13

Тернарный оператор ? :

14

Оператор присваивания =, операторы сокращенного присваивания * =, / = , % = , + =, -=, =, & =, л = И 1 =

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

G)

Н А ЗАМ ЕТ КУ

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

П римеры п рограмм Я тебя полюбил - я тебя научу.

из к/ф «Кин-дза-дза»

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

G)

Н А ЗАМ ЕТ КУ

Ч исло назы вается четн ы м , есл и оно дел ится на 2 - то есть есл и при делении на 2 в остатке получаем О . Есл и ч исло на 2 не дел ится , то оно назы вается нечетн ы м .

Программа выполняется просто: появляется диалоговое окно с полем ввода, в которое пользователю предлагается ввести целое число. Далее появляется еще одно диалоговое окно с сообщением о том, что пользова­ тель ввел четное или нечетное число. Код программы представлен в лис­ тинге 2 . 1 . 106

Базовые типы и операто ры

[1i!] л истинг 2. 1 . Проверка числа на четность/нечетность u s ing Sys tem; u s ing Sys tem . Windows . Forms ; u s ing Micros oft . VisualBas i c ; c l a s s OddEvenDemo { s tatic vo id Main ( ) { 1 1 Целочисленные переменные : int numЬer, reminde r ; 1 1 Считывание целого числа : numbe r=Int 3 2 . Parse ( Interaction . I nputBox ( 1 1 Текст в окне : "Введите целое число : " , 1 1 Название окна : " Проверка " ) ); 1 1 Вычисляется остаток о т деления на 2 : reminder=numЬer% 2 ; s t ring txt= " Bы ввели " ; 1 1 Использован тернарный оператор : txt+= ( reminder==O ? " чeтнoe " : " нeчeтнoe " ) + " число ! " ; Me s s ageBox . Show ( txt ) ;

В программе используются две целочисленные переменные numb e r и reminde r - соответственно, для запоминания введенного пользова­ телем числа и остатка от деления этого числа на 2 . Для считывания чис­ ла использован статический метод I nputBox ( ) класса I nt e r a c t i o n (для использования этого класса в заголовке программы взята инструк­ ция u s i n g Mi c r o s o ft . Vi s u a l B a s i c ) . Аргументами методу пере­ дается два текстовых значения: текст, отображаемый над полем ввода, и название (заголовок) для окна. Метод I np u t B o x ( ) значением воз­ вращает введенное пользователем значение, но значение возвращается 107

Глава 2

в текстовом формате. Для преобразования текстового представления числа в целое число используем статический метод P a r s e ( ) из струк­ туры I n t 3 2 (структура доступна после подключения пространства имен S y s t e m командой u s i n g S y s t em). В частности, инструкция вызова метода I nputBox ( ) передана аргументом методу P a r s e ( ) . Результат преобразования присваивается значением переменной n umbe r. Командой remi n de r=numb e r % 2 в переменную reminde r записывает­ ся остаток от деления значения переменной numb e r на 2 . Переменная reminde r в принципе может принимать всего два значения: О при чет­ ном значении переменной numb e r и 1 при нечетном значении перемен­ ной numb e r . Текстовая переменная t x t объявляется с начальным значением " В ы вв ели " . Нам эта переменная нужна для того, чтобы записать в нее текст, который затем будет отображаться во втором диалоговом окне. Следу­ ющей командой t x t + = ( r e m i nde r== O ? " ч e т н o e " : " н е ч е т н о е " ) + " число ! " к текущему значению этой переменной дописывается недо­ стающая часть. Здесь в подвыражении в правой части мы использовали тернарный оператор. Речь об инструкции remi n de r = = O ? " ч e т н o e " : " нече т н о е " . Значение этого выражения определяется так: если зна­ чение переменной r em i n de r равно О, то значение выражения равно " че т ное " . В противном случае (если значение переменной reminde r отлично от О ) значение выражения равно " н ече т н о е " . Таким обра­ зом, в текстовое значение переменной t x t включается слово " че т н о е " или " н ече т н о е " в зависимости от значения переменной r em i n d e r . После того как значение переменной t x t сформировано, командой Me s s ageBox . S how ( txt ) отображается диалоговое окно с соответству­ ющим сообщением (для использования класса Me s s ageBox используем инструкцию u s i n g S ys tem . Wi ndows . F o rms в заголовке программы). При запуске программы на выполнение появляется окно с текстовым полем. На рис. 2 . 1 показано такое окно с числом 1 2 3 в поле ввода. Прооер"

Вее.аопе uелое число:

123

Рис.

1 08

2. 1 . В поле введено нечетное ч исло

Базовые типы и операто ры После щелчка по кнопке ОК появляется новое окно с сообщением о том, что число нечетное. Окно показано на рис. 2.2.

В ы ааищ нечетное число!

ок

Рис .

2 . 2 . Окно с соо б щением о том , что б ыло введено нечетное ч и сло

На рис. 2.3 показано начальное диалоговое окно с числом 1 24 в поле ввода. Прооероtа

1 24

Рис .

2.3. В поле введено четное ч исло

Если так, то вторым появится окно с сообщением о том, что пользова­ тель ввел четное число. Окно показано на рис. 2 .4.

Вы ваvш четное Ч\IСЛО!

ок

Рис. 2 . 4 . Окно с соо б щением о том , что б ыло введено четное ч исло

При этом стоит также заметить, что если пользователь в поле ввода в первом окне введет не число или вместо кнопки ОК щелкнет кноп­ ку Отмена (или закроет окно с помощью системной пиктограммы), то в программе произойдет ошибка. В принципе, подобные ситуации легко обрабатываются. Но пока что нас этот вопрос занимать не будет. В следующей программе для числа, введенного пользователем, опреде­ ляется количество сотен (в десятичном представлении числа это третья цифра справа). В листинге 2.2 представлен код программы. 109

Глава 2

[1i!] л истинг 2.2 . Количество сотен в числе us ing Sys tem; us ing Sys tem . Windows . Forms ; us ing Micros oft . Vi sualBas i c ; c l a s s Hundreds Demo { s tatic vo id Main ( ) { / / Целочисленные переменные : int numЬe r , hundreds ; / / Считывание целого числа : numbe r=Int 3 2 . Parse ( Interaction . I nputBox ( / / Надпись над полем ввода : " Введите целое число : " , / / Заголовок окна : " Количество сотен " ) ); / / Количество сотен в числе ( для целочисленных / / операндов деление выполняется нацело ) : hundreds=numbe r/ 1 0 0 % 1 0 ; / / Текстовая переменная : s t ring txt= " B этом числе "+hundreds+" сотен ! " ; / / Отображение окна с сообщением // ( аргументы метода - сообщение и заголовок окна ) : Me s s ageBox . Show ( tx t , " Coтни" ) ;

Эта программа напоминает предыдущую - как минимум в части счи­ тывания целочисленного значения. Число, введенное пользователем, записывается в переменную numb e r . Затем выполняется команда hundr e d s =numЬe r / 1 0 0 % 1 0 , благодаря чему в переменную hundreds записывается количество сотен в числе. Вычисления выполняются так: значение переменной numb e r делится на 1 0 0 . Здесь нужно учесть, что 110

Базовые типы и операто ры для целочисленных операндов выполняется целочисленное деление. Поэтому деление числа на 1 О О означает фактически отбрасывание двух последних цифр в представлении числа. Как следствие, третья справа цифра в значении переменной numb e r �перемещается� на последнюю позицию (первую справа).

G)

Н А ЗАМ ЕТ КУ

Значение переменной numЬer не меняется . Речь идет о значении вы­ ражения numЬe r / 1 О О по сравнению со значением переменной numЬer .

Далее вычисляется остаток от деления на 1 О значения выражения n umbe r / 1 0 0 (выражение numbe r / 1 0 0 % 1 0 ). Результат записывается в переменную hundr e d s . В программе объявляется текстовая переменная t x t с о значением "В э т ом числе " +hundreds+ " сотен ! " , в котором использована пере­ менная hundreds. Переменную txt используем в команде Me s s ageBox . Show ( txt , " Со тни " ) для отображения окна с сообщением (первый аргу­ мент определяет текст сообщения, а второй задает заголовок окна). На рис. 2.5 показано окно с полем, содержащим введенное пользовате­ лем число. Ко11ичкт110 соте:н

Рис .

2. 5 . В поле введено целое ч исло для оп ределения кол ичества сотен в ч исле

После щелчка по кнопке ОК появляется окно с сообщением, показанное на рис. 2.6. Сотни В ]ТОМ чиСJ'lе S сотен!

ок

Рис .

2 . 6 . Окно с соо б щением о кол ичестве сотен в ч исле 111

Глава 2 В данном случае мы ввели число 2 5 3 8 и программа вычисляет кор­ ректное значение 5 для количества сотен в числе.

Р ез ю ме Только быстро. А т о одна секунда здесь - это полгода там !

из к/ф -«Кин-дза-дза»

• При объявлении переменной указывается ее тип и название. Не­ сколько переменных одного типа может быть объявлено одновре­ менно. При объявлении переменной можно указать ее значение. Константы объявляются с ключевым словом c o n s t . • В языке С# существует несколько базовых типов. Целочислен­ ные типы данных b y t e , s b yt e , s h o r t , u s ho r t , i n t , u i n t , l o n g и u l ong. Отличаются эти типы размером выделяемой памяти и воз­ можностью/невозможностью использовать отрицательные чис­ ла. Действительные числа реализуются с помощью типов f l o a t и douЬ l e . Для финансовых расчетов используется тип de c ima l . Символьные значения реализуются через тип char. Логические зна­ чения реализуются как значения типа b o o l . • Целочисленные литералы п о умолчанию реализуются как i n t ­ значения, действительные числовые литералы реализуются как dоuЫ е -значения, символьные литералы реализуются как с h а r ­ значения, текст реализуется в виде объектов класса s t r ing. • Если в выражении используются значения разных (но совмести­ мых) типов, то применяется автоматическое преобразование типов. Можно также выполнять явное приведение типов. • Для выполнения основных операций применяются специальные операции. В С# есть четыре группы операторов: арифметические ( «сложение» +, «вычитание» - , «умножение» * , «деление» / , «оста­ ток от деления» % , «инкремент» + + , «декремент» - - ), логические ( «логические и» & и & &, «логические или» 1 и 1 1 , «логическое исклю­ чающее или» л , «логическое отрицание» ! ), операторы сравнения ( «меньше» =, «равно» ==, «не равно» ! = ), а также побитовые операторы ( «по­ битовое и» & , «побитовое или» 1 , «побитовое исключающее или» л , 1 12

Базовые типы и операто ры «побитовая инверсию> - , «сдвиг влево» < < , «сдвиг вправо» >>). В С# есть один тернарный оператор ? : , представляющий собой упрощен­ ную форму условного оператора. Для арифметических и побито­ вых операторов есть сокращенные формы операции присваивания ( * =, / = , %=, +=, - = , =, & =, л = и 1 =). Оператор присваивания = в языке С# возвращает значение.

Задания для самостоятел ьной работы Хочешь поговорить - плати еще чатл.

из к/ф -«Кин-дза-дза»

1 . Напишите программу, которая проверяет, делится ли введенное поль­

зователем число на 3.

2. Напишите программу, которая проверяет, удовлетворяет ли введенное

пользователем число следующим критериям: при делении на 5 в остатке получается 2, а при делении на 7 в остатке получается 1 . 3 . Напишите программу, которая проверяет, удовлетворяет ли введен­

ное пользователем число следующим критериям: число делится на 4, и при этом оно не меньше 1 0 .

4 . Напишите программу, которая проверяет, попадает л и введенное

пользователем число в диапазон от 5 до 1 О включительно.

5. Напишите программу, которая проверяет, сколько тысяч во введен­ ном пользователем числе (определяется четвертая цифра справа в деся­ тичном представлении числа). 6. Напишите программу, которая проверяет вторую справа цифру в вось­

меричном представлении числа, введенного пользователем. Число вво­ дится в десятичном (обычном) представлении.

7. Напишите программу, которая вычисляет третий бит справа в двоич­ ном представлении числа, введенного пользователем. Число вводится в десятичном (обычном) представлении. В программе используйте опе­ ратор побитового сдвига. 8. Напишите программу, в которой для введенного пользователем числа

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

1 13

Глава 2 9. Напишите программу, в которой для введенного пользователем чис­ ла в бинарном представлении четвертый бит устанавливается равным нулю. 1 0 . Напишите программу, в которой для введенного пользователем чис­

ла в бинарном представлении значение второго бита меняется на проти­ воположное (исходное нулевое значение бита меняется на единичное, а исходное единичное значение бита меняется на нулевое).

Гл ава 3 У П РАВЛ SI Ю ЩИ Е И НСТ РУК ЦИ И

З начит, такое предложение : сейчас мы на­ жимаем на контакты и перемещаемся к вам. Но если эта машинка не сработает, тогда уж вы с нами переместитесь, куд а мы вас переме­ стим !

из к/ф -«Кин-дза-дза»

В этой главе мы рассмотрим вопросы, связанные с использованием управляющих инструкций. Более конкретно, мы сосредоточим внима­ ние на следующих конструкциях языка С#: • познакомимся с условным оператором i f ; • научимся использовать оператор выбора s w i t ch ; • узнаем, как используется оператор цикла wh i l e ; • выясним, в чем особенности оператора цикла d o - wh i l e ; • убедимся в гибкости и эффективности оператора цикла f o r ; • познакомимся с инструкцией безусловного перехода g o t o ; • составим некоторое представление о системе обработки исключе­ ний. Теперь рассмотрим более детально означенные выше темы.

1 15

Глава 3

Условны й оператор if Или ты сейчас же отдаешь нам эту К Ц , или меньше чем за семь коробков мы тебя на З ем­ лю не положим !

из к/ф «:Кu н-дза-дза'>

Условный оператор позволяет выполнять разные блоки команд в зави­ симости от истинности или ложности некоторого условия (выражение со значением логического типа). Работает это так: сначала вычисляется значение некоторого логического выражения (условие). Если значение выражения равно t ru e (условие истинно), выполняется определенный блок команд. Если значение выражения равно f a l s e (условие ложно), выполняется другой блок команд.

Условие t r ue

, 1

>" " - -

, , ... - - - - �.

f a l se

... ,

...

, - - "

" .\ ,

" ' , '

1 1 \

1

'

1

""

\ " ... "

,

' '

1

1

-\

Команды

,-- \

, - - ..,

'

, '·

Команды

,�.

. '

' 1 1

�-

1 ,

' -

i f - бл о к

'

,_ .... ' 1 ,

' '

1

- - ' ' ' , -' - ,

... _ _ _ ...

, , ,, ... " _ " ,

,'

,

,

'

1 1

�"-

'

е l s е - бл о к

\

,

, . - -

\

' ,

'

1 ' - -:

' , _

...\ ,

... ... _ _ ... ...

,

,'

,, ... _ _ _ "

Рис. 3. 1 . П р и н ци п ы выпол н е н и я условного оператора Описывается условный оператор достаточно просто: указывается клю­ чевое слово i f, после которого в круглых скобках следует условие, проверяемое при выполнении условного оператора. Блок команд, вы­ полняемых при истинном условии, указывается в фигурных скобках сразу после ключевого слова i f с условием ( i f-блок). Команды, пред­ назначенные для выполнения в случае ложного условия, указываются 116

Управля ющие инструкции в фигурных скобках после ключевого слова e l s e ( е l s е -блок). Шаблон описания условного оператора приведен ниже (жирным шрифтом выде­ лены ключевые элементы шаблона): if (условие ) { 1 1 Команды - если условие истинно

else { 1 1 Команды - если условие ложно

Принципы выполнения условного оператора также проиллюстрирова­ ны в схеме на рис. 3. 1 .

Условие f a l se

t r ue

1 1

,

,

" - - - ...:. .

, - - ... ,, ... - - ... ... 1

\ •-,

'

К оманды

,'' \

1 1 \

1

\ 1 1

1 1

'

� ... _ : \ " ... _ :: '

'

i f - блок 1

" ... ..,. _ _

" ...\ ... " ... _ _ ... ... r. '·',

...

,

'

'

'._ , - ' /

_ _ _ ,

Рис. 3.2. Выполнение условного оператора в упрощенной форме Если блок состоит всего из одной команды, то фигурные скобки для вы­ деления блока можно не использовать. У условного оператора есть упрощенная форма, в которой отсутству­ ет е l s е -блок. Если так, то оператор выполняется следующим обра­ зом: проверяется условие, и, если оно истинно, выполняются команды в i f-блоке. Если условие ложно, то ничего не происходит - выполня­ ется команда, следующая после условного оператора. Шаблон описания 1 17

Глава З условного оператора в упрощенной форме такой (жирным шрифтом вы­ делены ключевые элементы шаблона): if (условие ) { / / Команды - если условие истинно

Как выполняется условный оператор в упрощенной форме, иллюстри­ рует схема на рис. 3.2. Небольшой пример, иллюстрирующий работу условного оператора, представлен в листинге 3. 1 .

� Листин г 3. 1 . Использовани е условно го оператора us ing Sys tem . Windows . Forms ; us ing Micros oft . Vi sualBas i c ; c l a s s Usingi fDemo { s tatic vo id Main ( ) { / / Переменная для определения типа пиктограммы : Me s s ageBoxi con icon ; / / Переменные для определения текста сообщения , / / заголовка окна и имени поль зователя : s t ring msg , t i t l e , name ; / / Считывание имени пользователя : name=Interaction . InputBox ( / / Текст над полем ввода : " Как Вас зовут ? " , / / Название окна : " Знакомимся " ) ; / / Проверка введенного поль зователем текста : i f ( name== " " ) { / / Если текст не введен / / Пиктограмма ошибки : icon=Me s s ageBoxi con . Error; / / Текст сообщения : msg= " Очень жаль , что мы не познакомилис ь ! " ;

118

Управля ю щие инструкции 1 1 Заголовок окна : titlе=" Знакомство не состоялось " ;

e l s e { / / Если текст введен 11 Информационная пиктограмма : icon=Me s s ageBoxi con . I nformation ; 1 1 Текст сообщения : msg= " Очень приятно , " +name+ " ! " ; 1 1 Заголовок окна : titlе=" Знакомство состоялось " ;

1 1 Отображение сообщения ( аргументы - текст / / сообщения , заголовок, кнопки и пиктограмма ) : Me s s ageBox . Show (msg, title , Mes sageBoxButton s . OK , icon) ;

Программа простая: отображается окно с полем ввода, и пользователю предлагается ввести туда имя. Затем появляется новое диалоговое окно с сообщением, которое содержит введенное пользователем имя. Но это, если имя пользователь ввел. Однако пользователь в первом окне может на­ жать кнопку отмены или закрыть окно с помощью системной пиктограммы с крестом. Вот такая ситуация и обрабатывается с помощью условного опе­ ратора. А именно, мы воспользуемся тем, что если пользователь закрывает окно с полем ввода без ввода текста, то соответствующий метод возвращает пустую текстовую строку. Чтобы легче было понять, как организован про­ граммный код, рассмотрим результат выполнения программы. Сначала, как указывалось, появляется окно с полем ввода, представленное на рис. 3.3. Зкакомимс.я

IAnoo l O ) { 1 1 Отображение сообщения : Console . WriteLine ( " Oгo, как много букв ! " ) ;

1 1 Если в строке не больше десяти символов : else { 1 1 Отображение сообщения : Console . WriteLine ( " Oгo, как мало букв ! " ) ;

1 1 Е сли введена пустая строка : else { Console . WriteLine ( "Жaль , что не ввели текст ! " ) ;

Алгоритм выполнения программы простой: пользователю предлагается ввести текстовое значение, и это значение считывается и записывается в текстовую переменную. Затем в дело вступают вложенные условные операторы. Во внешнем операторе проверяется, не пустая ли введенная пользователем текстовая строка. И если строка не пустая, то во внутрен­ нем условном операторе проверяется, не превышает ли длина строки значение 1 О . В зависимости от истинности или ложности этих условий в консольное окно выводятся разные сообщения. 126

Управля ющие инструкции Для записи текстового значения, введенного пользователем, использу­ ется переменная t x t . Значение считывается командой txt=Co n s o l e . Re adL i n e ( ) . Во внешнем условном операторе проверяется условие t x t ! = " " . Если условие ложно, то выполняется команда C o n s o l e . W r i t e L i n e ( " Жал ь , ч т о не в в ели т е к с т ! " ) в е l s е -блоке внеш­ него условного оператора. Если же условие t x t ! = " " во внешнем ус­ ловном операторе истинное, то в i f-блоке сначала выполняется коман­ да C on s o l e . Wr i t e L i n e ( " Спа сибо , ч т о в в ели т е к с т ! " ) , после чего на сцену выходит внутренний условный оператор. В этом опера­ торе проверяется условие txt . Length> l O . Здесь мы воспользовались свойством L e n gth, которое возвращает количество символов в тексто­ вой строке. Следовательно, условие txt . Length> l O истинно в случае, если текстовая строка, на которую ссылается переменная t x t , содер­ жит больше 1 0 символов. Если так, то выполняется команда Co n s o l e . W r i t e L i n e ( " O г o , как мн о г о букв ! " ) в i f-блоке внутреннего ус­ ловного оператора. Если условие t x t . L e n g t h > 1 О ложно, то выпол­ няется команда C o n s o l e . Wr i t e L i n e ( " О г о , как мало букв ! " ) в е l s е -блоке внутреннего условного оператора. Таким образом, возможны три принципиально разных случая: •

пользователь не ввел текст ;



пользователь ввел текст, состоящий больше чем из 1 О символов ;



пользователь ввел текст, состоящий не больше чем из 1 О символов.

Результат выполнения программы может быть таким (здесь и далее жирным шрифтом выделено значение, которое вводит пользователь).

[1i!J Резул ьтат выполнения программы (из листинга 3.3 ) Введите текст : Изучаем С# Спасибо , что ввели текст ! Ого, как мало букв !

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

[1i!J Резул ьтат выполнения программы (из листинга 3.3 ) Введите текст : Продоmкаем изучать С#

127

Глава 3 Спасибо , что ввели текст ! Ого, как много букв !

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

� Резул ьтат выпол нения программы (из листинга 3.3 ) Введите текст : Жаль , что не ввели текст !

Еще один пример, рассматриваемый далее, иллюстрирует схему с вло­ женными условными операторами, когда каждый следующий вну­ тренний условный оператор формирует е l s е -блок внешнего условно­ го оператора. Программа, представленная в листинге 3.4, выполняется по простой схеме: пользователь вводит целое число (предположительно, от 1 до 4), а программа выводит текстовое название этого числа.

� Листинг 3. 4 . Определение ч исл а us ing Sys tem; c l a s s Anothe rNe stedi fDemo { s tatic vo id Main ( ) { 1 1 Переменная для запоминания введенного числа : int numЬe r ; 1 1 Отображение сообщения : Console . Write ( " Bвeдитe целое число : " ) ; 1 1 Считывание числа : numbe r= Int 3 2 . Parse ( Console . Read1ine ( ) ) ; 1 1 Е сли введена единица : i f ( numЬer==l ) Console . WriteLine ( "Eдиницa " ) ; 1 1 Е сли введена двойка : e l s e i f ( numbe r==2 ) Console . WriteLine ( " Двoйкa " ) ; 1 1 Е сли введена тройка : e l s e i f ( numbe r==З ) Console . WriteLine ( " Tpoйкa " ) ; 1 1 Е сли введена четверка :

128

Управля ющие инструкции e l s e i f ( numbe r==4 ) Console . WriteLine ( "Чeтвepкa " ) ; 1 1 Все прочие случаи : e l s e Console . WriteLine ( " Heизвecтнoe число " ) ;

Программа «узнает� числа от 1 до 4 включительно. В начале выполне­ ния программы командой C on s o l e . W r i te ( " Введите целое чис ­ л о : " ) отображается приглашение ввести целое число. Число считы­ вается командой n umb e r = I n t 3 2 . P a r s e ( C o n s o l e . Re a dL i n e ( ) ) и записывается в переменную n umЬe r. Затем задействуется блок из вло­ женных условных операторов, в каждом из которых проверяется введен­ ное значение. При наличии совпадения в консольном окне появляется сообщение соответствующего содержания (название введенного числа). Если пользователь ввел число, не попадающее в диапазон значений от 1 до 4 , то выполняется команда C o n s o l e . W r i t e L i n e ( " Неиз в е с т н о е число " ) . Ниже показано, как может выглядеть результат выполнения программы, если пользователь вводит «знакомое� для программы чис­ ло (здесь и далее жирным шрифтом выделено введенное пользователем значение).

[1i!J Резул ьтат выполнения программы (из листинга 3. 4) Введите целое число : 2 Двойка

Если программе не удается идентифицировать число, то результат та­ кой.

[1i!J Резул ьтат выполнения программы (из л истинга 3. 4) Введите целое число : 5 Неизвестное число

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

129

Глава 3

Оператор выбора switch Нет-нет, шуба подождет. Я считаю, что глав­ ное - посмотреть на мир.

из к/ф «Бриллиан товая рука»

Оператор выбора swi tch позволяет выполнить проверку значения не­ которого выражения. В языке С# выражение, которое проверяется с по­ мощью оператора выбора swi t ch, может возвращать значение целочис­ ленного, символьного или текстового типа. Описывается оператор выбора следующим образом. Сначала указывается ключевое слово swi t ch, после которого в круглых скобках следует проверяемое выражение. Тело операто­ ра выбора заключается в фигурные скобки. Там описываются с а s е-блоки. Каждый такой блок начинается с ключевого слова c a s e . После него указы­ вается контрольное значение (заканчивается двоеточием). Каждый с а s е ­ блок содержит набор команд, заканчивающийся инструкцией break. Кон­ трольные значения в с а s е-блоках сравниваются со значением выражения в switсh-инструкции. Если совпадение найдено, то выполняются коман­ ды в соответствующем с а s е-блоке. На случай, если совпадения нет, в опе­ раторе выбора s w i t ch может быть предусмотрен блок de fau l t . Общий шаблон описания оператора выбора swi tch с тремя с а s е-блоками пред­ ставлен ниже (жирным шрифтом выделены ключевые элементы шаблона): switсh(выражение){ case значение

1:

1 1 Команды break ; case значение 2 : 1 1 Команды break ; case значение 3 : 1 1 Команды break ; default : 11 Команды break ;

130

Управля ю щие инструкции Блок de fau l t не является обязательным - его можно не указывать со­ всем. На рис. 3.6 показана схема, иллюстрирующая способ выполнения оператора выбора s w i t c h .

' 1

1

'

,

..,, , -

, , ... " - - - - - - - (::: , , , ...

' · · -

(

---

не

'

,

...

... _

,

,,

...

'

'

\" " ,

'

о б я з а тел ь ный

_

...

... ," "

' " ... ... " блок ' ... ...

...

,

)--

:

'

/

'

_к _о _м _а.вды _ _ _ _ _

О

break

)

_ _

" ...

... _ _ _ _

_ � , ,' "" - - - '

Рис. 3. 6. В ы полнение оператора вы б ора 131

Глава 3 Таким образом, при выполнении оператора выбора сначала вычисляется значение выражения в s w i t сh-инструкции. Полученное значение по­ следовательно сравнивается с контрольными значениями в с а s е -бло­ ках. При первом же совпадении выполняются команды в соответству­ ющем с а s е -блоке - вплоть до инструкции b r e a k. Если совпадение не найдено и в операторе выбора есть de fau l t -блoк, то выполняются команды в этом блоке. Если совпадение не найдено и de f a u l t-блока в операторе выбора нет, то ничего не происходит.



ПОДРОБН ОСТИ

И усл о в н ы й операто р , и оператор выбора, и рассматриваемые далее операторы цикл а - все переч исленные управл я ющие и н ­ струкци и есть не тол ько в языке С# , но и , скажем , в языках С++ и Java . Даже бол ьше - там они п рактически такие же , как в язы­ ке С# . И в плане си нтаксиса, и в плане п р и н ципов выпол нения . Но вот оператор выбора в С# немного особ ы й . Во-первых, кро­ ме цел оч исленных и сим вол ьных вы раже н и й в операторе выбора мо гут испол ьзоваться и текстовые вы ражения . Такого нет в языке С++ (там п роверяемое в ы ражение может быть целоч исл е н н ы м или символ ь н ы м ) . Во - вторых, в С# в операторе выбора, есл и с а s е ­ блок непусто й , он должен заканчи ваться Ь r е а k - и нструкцие й . В от­ л и ч и е от С#, в языках С++ и Java с а s е -блок может заканчи ваться инструкцией b r e a k , но это не обязател ьно. Вообще , инструкция b r e a k испол ьзуется для завершения работы оп ераторов цикл а или оператора выбора. Само по себе завершение ко манд в с а s е - бл оке оператора выбора работу это го оператора не завершает. Други­ м и сл овам и , есл и в каком -то с а s е - бл оке команды выпол н ил и с ь , т о это к автоматическому завершению в ы п о л н е н и я всего операто ­ ра выбора не п р и водит. Чтобы заверш ить оператор выбора, нужна инструкция b r e a k . Ч исто гипотетически , есл и бы с а s е - бл ок не за­ кан ч и вался инструкцией b r e a k , то п осл е завершения выполнения команд в это м бл оке должно было бы начаться выпол нение команд в следующем с а s е - блоке (даже есл и нет сов падения с контрол ь­ ным значением в этом блоке ) . В языках С++ и Java все так и п роис­ ходит. Что касается языка С # , то здесь п р и про верке знач ения в ы ­ ражения и срав нении е г о с контрол ь н ы м и знач е н и я м и с а s е - бл оки могут переби раться не в том по рядке , как они указан ы в операторе выбора. П оэтому в ы пол н е н и е кода необходимо огранич ить л и ш ь блоком , для которого выявлено сов падение контрол ьного значе­ н и я со значением п роверяемого вы ражения . Как бы там н и был о , но в языке С# непустые с а s е - блоки и блок de fau l t заканчива­ ются инструкцией b r e a k . Как и зачем испол ьзуются пустые с а s е ­ блоки - обсудим немного позже .

132

Управля ющие инструкции Несложно заметить, что в некотором смысле оператор выбора напоми­ нает блок из вложенных условных операторов, хотя полной аналогии здесь, конечно, нет. Небольшой пример, в котором использован опера­ тор выбора, представлен в листинге 3.5. Фактически это альтернативный способ реализации программы с вложенными условными операторами, в которой по введенному пользователем числу определяется название этого числа (см. листинг 3.4). Но на этот раз вместо условных операто­ ров использован оператор выбора s w i t ch.

� Листинг 3. 5 . З накомство с оператором выбора u s ing Sys tem; u s ing Sys tem . Windows . Forms ; u s ing Micros oft . VisualBas i c ; c l a s s SwitchDemo { s tatic vo id Main ( ) { / / Переменная для запоминания введенного числа : int numЬer; / / Переменная для записи названия числа : s t ring name ; / / Считывание числа : numbe r=I nt 3 2 . Parse ( Interaction . I nputBox ( / / Текст над полем ввода : "Введите число : " , / / Заголовок окна : "Число " ) ); / / Использование оператора выбора для определения / / названия введенного числа : switch ( numЬe r ) { case 1 :

/ / Если ввели число 1

nаmе=" Единица " ;

/ / Название числа

break;

/ / Завершение блока

case 2 :

/ / Если ввели число 2

133

Глава 3 nаmе=" Двойка " ;

/ / Название числа

break;

/ / Завершение блока

case 3 :

/ / Если ввели число 3

nаmе=" Тройка " ;

/ / Название числа

break;

/ / Завершение блока

case 4 :

/ / Если ввели число 4

nаmе= "Четверка " ;

/ / Название числа

break;

/ / Завершение блока

de fault :

/ / Ввели другое число

/ / Текст сообщения : nаmе= " Неизвестное число " ; break;

/ / Завершение блока

} / / Завершение оператора выбора / / Отображение сообщения : Me s s ageBox . Show ( name , "Чиcлo " ) ;

Предыдущая версия программы была консольной. Эта версия для вво­ да числа и вывода сообщения использует диалоговые окна. Но это от­ личие �косметическое» . Идеологически важное отличие состоит в том, что здесь мы используем оператор выбора s w i t c h . Целочисленная переменная numb e r предназначена для записи числа, которое вво­ дит пользователь. Текстовая переменная n ame нужна для того, чтобы сформировать и запомнить текстовое значение - название введенного пользователем числа. Для считывания числа используем статический метод I np u t B o x ( ) класса I n t e r a c t i o n . Для преобразования тек­ стового представления числа в целое число используем статический метод P a r s e ( ) из структуры I n t 3 2 . Результат записывается в пере­ менную numb e r . Для проверки значения переменной numb e r использован оператор выбора. Проверяемым выражением в нем является эта переменная. В с а s е -блоках указаны контрольные значения - целые числа от 1 до 4 включительно (всего четыре с а s е -блока). При наличии совпадения значения переменной numb e r и контрольного значения в с а s е -блоке 134

Управля ю щие инструкции получает значение переменная name (значение переменной - название введенного числа). На случай, если совпадения не будет, предусмотрен de f a u l t-блок. В этом блоке значением переменной name присваивает­ ся текст, сообщающий о невозможности идентифицировать число. Таким образом, было или не было совпадение, переменная n ame по­ лучит значение. Это значение используется в команде Me s s a g e B o x . Show ( name , " Число " ) , которой отображается диалоговое окно с сооб­ щением (название числа или сообщение о том, что число неизвестно). На рис. 3.7 показано окно с полем ввода, в которое введено число 2 . Число

Рис. 3. 7. В поле введено ч исло 2 После подтверждения ввода появляется новое диалоговое окно, пока­ занное на рис. 3.8. Число



Двойк1 ок

Рис. 3.8. Окно с соо б щением после ввода числа 2 На рис. 3.9 показано окно с полем ввода, в котором пользователь указал число 5 . ЧиU10

Рис. 3. 9 . В поле введено ч исло 5 135

Глава 3

После щелчка по кнопке ОК появляется окно с сообщением о том, что число неизвестно. Окно показано на рис. 3. 1 0. Чием



Нrю�sктн о е ч�tсло

ок

Рис. 3. 1 О. Окно с соо б щением после ввода ч исла 5 Стоит заметить, что если пользователь вместо ввода числа в окне с по­ лем щелкнет, например, кнопку Отмена, то возникнет ошибка. Жела­ ющие могут подумать, как следует модифицировать программный код, чтобы подобная ситуация обрабатывалась корректно.

G)

Н А ЗАМ ЕТ КУ

В программе испол ьзовано нескол ько пространств имен . П ростран­ ство имен Sys tem . Windows . Forms необходи мо подкл ючить для ис­ пол ьзования статического метода Show ( ) из класса Me s s ageBox . Метод отображает диалоговое окно с сообщением ( в данном слу­ чае назван ие введенного пользователем ч исла) . Пространство имен Mi c ro s o ft . V i s u a l Ba s i c нужно для испол ьзования статического метода I nputBox ( ) из класса Interaction . Метод отображает окно с полем ввода . Напом н и м , что в данном случае мы п рибегаем к по­ мощи средств разработки языка Visual Basic. Наконец, пространство имен Sys tem нам понадобилось, поскол ьку мы используем стати­ ческий метод Parse ( ) из структуры I n t 3 2 . Вообще-то м ы еще ис­ пол ьзуем и текстовый тип S t r i n g. Это класс из п ространства имен Sys tem. Но в программе ссылка на текстовый тип выпол нена через идентификатор s t ring, явля ющийся псевдонимом для инструкции Sys tem . S t r i n g. Так что s t r ing можно было бы испол ьзовать и без подкл ючения пространства имен Sys tem.

Как отмечалось ранее, с а s е -блоки в операторе выбора могут быть пу­ стыми. Так поступают в случае, если необходимо, чтобы для несколь­ ких контрольных значений выполнялись одни и те же команды. Если так, то вместо дублирования команд в соответствующих с а s е -блоках (что неудобно и не очень рационально) используют несколько идущих один за другим пустых блоков. Причем в таких пустых с а s е -блоках нет

136

Управля ющие инструкции даже Ь r е а k-инструкций. Пример подобного подхода проиллюстриро­ ван в следующей программе, представленной в листинге 3.6.

� Листинг 3.6. Оператор выбора с пустыми са sе -блоками u s ing Sys tem; u s ing Sys tem . Windows . Forms ; u s ing Micros oft . VisualBas i c ; c l a s s Anothe rSwitchDemo { s tatic vo id Main ( ) { / / Переменная для запоминания введенного числа : int numЬer; / / Переменная для текста сообщения : s t ring txt= " " ;

/ / Началь ное значение переменной

/ / Считывание числа : numbe r=I nt 3 2 . Parse ( Interaction . I nputBox ( / / Текст над полем ввода : "Введите целое число от

1

до 9 : " ,

/ / Заголовок окна : "Число " ) ); / / Проверка значения переменной numbe r : switch ( numЬe r ) { case

1:

case 9 :

/ / Оператор выбора

/ / Е сли значение

1

/ / Е сли значение 9

/ / Текст сообщения : txt=" Bы ввели нечетное , \n но не простое число . " ; break; / / Завершение блока case 2 :

/ / Е сли значение 2

case 3 :

/ / Е сли значение 3

case 5 :

/ / Е сли значение 5

case 7 :

/ / Е сли значение 7

137

Глава З / / Текст сообщения : txt=" Bы ввели простое число . " ; break; / / Завершение блока case 4 :

/ / Е сли значение 4

case 8 :

/ / Е сли значение 8

/ / Текст сообщения : txt=" Bы ввели число - степень двойки . " ; break; / / Завершение блока case 6 :

/ / Е сли значение 6

/ / Текст сообщения : txt=" Bы ввели 6 - совершенное число . " ; break; / / Завершение блока

/ / Отображение диалогового окна с сообщением : Me s s ageBox . Show ( tx t , "Чиcлo " ) ;

Данная программа в некотором смысле напоминает предыдущую. Сна­ чала пользователю предлагается ввести целое число (в диапазоне от 1 до 9 ) . Результат записывается в переменную numb e r . После этого с по­ мощью оператора выбора проверяется значение этой переменной. Мы �классифицируем» числа по следующим категориям: • Простые числа - числа, которые не имеют других делителей, кроме единицы и себя самого. В диапазоне чисел от 1 до 9 простыми явля­ ются числа 2 , 3, 5 и 7 . • Числа, которые являются степенью двойки - в диапазоне от 1 до 9 2 3 в эту категорию попадают числа 4 (2 4) и 8 (2 8). =

=

• Число 6 является совершенным - сумма его делителей (числа 1, 2 и 3 ) равна самому этому числу. Следующее совершенное число - это 2 8 (его делители 1 , 2 , 4 , 7 и 1 4 в сумме дают 2 8 ), но оно не попадает в интервал от 1 до 9 . • Нечетные числа, которые при этом н е являются простыми - в ука­ занном диапазоне это числа 1 и 9 . 138

Управля ю щие инструкции Введенное пользователем число с помощью оператора выбора «припи­ сывается� к одной из перечисленных групп. И в этом операторе выбора мы используем пустые с а s е-блоки. Например, есть в операторе выбо­ ра такая конструкция (комментарии для удобства удалены): case 2 : case 3 : case 5 : case 7 : txt= "Bы ввели простое число . " ; break;

Как это работает? Допустим, пользователь ввел значение 2. При срав­ нении этого значения с контрольными значениями в с а s е -блоке со­ впадение имеет место для блока c a s e 2 . Поэтому будут выполнены все команды от места, где идентифицировано совпадение, до первой ин­ струкции b r e a k. В результате выполняется команда t x t = " Bы в в ели про с т о е число . " . Теперь предположим, что пользователь ввел значе­ ние 5 . Совпадение проверяемого (переменная numb e r ) и контрольно­ го значения имеет место в блоке c a s e 5. Он пустой. Но это все равно с а s е-блок. Поэтому выполняются команды от места совпадения до пер­ вой инструкции b r e a k. Итог такой - выполняется команда t x t = " Bы в в ели про с т о е число . " . То же получаем, когда пользователь вводит значение 3 и 7 . Прочие блоки в операторе выбора работают по такому же принципу. Внешне все выглядит следующим образом. При запуске программы на выполнение появляется окно с полем ввода, в которое следует ввести число от 1 до 9. Окно показано на рис. 3. 1 1 . Число

Рис. З. 1 1

.

Окно с полем для ввода ч исла в диапазоне от 1 до 9

Если пользователь вводит числа 1 или 9 , то следующим появляется окно, представленное на рис. 3. 1 2 . 139

Глава 3

ЧНо

Вы е в е1 ш нечflНое.. но не: npocтot чиС/lо.

ок

Рис. 3. 1 2 . Окно появляется , есл и пол ьзовател ь вводит ч исло 1 или 9

G)

Н А ЗАМ ЕТ КУ

В операторе выбора в одном из с а s е -блоков (для значений 1 и 9 ) при оп ределении текстового значения переменной txt в текстовом л итерале испол ьзована инструкция \ n . Напом н и м , что это инструк­ ция перехода к новой строке . П ри отображен и и соответствующего текста в том месте , где размещена инструкция \ n , выполняется пе­ реход к новой строке. Резул ьтат можно видеть на рис . 3 . 1 2 , где текст в диалоговом окне отображается в две строки .

В случае, если пользователь вводит число 2 , 3 , 5 или 7 , появится окно, представленное на рис. 3. 1 3 .

Число

Вы

в аt..n и простое число.

ок

Рис. 3. 1 3. Окно появляется , есл и пол ьзовател ь вводит ч исло 2, 3, 5 или 7

Если пользователь вводит число 6 , появляется окно, показанное на рис. 3. 1 4 .

Число

Вы

авvш

6

·

совершенное число.

ок

Рис. 3. 1 4 . Окно появляется , есл и пользовател ь вводит ч исло 6 140

Управля ющие инструкции Наконец, если пользователь вводит число 4 или 8, то появляется окно, показанное на рис. 3 . 1 5 . Число

ок

Рис. 3. 1 5 . Окно появляется , есл и пол ьзовател ь вводит ч и сла 4 или 8 Хочется обратить внимание на несколько обстоятельств. Во-первых, в операторе выбора мы не использовали de f a u l t - блок. Как упоми­ налось ранее, этот блок не является обязательным, чем мы, собствен­ но, и воспользовались. Но поскольку теперь в s w i t с h-операторе de f а и 1 t-блока нет, то теоретически может получиться, что в операторе переменной txt значение не будет присвоено - например, если пользо­ ватель введет число, которое не попадает в диапазон значений от 1 до 9 . И это проблема, поскольку переменная t x t используется в команде Me s s ageBox . S h o w ( t x t , " Число " ) после оператора выбора. Такие си­ туации компилятором отслеживаются, и выдается ошибка еще на этапе компиляции. Чтобы ее избежать, при объявлении переменной txt мы ей сразу присвоили пустое текстовое значение. В таком случае, даже если пользователь введет значение вне рекомендуемого диапазона и в опера­ торе выбора значение переменной t x t присвоено не будет, переменная останется со своим старым значением. Возможно, это не самый лучший способ решения проблемы, но, во всяком случае, при компиляции не бу­ дет ошибки. Также стоит заметить, что, если пользователь в поле ввода введет не чис­ ло, отменит ввод (щелкнув кнопку Отмена) или закроет окно щелчком по системной пиктограмме, возникнет ошибка. Чтобы ее избежать, мож­ но воспользоваться системой перехвата и обработки исключений. Как это делается, кратко будет показано в одном из разделов в конце главы. Обработке исключений также посвящена одна из глав во второй части книги.

141

Глава З

Оператор ц и кла wh i l e З амечательная идея ! Ч то ж она мне самому в голову не пришла ?

из к/ф �Ирония судьбы,

WlU

С легким паром»

Оператор цикла позволяет многократно выполнять определенный набор команд. В языке С# существует несколько операторов цикла, и со всеми ними мы познакомимся. Но начнем с оператора цикла whi l e. У него до­ статочно простой синтаксис. Описание оператора начинается с ключевого слова whi l e. В круглых скобках после ключевого слова whi l e указьшает­ ся некоторое условие (выражение со значением логического типа). Затем в фигурных скобках указьшается блок из команд, формирующих тело опе­ ратора цикла. Общий синтаксис оператора цикла wh i l e, таким образом, следующий (жирным шрифтом выделены ключевые элементы шаблона): while (ycлoвиe ) { 1 1 Команды

Выполняется оператор цикла wh i l e так. Сначала проверяется условие (в круглых скобках после ключевого слова w hi 1 е ). Если условие истинно (значение t rue ), то выполняются команды в теле оператора цикла. После этого снова проверяется условие. Если оно истинно, то снова выполняют­ ся команды в теле оператора цикла, после чего опять проверяется условие, и так далее. Оператор цикла выполняется до тех пор, пока при проверке условия оно не окажется ложным (значение fa l s e). Если при проверке условия оно оказывается ложным, команды в теле оператора цикла не вы­ полняются, работа оператора цикла завершается и управление передается следующей инструкции после оператора цикла. Схема выполнения опе­ ратора цикла wh i l e проиллюстрирована на рис. 3. 1 6. Стоит заметить, что команды в теле оператора выполняются блоком то есть условие в очередной раз проверяется только после того, как вы­ полнены все команды в теле оператора цикла. Условие, указанное в круг­ лых скобках после ключевого слова wh i l e , должно быть таким, чтобы при выполнении команд в теле оператора цикла оно в принципе могло измениться. Проще говоря, чтобы в операторе цикла начали выполнять­ ся команды, условие в самом начале должно быть равно t ru e . А чтобы оператор цикла в какой-то момент завершил выполнение, условие долж­ но стать равным f a l s e . Иначе получим бесконечный цикл. 142

Управля ющие инструкции

,/ ' ' '

,. - -1

'

1

,

\

... - -

t r ue

'

- - - •

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



166

Условный оператор i f позволяет выполнять разные блоки команд в зависимости от истинности или ложности некоторого условия.

Управля ющие инструкции Проверяемое условие указывается в круглых скобках после ключе­ вого слова i f. Команды, выполняемые при истинном условии, ука­ зываются в блоке после i f-инструкции. Команды, выполняемые при ложном условии, указываются в е l s е -блоке. Существует упрощен­ ная форма условного оператора без е l s е -блока. • Оператор выбора s w i t c h позволяет выполнять разные блоки ко­ манд в зависимости от значения некоторого выражения. Проверя­ емое выражение (целочисленное, символьное или текстовое) ука­ зывается в круглых скобках после ключевого слова s w i t ch. Затем указываются с а s е -блоки с контрольными значениями. Выполняют­ ся команды в с а s е -блоке, в котором контрольное значение совпа­ дает со значением проверяемого выражения. В случае, если значе­ ние выражения не совпадает ни с одним из контрольных значений в с а s е -блоках, выполняются команды в de f a u l t-блоке. Этот блок не является обязательным. Каждый с а s е -блок и de f a u l t-блок за­ канчивается инструкцией b r e a k. В случае необходимости можно использовать пустые с а s е -блоки. • Оператор цикла wh i l e позволяет многократно выполнять блок определенных команд. После ключевого слова wh i l e в круглых скобках указывается условие, при истинности которого выполняют­ ся команды в теле оператора цикла. Каждый раз после выполнения этих команд проверяется условие, и, если оно истинно, команды вы­ полняются снова. • Оператор цикла do-wh i l e похож на оператор цикла wh i l e , но в опе­ раторе do - wh i l e сначала выполняются команды, а затем проверяет­ ся условие. Команды указываются после ключевого слова do. После блока команд следует ключевое слово wh i l e и, в круглых скобках, условие. Оператор цикла выполняется до тех пор, пока при очеред­ ной проверке условия оно не оказывается ложным. • Описание оператора цикла f o r начинается с ключевого слова f o r . В круглых скобках указывается три блока инструкций. Блоки разде­ ляются между собой точкой с запятой. Если блок содержит несколь­ ко инструкций, то они разделяются запятыми. Команды, формиру­ ющие тело оператора цикла, указываются в круглых скобках после f о r -инструкции. Выполнение оператора цикла начинается с вы­ полнения команд в первом блоке. После этого проверяется условие во втором блоке. Если оно ложно, оператор цикла завершает работу. Если условие истинно, то выполняются команды в теле оператора 167

Глава З цикла и в третьем блоке. Затем снова проверяется условие. Если ус­ ловие ложно, работа оператора цикла завершается. Если условие истинно, выполняются команды в теле оператора и в третьем блоке и снова проверяется условие. И так далее, пока при проверке усло­ вия оно не окажется ложным. • Инструкция безусловного перехода g o t o позволяет перейти к вы­ полнению программного кода в том месте, которое выделено меткой. Используя инструкцию g o t o и условный оператор, можно органи­ зовать циклическое выполнение программного кода (симулировать работу оператора цикла). Общая рекомендация состоит в том, чтобы избегать использования инструкции g o t o . • Система обработки исключений позволяет предусмотреть специаль­ ный код, выполняемый при возникновении ошибки. С этой целью используется конструкция t ry- c at ch. Программный код, при вы­ полнении которого может возникнуть ошибка, помещается в t r у­ блок. Программный код, предназначенный для выполнения в случае возникновения ошибки, помещается в с а t с h-блок. Если при выпол­ нении кода в t rу-блоке ошибка не возникает, то с а t сh-блок игно­ рируется. Если при выполнении кода в t rу-блоке возникает ошибка, то выполнение команд в блоке t r y прекращается и начинают выпол­ няться команды в блоке c a t c h .

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

из к:/ф -«Кин-дза-дза»

1 . Напишите программу, в которой пользователь вводит число, а про­ грамма проверяет, делится ли это число на 3 и на 7 . Результаты проверки отображаются в сообщении в диалоговом окне. Используйте обработку исключений. 2. Напишите программу, в которой пользователь последовательно вво­ дит два целых числа. Программа определяет, какое из чисел больше или они равны, и выводит сообщение в диалоговом окне. Используйте обра­ ботку исключений.

1 68

Управля ющие инструкции 3 . Напишите программу, в которой вычисляется сумма чисел, которые

вводит пользователь. Программа выводит запрос на ввод числа, считы­ вает введенное пользователем число, прибавляет его к сумме и снова выводит запрос на ввод числа. Процесс продолжается до тех пор, пока пользователь не введет нулевое значение. Используйте обработку ис­ ключений. 4. Напишите программу, в которой пользователь вводит целое число в диапазоне от 1 до 7 , а программа определяет по этому числу день не­ дели. Если введенное пользователем число выходит за допустимый диа­ пазон, выводится сообщение о том, что введено некорректное значение. Используйте оператор выбора s w i t ch. Предложите механизм обработ­ ки ошибки, связанной с вводом нечислового значения. 5. Напишите программу, в которой пользователю предлагается ввести

название дня недели. По введенному названию программа определяет порядковый номер дня в неделе. Если пользователь вводит неправиль­ ное название дня, программа выводит сообщение о том, что такого дня нет. Предложите версию программы на основе вложенных условных операторов и на основе оператора выбора s w i t ch. 6. Напишите программу, в которой вычисляется сумма нечетных чисел. Для проверки результата воспользуйтесь тем, что 2 + 4 + 6 + ". + 2п = п(п + 1 ). Предложите версии программы, использующие разные опера­ торы цикла. 7. Напишите программу для вычисления суммы квадратов натуральных чисел. Для проверки результата воспользуйтесь тем, что 1 2 + 2 2 + 3 2 + " . 2 n(n + 1 ) (2n + 1) +п = П редложите версии программы, использующие разные 6 операторы цикла. •

8. Напишите программу, которая выводит последовательность чисел

Фибоначчи. Первые два числа в этой последовательности равны 1 , а ка­ ждое следующее число равно сумме двух предыдущих (получается по­ следовательность 1 , 1 , 2 , 3, 5 , 8 , 1 3 , 2 1 , 3 4 , 5 5 , 8 9 и так далее). Количе­ ство чисел в последовательности вводится пользователем. Предложите версии программы, использующие разные операторы цикла. 9. Напишите программу, в которой пользователем вводится два целых числа. Программа выводит все целые числа - начиная с наименьшего (из двух введенных чисел) и заканчивая наибольшим (из двух введен­ ных чисел). Предложите разные версии программы (с использованием

169

Глава З разных операторов цикла), а также механизм обработки исключений для этой программы. 1 0 . Напишите программу, в которой вычисляется сумма чисел, удовлет­ воряющих таким критериям: при делении числа на 5 в остатке получа­ ется 2 , или при делении на 3 в остатке получается 1 . Количество чисел в сумме вводится пользователем. Программа отображает числа, которые суммируются, и значение суммы. Используйте обработку исключений. Предложите версии программы, использующие разные операторы цикла.

Гл ава 4 МАССИВЫ

- Пойдем простым логическим ходом. - Пойдем вместе .

из к/ф �Ирония судьбы,

WlU

С легким паром»

В этой главе мы обсудим исключительно важную конструкцию - речь пойдет о массивах. Среди тем, которые мы рассмотрим, будут такие: • одномерные массивы - способы их объявления и использования ; • особенности работы с двумерными массивами ; • способы инициализации массивов ; • выполнение основных операций с массивами - в частности, речь бу­ дет идти о копировании и присваивании массивов ; • создание �рваных» массивов - то есть массивов со строками разной длины ; • особенности массива из объектных ссылок. Также мы познакомимся со способами обработки аргументов командной строки. Еще в главе есть различные примеры использования массивов. Начнем же с азов - с создания одномерных массивов.

Одномерные масси вы Первый раз таких единоличников вижу.

из к/ф �девчата»

Массив - это набор элементов одного типа, которые объединены об­ щим именем. Переменные, входящие в массив, называются элемента­ ми массива. Поскольку одно и то же имя (имя массива) 4П рименяет­ ся» сразу к нескольким переменным, то эти переменные нужно как-то 171

Глава 4 идентифицировать. Идентификация выполняется с помощью индекса или индексов. Индекс - это целое число. Количество индексов, необ­ ходимых для однозначной идентификации переменной в массиве, опре­ деляет размерность массива. Под размером массива обычно подразуме­ вают общее количество элементов в массиве. Под размером массива для данной размерности имеют в виду количество значений, которые мо­ жет принимать индекс, соответствующий данной размерности. Самые простые - одномерные массивы, в которых для идентификации элемен­ та в массиве нужно указать всего один индекс. Знакомство с массива­ ми начнем именно с одномерных массивов. То есть далее в этом разделе речь идет об одномерных массивах. Мы уже выяснили, что массив - это набор переменных. Возникает есте­ ственный вопрос: как получить доступ к этому набору? Ответ состоит в том, что доступ к массиву получают с помощью специальной пере­ менной, которая называется переменной массива. Как и обычную пере­ менную, переменную массива перед использованием следует объявить. При объявлении переменной массива указывают идентификатор типа элементов массива, после него указываются пустые квадратные скобки и имя переменной массива. То есть шаблон объявления переменной мас­ сива такой: тип [ ] переменная

Например, если мы хотим объявить переменную массива с названи­ ем nums и предполагается, что массив будет состоять из целочислен­ ных значений типа i n t , то переменная массива объявляется командой i n t [ ] num s . Если бы мы объявляли переменную массива с названием s ymЬs и массив предполагался состоящим из символьных значений, то ко­ манда объявления такой переменной выглядела бы как char [ ] s ymЬ s . Н о создание (объявление) переменной массива н е означает создания массива. Другими словами, даже если мы объявили переменную масси­ ва, сам массив от этого не появляется. Его еще нет. Массив нужно со­ здать. Для создания массива используется оператор n e w . После оператора new указывается идентификатор типа, соответствующий типу элемен­ тов создаваемого массива, а в квадратных скобках после идентифика­ тора типа указывается размер массива. Шаблон для команды создания массива имеет такой вид: new тип [ размер ]

172

Масс ивы Например, если мы хотим создать одномерный целочисленный мас­ сив из 1 2 элементов, то команда создания такого массива выглядит как new in t [ 1 2 ] . Чтобы создать массив из 1 О элементов символьного типа, используем команду new char [ 1 О ] . Остается открытым вопрос о том, как переменная массива связана с собственно массивом. Ответ очень про­ стой: переменная массива ссылается на массив. Можно сказать и иначе: значением переменной массива может быть адрес массива в памяти.

G)

Н А ЗАМ ЕТ КУ

Что понимать под «адресом масси ва» и как этот адрес испол ьзуется , более детал ьно обсуждается в главе ( во второй части книги ) , посвя ­ щенной работе с указателя м и . Пока же нам достаточно самых общих представлений о том , что такое «адрес масси ва» .

Также нужно учесть, что команда создания массива не только создает массив, но еще и имеет результат. Это адрес созданного массива. А адрес массива, как мы уже знаем, может быть значением переменной массива. Главное, чтобы тип переменной массива соответствовал типу элементов в массиве. Если обобщить все вышеизложенное, то общая схема созда­ ния массива реализуется следующими командами: тип [ ] переменная ; переменная=nеw тип [ размер ] ;

То есть задача по созданию массива состоит из двух этапов: •



объявление переменной массива ; создание массива и присваивание ссылки на массив переменной мас­ сива.

Эти два этапа можно объединить и воспользоваться такой командой: тип [ ] переменная=nеw тип [ размер ] ;

Схема реализации одномерного массива проиллюстрирована на рис. 4. 1 . Например, командой i n t [ ] nums=new i n t [ 1 2 ] создается целочис­ ленный массив из 1 2 элементов, объявляется переменная массива nums и ссылка на созданный массив записывается в эту переменную. Ко­ мандой char [ ] s ymb s =new char [ 1 О ] создается массив из 1 О сим­ вольных элементов, объявляется переменная массива s ymb s и ссылка на массив записывается в переменную. 173

Глава 4

/

, ...

/

.... - "

,-

"

- ,1 - , Пер емен н а я: масс и в а '.

, , .... - - " .>, поэтому нельзя однозначно предугадать, когда именно объекты будут удалены. Можно быть уверенным лишь в том, что это произойдет.

Стати ч еские ч лены кл асса Приедут тут всякие : без профессии , без подушек" . из к/ф « д евчата>.>

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

G)

Н А ЗАМ ЕТ КУ

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

Статические члены класса описываются с ключевым словом s t a t i c . Для обращения к статическому члену класса (полю или методу) указы­ вается имя класса, после которого через точку указывают имя поля или имя метода (с аргументами или без). Таким образом, если при обращении 314

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

(D

Н А ЗАМ ЕТ КУ

Статические поля играют рол ь глобал ьных переменных. Они «не при­ вязан ы » к какому-то кон кретному объекту и существуют «сами по себе » . Единственное огран ичение - статические поля нужно описы вать в классе и при обращении указы вать имя этого класса . Аналогично, статические методы в языке С# и грают п римерно ту же рол ь, что и фун кци и в языке С++ . Статический метод - это , по сути , блок команд, которые не подразумевают испол ьзован ия объекта , и поэтому для выполнения этих команд ( вызова метода) объект как таково не нужен .



ПОДРОБН ОСТИ

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

При работе со статическими методами существует очевидное ограниче­ ние: статический метод может обращаться только к статическим полям и методам в классе. Объяснение простое: поскольку статический метод существует без привязки к объекту, то нет смысла обращаться к полям и методам объекта (поскольку объекта как такового нет). В листинге 6.6 представлена программа. В ней используется класс со ста­ тическим полем и методом.

� Листинг 6 . 6 . Знакомство со статическими полями и методами u s ing Sys tem; 11 Класс со статическим полем и методом : c l a s s MyClas s { 1 1 Статическое поле :

315

Глава б puЫ ic static int code=l O O ; 1 1 Статический метод : puЫ ic static void show ( ) { Console . WriteLine ( " Cтaтичecкoe поле : " +code ) ;

1 1 Класс с главным методом : c l a s s StaticDemo { 1 1 Главный метод : static vo id Main ( ) { 1 1 Вызов статического метода : MyClas s . show ( ) ; 1 1 Обращение к статическому полю : MyClas s . code=2 0 0 ; 1 1 Вызов статического метода : MyClas s . show ( ) ;

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

� Результат выполнения программы ( из листинга 6 . 6) Статическое поле : 1 0 0 Статическое поле : 2 0 0

В программе описьmается класс MyC l a s s , у которого есть открытое статиче­ ское целочисленное поле code с начальным значением 1 О О , а также статиче­ ский метод show ( ) (без аргументов и не возвращающий результат). Метод при вызове отображает в консольном окне значение статического поля code. В главном методе программы командой MyC l a s s . s h o w ( ) вызы­ вается статический метод s h o w ( ) класса MyC l a s s . В результате в консоли отображается текущее значение статического поля c o d e . Мы это значение можем изменить - например, с помощью команды MyC l a s s . c o de = 2 0 0 , после чего значение статического поля стано­ вится равным 2 0 0 . Проверить это легко - достаточно вызвать метод 316

З нако мство с классами и о бъекта м и s h ow ( ) (команда MyC l a s s . s how ( ) ) . В данном случае примечателен факт, что мы не создали ни одного объекта класса MyC l a s s , но это не ме­ шает нам использовать статические члены этого класса. Еще один, на этот раз �математический� пример с использованием ста­ тических полей и методов представлен в листинге 6.7. В программе опи­ сан класс МуМа th, в котором есть статические методы для вычисления значений синуса и экспоненты. В классе также имеется константное ста­ тическое поле, значение которого определяет иррациональное число л.

G)

Н А ЗАМ ЕТ КУ

Что касается статических полей , то нередко они испол ьзуются как статические константы : для такого поля указы вается идентифика­ тор типа (и есл и нужно - спецификатор уровня доступа ) , но вместо кл ючевого слова s t a t i c указы вается идентификатор c o n s t . При­ ч и на в том , что константн ые поля по умолчанию реал изуются как статические. Значение константного поля указы вается при объя в­ лении и впоследстви и не может быть изменено.



ПОДРОБН ОСТИ

Дл я вычисления экспоненты испол ьзуется следующее вы ражение: "п х2 х3 х" � ехр (х) ::::: 1 + х + 2Т + 31 ." + nг = Lk=O k! . В п рограмме описывается статический метод для выч исления сум м ы Lk=O qk q0 + q , + + qn , где при заданно �значен и и аргумента х слагаем ые в сум ме вычис­ =

···

ля ются как qk = k!· Сум ма вычисляется с помощью оператора цик­

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

qk+ 1 qk

х qk+ i = qk x k+ l

=

(легко п роверить, что есл и

qk

), k..!.__ +1

=





k! и qk = (k+ l)! ' то

Аналоги ч н ы м образом выч исляется си нус : испол ьзуется формула (-1 )"х>п+1 - " п (-1 )kx>k+1 xl xs х' s 1 n (x) - х - 31 + 51 - 71 + ". + (2n + l ) ! - Lk=O ( 2k + l ) ! . П одход испол ьзу •

ем тот же , что и при вычислении экспоненты - то есть выч исляет-

Lk=O qk - qo + q, + ". + qn , _ (-1 J k+ 1x2k+з qk+ 1 х' и тоrДа qk+ I qk+ 7 ( 2k + 3) ! ' qk - (2k + 3)(2k + 2) '

ся сум ма вида

_

но на этот раз =

qk х

(-1 )х'

(- 1 )kx2k+ 1 q k= (2k + l )! ,

(2k + 3)(2k + 2)

317

Глава б Для определения значения параметра п ( верхняя граница в сум мах, через которые вычисляется си нус и экспонента) в програм ме (в со­ ответствующем классе) объя влено статическое целоч исленное поле. А значение тт=З , 1 4 1 592 определяется через статическую константу.

Проанализируем представленный ниже программный код.

[1i!J Л истинг 6. 7. И спользование статических полей и методов us ing Sys tem; / / Класс со статическими методами и полями : c l a s s MyMath { / / Константное поле ( число " пи" ) : puЫ ic const douЫe Рi=З . 1 4 1 5 92 ; / / Закрытое статическое поле ( граница суммы) : private static int N=l O O ; / / Статический метод для вычисления экспоненты : puЫ ic static douЫe exp ( douЫe х ) { / / Сумма и добавка к сумме : douЫe s=O , q= l ; / / Вычисление суммы : for ( int k=O ; k=text . Length истинно в том случае, если индекс меньше нуля или больше максимально допустимого ин­ декса в тексте (определяется длиной текста). В этом случае выполня­ ется инструкция r e t u rn, которая завершает работу аксессора, и с тек­ стовым полем объекта, соответственно, ничего не происходит. Если же этого не происходит, то индекс попадает в допустимый диапазон значе­ ний и начинается процесс вычисления нового текстового значения для поля t e x t . Для этого объявляется локальная текстовая переменная t с пустой текстовой строкой в качестве начального значения. Затем запу­ скается оператор цикла, в котором к текстовой строке последовательно дописываются начальные символы из поля t e x t , но только до символа с индексом k (этот символ не копируется). Далее командой t + =va l u e к текстовой строке дописывается тот символ, который присваивает­ ся значением выражению с проиндексированным объектом. То есть 490

С в ойст ва и индекс аторы получается, что вместо символа с индексом k из текстового поля t e x t в текстовую строку дописывается тот символ, что указан в операции присваивания (определяется значением параметра val ue ). Затем сно­ ва запускается оператор цикла, с помощью которого к текстовой строке из переменной t дописываются все оставшиеся символы из текстово­ го поля t e x t . По завершении этого оператора цикла командой t e x t = t текстовое поле получает новое значение. Новое значение поля t e x t от­ личается от предыдущего значения одним символом. В главном методе программы командой MyS t r i n g t x t = " Myx a " соз­ дается объект t x t класса MyS t r i n g (здесь использована операция неявного приведения типов). Также главный метод содержит приме­ ры использования индексатора с индексом, значение которого выхо­ дит за допустимый диапазон (команды t x t [ - 1 ] = ' ы ' и t x t [ 4 ] = ' ъ ' ). Есть также команды ( t x t [ O ] = ' C ' , t x t [ l ] = ' л ' , t x t [ 2 ] = ' o ' и txt [ 3 ] = ' н ' ), в которых значение индекса корректно. Для проверки значения текстового поля объекта t x t используется переопределение метода T o S t r i n g ( ) (метод вызывается, когда объект t x t передается аргументом методу W r i t e L i n e ( ) ). В следующем примере описывается класс с индексатором, индекс кото­ рого не является целым числом. Соответствующая программа представ­ лена в листинге 9. 1 1 .

� Л истинг 9 . 1 1 . И ндексатор с нечисловым индексом u s ing Sys tem;

11 Класс с индексатором : c l a s s MyClas s {

1 1 Целочисленное поле : puЫ ic int code ;

1 1 Конструктор с одним аргументом : puЫ ic MyCla s s ( int n ) { code=n ;

1 1 Целочисленный индексатор с индексом , который является 11 объектом класса MyCla s s : puЫ ic int this [ MyC l a s s obj ] {

1 1 Метод вызывается при считывании значения 491

Гл ава 9 1 1 выражения с проиндексированным объектом : get {

1 1 Резуль тат : return code - obj . code ;

1 1 Метод вызывается при присваивании значения 11 выражению с проиндексированным объектом : set {

1 1 Присваивается значение полю : code=obj . code+value ;

1 1 Класс с главным методом : c l a s s Non intindexDemo {

1 1 Главный метод : static vo id Main ( ) {

1 1 Создание объекта : MyC l a s s A=new MyC l a s s ( l O O ) ;

1 1 Проверка значения поля объекта : Console . WriteLine ( " Oбъeкт А : { 0 } " , A . code ) ;

1 1 Создание объекта : MyC l a s s B=new MyC l a s s ( 1 5 0 ) ;

1 1 Проверка значения поля объекта : Console . WriteLine ( " Oбъeкт В : { 0 } " , B . code ) ;

1 1 Использование индексатора : int num=A [ B ] ; Console . WriteLine ( " Bыpaжeниe А [ В ] = { О } " , num) ; Console . WriteLine ( " Bыpaжeниe В [А ] = { О } " , В [А ] ) ; А [ В ] =2 0 0 ;

1 1 Проверка значения поля объекта : Console . WriteLine ( " Oбъeкт А : { 0 } " , A . code ) ;

492

С в ойст ва и индекс аторы Результат выполнения программы такой.

[1i!J Результат выполнения программы (из листинга 9 . 1 1 ) Объект А : 1 0 0 Объект В : 1 5 0 Выражение А [ В ] = - 5 0 Выражение В [ А] = 5 0 Объект А : 3 5 0

Здесь мы описываем класс MyC l a s s , у которого есть открытое целочис­ ленное поле c o de , конструктор с одним аргументом и индексатор. Тип индексатора определяется ключевым словом i n t , а вот индекс в индекса­ торе описан как MyC l a s s obj . Аксессоры индексатора описаны так, что результатом выражения вида А [ В ] , в котором А и В являются объектами класса MyC l a s s, является разность значений поля c o de объекта А и объ­ екта В. Например, если поле c o de объекта А равно 1 О О , а поле c o de объ­ екта В равно 1 5 О , то результатом выражения А [ В ] будет 5 О (разность значений 1 О О и 1 5 О ). Значение выражения В [ А ] при этом равно 5 О (раз­ ность значений 1 5 О и 1 О О ). Если выражению вида А [ В ] присваивается целочисленное значение, то поле c o de объекта А получит новое значение, которое равно сумме значения поля c o de объекта В и значения, присваи­ ваемого выражению А [ В ] . Так, при значении поля c o de объекта В равном 1 5 О в результате выполнения команды А [ В ] =2 О О поле c o de объекта А получит значение 3 5 О (сумма значений 1 5 О и 2 О О ). -

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

из к/ф «Бриллиантовая рука»

Двумерный индексатор описывается, в принципе, так же, как и одномер­ ный индексатор. Отличие лишь в том, что теперь в индексаторе опи­ сывается два индекса (могут быть разного типа). Для каждого индекса указывается тип, описания индексов в квадратных скобках разделяют­ ся запятыми. При индексировании объектов также указывается два ин­ декса. В листинге 9. 1 2 представлена программа, дающая представление о том, как описывается и используется двумерный индексатор. 493

Гл ава 9

[1i!J Л истинг 9 . 1 2 . Знакомство с двумерными индексаторами us ing Sys tem; / / Класс с двумерным индексатором : c l a s s MyClas s { / / Закрытое поле , являющееся ссылкой н а двумерный / / символьный массив : private char [ , ] s ymЬ s ; / / Конструктор с двумя аргументами : puЫ ic MyC la s s ( int а , int Ь ) { / / Создание двумерного массива : s ymbs=new char [ a , Ь ] ; / / Заполнение двумерного массива . / / Перебор строк массива : for ( int i=O ; i