МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ...

356
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ НАЦИОНАЛЬНЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «Харьковский политехнический институт» Л.В. Соловей, Н.Н. Мирошниченко, Н.Г. Пономарёва ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ C# Учебное пособие для студентов химических специальностей в том числе для иностранных студентов Утверждено редакционно-издательским советом университета, протокол № 2 от 24.12.15 г. Харьков НТУ «ХПИ» 2016

Upload: others

Post on 19-Jan-2020

15 views

Category:

Documents


0 download

TRANSCRIPT

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ

НАЦИОНАЛЬНЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «Харьковский политехнический институт»

Л.В. Соловей, Н.Н. Мирошниченко, Н.Г. Пономарёва

ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ C#

Учебное пособие для студентов химических специальностей

в том числе для иностранных студентов

Утверждено редакционно-издательским советом университета, протокол № 2 от 24.12.15 г.

Харьков НТУ «ХПИ»

2016

УДК 519.682 ББК 22.18 С 60

Р е ц е н з е н т ы: В.М. Колодяжный, д-р физ.-мат. наук, проф., профессор ХНАДУ; Д.А. Лисин, канд. техн. наук, доцент ХНУ им. В.Н. Каразина.

Посібник присвячений вивченню мови програмування С#. Використовується ефективний підхід до вивчення основ програмування: теорія чергується лабораторними роботами. Теоретичний матеріал, необхідний для виконання завдань, наведено до кожної лабораторної роботи. Подано велику кількість прикладів різної складності.

Призначено для студентів хімічних спеціальностей.

С 60 Программирование на языке С#: учеб. пособие / Л.В. Соловей, Н.Н. Мирошниченко, Н.Г. Пономарёв. – Х. : НТУ «ХПИ», 2016. – 356 с. – На рус. яз.

ISBN 978-617-05-0166-0 Пособие посвящено изучению языка программирования С#. Используется

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

Предназначено для студентов химических специальностей. Ил. 188. Табл. 34. Библиогр.: 7 назв.

УДК 519.682 ББК 22.18

© Соловей Л.В., Мирошниченко Н.Н.., ISBN 978-617-05-0166-0

Пономарёв Н.Г., 2015

3

ОГЛАВЛЕНИЕ

Введение ................................................................................................................... 6

ГЛАВА 1 ОБЩИЕ СВЕДЕНИЯ О ЯЗЫКЕ C# ................................................... 8

1.1 Элементы языка, типы данных, переменные, константы .............................. 8

1.2 Операции и выражения в языке C#, математические функции (методы) ... 15

ГЛАВА 2 ОПЕРАТОРЫ ПРИСВАИВАНИЯ, ВЕТВЛЕНИЯ, ОПЕРАТОР goto ......................................................................................................................... 21

2.1 Базовые конструкции структурного программирования ............................. 21

2.2 Оператор присваивания ................................................................................. 22

2.3 Ввод-вывод в консольном режиме ................................................................ 24

2.4 Метки и оператор безусловного перехода goto .......................................... 26

2.5 Операторы ветвления: оператор if и оператор switch .............................. 27

2.5.1 Условный оператор if ............................................................................ 27

2.5.2 Оператор выбора switch ........................................................................ 32

ГЛАВА 3 ОПЕРАТОРЫ ЦИКЛА: for, while, do-while........................... 37

3.1 Цикл с параметром for ................................................................................. 38

3.2 Цикл с предусловием while ......................................................................... 41

3.3 Цикл с постусловием do-while ................................................................... 43

3.4 Оператор break для выхода из цикла .......................................................... 44

3.5 Применение оператора continue ................................................................ 45

ГЛАВА 4 ОДНОМЕРНЫЕ МАССИВЫ ............................................................ 47

4.1 Описание одномерных массивов .................................................................. 47

4.2 Ввод - вывод элементов одномерного массива ............................................ 50

4.3 Накопление суммы и произведения элементов массива .............................. 52

4.4 Заполнение элементов массива при помощи генератора случайных чисел 53

4.5 Оператор цикла foreach для работы с одномерными массивами ............ 58

ГЛАВА 5 ДВУМЕРНЫЕ МАССИВЫ ................................................................ 60

5.1 Описание двумерных массивов ..................................................................... 60

5.2 Ввод - вывод элементов двумерного массива .............................................. 61

5.3 Накопление суммы элементов двумерного массива. Сумма элементов главной и побочной диагонали ........................................................................... 63

4

ГЛАВА 6 МЕТОДЫ ............................................................................................... 68

6.1 Синтаксис определения метода ..................................................................... 68

6.2 Способы передачи параметров ...................................................................... 71

6.2.1 Параметры – значения ............................................................................. 72

6.2.2 Параметры – ссылки ................................................................................ 72

6.2.3. Выходные параметры .............................................................................. 74

ГЛАВА 7 СИМВОЛЫ И СТРОКИ ...................................................................... 79

7.1 Символы .......................................................................................................... 79

7.2 Строки ............................................................................................................. 82

7.2.1 Операции, которые можно совершать над строками ............................. 85

7.2.2 Методы класса String ........................................................................... 87

7.2.3 Массив строк .......................................................................................... 103

7.3 Форматирование данных числовых типов .................................................. 105

ГЛАВА 8 КЛАССЫ, СТРУКТУРЫ, ПЕРЕЧИСЛЕНИЯ ............................... 109

8.1. Классы и объекты ........................................................................................ 109

8.2. Структуры .................................................................................................... 119

8.3. Перечисления ............................................................................................... 122

ГЛАВА 9 ФАЙЛЫ ............................................................................................... 125

9.1 Файловое хранение числовых данных ........................................................ 127

9.2 Файловое хранение текстовых данных ....................................................... 133

ГЛАВА 10 ЛАБОРАТОРНЫЙ ПРАКТИКУМ ................................................ 138

10.1 Составление программ линейной структуры ............................................ 138

10.1.1 Примеры создания проектов ................................................................ 138

10.1.2 Задачи для выполнения лабораторных работ – часть 1 ...................... 159

10.1.3 Задачи для выполнения лабораторных работ – часть 2 ...................... 160

10.2 Составление программ разветвляющейся структуры ............................... 163

10.2.1 Примеры решения задач ...................................................................... 163

10.2.2. Задачи для выполнения лабораторных работ – часть 1 ..................... 177

10.2.3. Задачи для выполнения лабораторных работ – часть 2 ..................... 179

10.3 Циклы .......................................................................................................... 181

10.3.1 Примеры решения задач ...................................................................... 181

10.3.2 Задачи для выполнения лабораторных работ – часть 1 ...................... 190

10.4 Одномерные массивы ................................................................................. 194

10.4.1 Примеры решения задач ...................................................................... 194

10.4.2 Задачи для выполнения лабораторных работ (часть 1) ...................... 235

5

10.4.3 Задачи для выполнения лабораторных работ (часть 2) ..................... 241

10.4.4 Задачи для выполнения лабораторных работ (часть 3) ..................... 243

10.4.5 Задачи для выполнения лабораторных работ (часть 4) ..................... 243

10.5 Двумерные массивы ................................................................................... 245

10.5.1. Примеры решения задач ..................................................................... 245

10.5.2. Задачи для выполнения лабораторных работ (часть 1) .................... 265

10.5.3. Задачи для выполнения лабораторных работ (часть 2) .................... 269

10.5.4. Задачи для выполнения лабораторных работ (часть 3) .................... 273

10.6 Методы ....................................................................................................... 274

10.6.1 Примеры решения задач ...................................................................... 274

10.6.2. Задачи для выполнения лабораторных работ (часть 1) .................... 314

10.6.3. Задачи для выполнения лабораторных работ (часть 2) .................... 315

10.7 Строки ........................................................................................................ 318

10.7.1. Примеры решения задач ..................................................................... 318

10.7.2. Задачи для выполнения лабораторных работ .................................... 327

10.8 Структуры, перечисления .......................................................................... 330

10.8.1 Примеры решения задач ...................................................................... 330

10.8.2 Задачи для выполнения лабораторных работ ..................................... 333

10.9 Файлы ......................................................................................................... 334

10.9.1. Примеры решения задач ..................................................................... 334

Список литературы ............................................................................................ 354

6

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

них действительно хороши. Хороший язык программирования должен быть одновременно эффективным и гибким, а его синтаксис – кратким, но ясным. Он должен поддерживать самые современные возможности программирования. Именно таким языком и является C#.

Язык C# был создан корпорацией Microsoft для поддержки среды .NET Framework и опирается на богатое наследие в области программирования. Его главным разработчиком был Андерс Хейльсберг (Anders Hejlsberg) – известный специалист по программированию.

C# происходит напрямую от двух самых удачных в области программирования языков: C и C++. От языка C он унаследовал синтаксис, многие ключевые слова и операторы, а от C++ – усовершенствованную объектную модель. Кроме того, C# тесно связан с Java – другим не менее удачным языком. На рис.1 приведено генеалогическое дерево C#.

Рисунок 1 – Генеалогическое дерево C#

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

В языке C# удачно сочетаются испытанные средства программирования с самыми последними новшествами, и предоставляется

7

возможность для эффективного написания программ, предназначенных для вычислительной среды современных предприятий. Это, без сомнения, один из самых важных языков программирования XXI века.

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

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

В главе 1 изложены общие сведения о языке С#: элементы языка, типы данных, переменные, константы, операции и выражения, математические функции (методы).

В главе 2 рассмотрены операторы присваивания, ветвления, оператор безусловного перехода, приведены примеры программ линейной и разветвленной структуры.

В главе 3 представлены операторы цикла. Главы 4 и 5 посвящены изучению одномерных массивов и обработки

матриц: объявление, ввод – вывод элементов массива, накопление суммы и произведения элементов массива.

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

Глава 7 посвящена обработке строк. Описаны методы обработки строк.

Глава 8 познакомит студента с основами объектно-ориентированного программирования, с понятиями классы и объекты. Кроме того, в главе 8 рассмотрены еще две категории типов значений: структуры и перечисления.

В главе 9 описано использование файлов в языке С#. Приводятся примеры файлового хранения числовых и текстовых данных.

Глава 10 – лабораторный практикум, в котором по каждой теме приведены примеры решения задач и варианты для самостоятельной работы.

8

ГЛАВА 1 ОБЩИЕ СВЕДЕНИЯ О ЯЗЫКЕ C#

1.1 Элементы языка, типы данных, переменные, константы

Элементы языка C#

Множество символов языка C# включает прописные и строчные

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

В C# большие и маленькие буквы разные, как в именах переменных, так и при написании служебных слов.

Лексема – это минимальная единица языка, имеющая самосто-ятельный смысл. Существуют следующие виды лексем: имена (иденти-фикаторы), ключевые слова, знаки операций, разделители, константы.

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

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

Таблица 1.1 – Ключевые слова C# abstract ascending as base bool break byte case catch char checked class const continue decimal default delegate descending do double dynamic else enum equals event explicit extern false finally fixed float for foreach from goto group if implicit in int

9

Окончание таблицы 1.1 into interface internal is join let lock long namespace new null object on operator orderby out override params partial private protected public readonly ref return sbyte sealed select short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using value var virtual volatile void where while

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

Таблица 1.2 – Типы данных C# Тип

данных Значение

Что хранит

Занимает в

памяти 1 2 3 4

Int от –2 147 483 648 до 2 147 483 647

Целочисленный тип

4 байта

Uint От 0 до 4 294 967 295 Целочисленный без знака

4 байта

Long от – 9 223 372 036 854 775 808 до 9 223 372 036 854 775 807

Длинный целочисленный

8 байтов

Ulong от 0 до 18 446 744 073 709 551 615

Длинный целочисленный без знака

8 байтов

Byte От 0 до 255(без знака) 8- ми разрядный целочисленный без знака (двоичные числа)

1 байт

Sbyte От –128 до 127 8-ми разрядный целочисленный со знаком

1 байт

10

Окончание таблицы 1.2 1 2 3 4

Short От –32768 до 32767 Короткий целочисленный

2 байта

Ushort От 0 до 65535 Короткий целочисленный без знака

2 байта

Double от ±5,0e–324 до ±1.7e+308 Числа с плавающей точкой двойной точности

8 байтов

float От ±1.5E–45 до ±3.4E+38 Числа с плавающей точкой одинарной точности

4 байта

decimal От ±7,9E–28 до ±7.9E+28 Десятичный (для финансовых расчетов)

16 байтов

Bool True, False Логический, представляет два значения: истина или ложь .

различно

Char Один символ Символьный (один символ –кодировка Unicode)

2 байта

String От 0 до 2 миллиардов символов в кодировке Unicode

Строковый тип Различно

Константы

Константами называют неизменяемые величины. В C# есть целые,

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

Пример 10 – это целочисленная константа; a – это символьная константа (символ, заключенный в апострофы); 15.347 – это вещественная константа с фиксированной точкой; 1.34e3 – это вещественная константа с порядком (1.34e3 = 13401034,1 3 ). True – это константа типа bool; False – это константа типа bool.

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

11

типов: int, uint, long, ulong в зависимости от значения константы. Явно указать тип константы можно с помощью суффикса.

Пример 12 – константа типа int 12L – константа типа long 10.23F –это константа типа float

Пример Информатика – это строковая константа (набор символов, заключенных в двойные кавычки). Помимо обычных символов, строковая константа может содержать одну или несколько управляющих последовательностей символов. Среди них самые распространенные: \n – перевод строки; \t – горизонтальная табуляция.

Пример Console.WriteLine(Первая строка\nВторая строка\nТретья строка); Console.WriteLine(Один\tДва\tТри);

Результат: Первая строка Вторая строка Третья строка Один Два Три;

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

Пример Console.WriteLine(@Первая строка Вторая строка Третья строка);

12

Результат: Первая строка Вторая строка Третья строка

Именованные константы

Именованные константы применяются для того, чтобы вместо значений констант можно было использовать в программе их имена. Такие константы при описании задаются ключевым словом const. Пример const int b=10, float y=0.15F;

Переменные

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

Синтаксис оператора объявления переменной: тип имя_переменной;

Пример int i, k; bool b1; float x; char c; double z;

Имена переменных называют идентификаторами. В идентифика-торе могут использоваться буквы, цифры и символ подчеркивания. Первым символом идентификатора может быть буква или знак подчеркивания, но не цифра. Длина идентификатора не ограничена. Пробелы внутри имен не допускаются. Идентификатор не должен совпадать с ключевыми словами. В идентификаторах C# можно использовать буквы разных алфавитов, например, русского или греческого. Прописные и строчные буквы различаются, например, A и a – два разных имени.

Задать значение переменной можно с помощью оператора

13

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

Синтаксис оператора: тип имя_переменной = значение;

где значение – это конкретное значение, задаваемое при создании переменной. Оно должно соответствовать указанному типу переменной.

Пример int i=10; // задать начальное значение 10 переменной i float y = 1.245F; // переменная f инициализируется числовым значением 1,245 double z = 5.76; // или z = 5.76D; z = -76.45d; s1 = ABCDEF; b1 = true;

При присваивании числового значения (константы) переменной типа float следует использовать суффикс F(f).

При присваивании переменной double или float константы следует ставить после десятичной точки 0, даже если число не имеет значащих десятичных знаков. В противном случае число может интерпретироваться компилятором как целое.

Пример double a = 123.0; float w = 827.0f;

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

Типы с плавающей точкой позволяют представлять числа с дробной частью. Для математических расчетов наибольшей популярностью пользуется тип double, так как позволяет производить вычисления с большой точностью. Этот тип используется во многих математических функциях библиотеки C#. Например, метод Math.Sqrt(x) возвращает значение типа double, которое представляет собой квадратный корень из аргумента типа double, передаваемого данному методу.

14

Тип decimal предназначен для денежных расчетов. При присваивании константы переменной типа decimal следует использовать суффикс M(m), например: Decimal cost = 13569.34m, size = 9845M;

Пример bool b1= true, b2= false; тип bool – это булевы переменные, для них определены только два значения: true (истина) и false (ложь).

Пример Char a = x; // символьная переменная string b = первая строка; // строковая переменная

Неявно типизированные переменные

Неявно типизированная переменная объявляется с помощью

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

Пример var x = 2.4578; В данном примере переменная x инициализируется вещественной констан-той, которая по умолчанию имеет тип double, и поэтому переменная отно-сится к типу double.

Пример var y = 4.5783F; // переменная отнесена к типу float

Явное и неявное преобразование данных

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

Общее правило: неявно можно выполнять все преобразования,

15

которые не приведут к потере информации. Поэтому данные типов bool, double, decimal не могут быть неявно преобразованы ни в какие типы данных. Тип float может быть преобразован в double; int может быть преобразован в long, float, double, decimal; long может быть преобразован в float, double, decimal. Явное преобразование выполняется следующим образом: (новый тип данных) переменная

Пример x = (float)56.3; // константа типа double преобразуется в float i = (int)8.6; // результат i = 8

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

Область видимости переменных

Область видимости локальной переменной или локальной константы ограничена текущим блоком. Блок операторов представляет собой последовательность операторов, заключенную в фигурные скобки (токены { }). В этом блоке нельзя объявить другую локальную переменную с тем же именем.

1.2 Операции и выражения в языке C#, математические функции (методы)

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

состоит из операндов (констант, переменных, обращений к функциям), круглых скобок и знаков операций.

Пример: a*b–Math.sin(x)

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

16

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

Арифметические операции сложения, вычитания, умножения и деления применимы к любым числовым типам. Арифметические операции обозначают привычными знаками +, –, *, /, %.

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

Пример i = 14; k = 4; x = (float)i/k;

Ниже в табл.1.3 приведены арифметические операции, в табл.1.5 и

табл. 1.6 – операторы сравнения и логические операторы, которые использует C#. К арифметическим данным могут применяться математи-ческие функции (методы), которые содержаться в библиотеке Math. С помощью методов этого класса можно вычислить:

тригонометрические функции: Sin(x), Cos(x), Tan(x); обратные тригонометрические функции: Asin(x), Acos(x), Atan(x); гиперболические функции: Tanh(x), Sinh(x), Cosh(x); экспоненту и логарифмические функции Exp(x), Log(x), Log10(x),

Log(x,a); модуль (абсолютную величину), квадратный корень, знак: Abs(x),

Sqrt(x), Sign(x); округление: Ceiling(x), Floor(x), Round(x); минимум, максимум: Min(x,y); Max(x,y); степень, остаток: Pow(x,y), IEEERemainder(x,y); полное произведение двух целых величин: BigMul(x,y); деление и остаток от деления: DivRem(x,y,rem).

Кроме того, у класса Math есть два полезных поля: число и число e . Список математических методов класса System.Math приведен в таблице 1.4.

17

Таблица 1.3 – Арифметические операции Операция Знак Запись Действие

Арифметическое сложение + a + b Складывает два числа Унарный плюс + +а Арифметическое вычитание – a – b Вычитает из одного числа другое Унарный минус – –a Умножение * a * b Умножает два числа Деление / a / b Делит два числа и возвращает

результат с плавающей точкой

Деление по модулю (операция вычисления остатка)

% a%b Получение остатка от целочис-ленного деления (7%3=1). Можно применять и к типам с плавающей точкой (10.0%3.0=1).

Присваивание = a=b Задает новое значение переменной Инкремент + + i++;

++i; постфиксная форма, i = i+1; префиксная форма, i = i+1.

Декремент – – i– –; – – i;

постфиксная форма, i = i–1; префиксная форма, i = i–1.

Доступ к элементу . (точка) Выбор члена (класса или объекта) Выделение памяти new Создание объекта (создание

экземпляра)

Таблица 1.4 – Список математических методов класса System.Math Математические

методы Обозначение в

математике Назначение

1 2 3 Math.Abs(x) x Модуль (абсолютная величина числа x )

Math.Acos(x) arccos x Арккосинус числа x (в диапазоне от –1 до 1)

Math.Asin(x) arcsin x Арксинус числа x (в диапазоне от –1 до 1)

Math.Atan(x) arctg x Арктангенс числа x (в диапазоне от –1 до 1)

Math.Ceiling(x) Округление до большего целого. Возвращение ближайшего целого, большего, чем значение аргумента x. Пример Math.Ceiling(1.04) даст в результате 2

Math.Cos(x) cos x Косинус угла x . Угол x задается в радианах.

DivRem(x,y,rem) Деление и остаток

Math.E e Основание натурального логарифма (e = 2,718)

18

Окончание таблицы 1.4 1 2 3

Math.Exp(x) xe Экспонента. e – основание натурального логарифма, возведенное в степень x .

Math.Floor(x) Округление до меньшего целого. Возвращает ближайшее целое число, меньшее, чем значение аргумента x . Пример Math.Floor(1.04) даст в результате 1

Math.IEERemainder(x,y) Остаток от деления. Возвращает остаток от деления числа x на число y

Math.Log(x) ln x Натуральный логарифм x , где 0x Math.Log10(x) lg x Десятичный логарифм x

Math.Log(x, a) loga x Логарифм x по основанию a

Math.Max(x,y) Максимум из двух чисел.

Math.Min(x,y) Минимум из двух чисел.

Math.PI – константа Значение числа =3,1415926

Math.Pow(x,y) yx Возведение x в степень y

Math.Round(x) Округление. Округляет заданное число до ближайшего целого (арифметическое округление) Пример Math.Round(3.1) даст в результате 3. Math.Round(3.8) даст в результате 4.

Math.Round(x, n) Округление. Округляет число с плавающей запятой до заданного количества дробных разрядов n

Math.Sign(x) Знак числа. Возвращает значение, определяющее знак

целого числа. 1 0

( ) 0 если 01 0

xSign x x

x

Math.Sin(x) sin x Синус угла x . Угол x задается в радианах.

Math.Sqrt(x) x Корень квадратный из числа x , где 0x

Math.Tan(x) tg x Тангенс угла x . Угол x задается в радианах.

Math.Truncate(x) Вычисляет целую часть заданного десятичного числа.

Rnd(x) Случайное число из диапазона 0 – 1

19

Примечание. Результат вычисления большинства математических функций – тип double, аргументы функций также должны быть типа double, например, Math.Sin(double x). Названия функций пишутся с большой буквы. Результат функции Math.Sign(x) имеет тип int.

Таблица 1.5 – Операторы сравнения

Оператор Знак Запись равно == a==b не равно != a!=b

больше > a>b

меньше < a<b

больше или равно >= a>=b

меньше или равно <= a<=b

Таблица 1.6 – Логические операторы Оператор Значение & логическое И (AND) | логическое ИЛИ (OR) ^ логического исключающее ИЛИ (XOR) ! логическое отрицание НЕ (NOT) && условное И (AND) || условное ИЛИ (OR)

C# предоставляет несколько логических операций, которые можно

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

результат выполнения логической операции также относиться к типу bool.

Логические операторы &, |, ^ и ! поддерживают основные логи-ческие операции И, ИЛИ, исключающее ИЛИ и НЕ.

Логическое И (&) возвращает true, если оба операнда дают значение true.

Логическое ИЛИ (|) возвращает true, если хотя бы один из операндов дает значение true.

Логическое отрицание НЕ (!) возвращает true, если выражение дает false, или false, если выражение дает true.

Логическое исключающее ИЛИ (^) возвращает true, если один из

20

операндов дает значение true, а другой – false. Если оба операнда истины или ложны, то все условие будет целиком ложным.

В C# предусмотрены также условные версии (&& и ||) логических операторов (& и |). Они называются условными И и ИЛИ, так как второй операнд в них вычисляется только при необходимости. Если значение левого операнда однозначно определяет значение всего выражения, то значение второго операнда не вычисляется. В выражении x&&y значение y не вычисляется, если x имеет значение false. В выражении x||y значение y не вычисляется, если x равно true. Операции && и ||

предназначены для получения более эффективного кода.

Приоритет выполнения операторов: 1) Унарные операции (операции с одним операндом, например

изменение знака); 2) Операторы умножения / деления; 3) Операторы сложения / вычитания; 4) Операторы сдвига; 5) Операторы сравнения (причем операторы равно/ не равно имеют

меньший приоритет); 6) Логические. 7) Оператор присваивания выполняется последним. Операторы одного уровня приоритета выполняются слева направо. Порядок вычисления по умолчанию можно изменить с помощью

круглых скобок.

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

1. Правила записи идентификаторов в С#? 2. Какие типы данных вы знаете? 3. Что такое константы и для чего они нужны? 4. Что такое переменные? 5. Для чего нужно приведение типов? 6. Назовите арифметические операции в языке С#. 7. Какие Вы знаете операции сравнения, логические операции? 8. Приоритет выполнения операторов.

21

ГЛАВА 2 ОПЕРАТОРЫ ПРИСВАИВАНИЯ, ВЕТВЛЕНИЯ, ОПЕРАТОР goto

Любое выражение, завершающееся точкой с запятой,

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

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

2.1 Базовые конструкции структурного программирования В этой главе рассматриваются основные операторы C#, составля-

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

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

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

22

реализует многократное выполнение оператора. Базовые конструкции приведены на рис.2.1.

Следование Цикл Ветвление Рисунок 2.1 – Базовые конструкции структурного программирования

Конструкции могут вкладываться друг в друга произвольным

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

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

В большинстве языков высокого уровня существует несколько реализаций базовых конструкций; в C# есть четыре вида циклов и два вида ветвлений (на два и на произвольное количество направлений). В каждом случае программист выбирает наиболее подходящие средства. Главное, о чем нужно помнить при написании программ, – они должны состоять из четкой последовательности блоков строго определенной структуры.

2.2 Оператор присваивания

Синтаксис оператора: имя_переменной = выражение;

23

Здесь имя переменной должно быть совместимо с типом выражения.

Пример y=a+b/2.0– Math.Cos(a);

Оператор присваивания позволяет создавать цепочку операций присваива-ния.

Пример int x, y, z; x=y=z=100; // присвоить значение 100 переменным x, y и z Такой способ присваивания удобен для задания общего значения целой группе переменных.

Сокращенные записи арифметических операций

В C# имеются сокращенные формы записи арифметических операций. Примеры сокращенных записей:

Операции присваивания: c+=3; равнозначно c=c+3; c–=3; равнозначно c=c–3; c*=3; равнозначно c=c*3; c/=3; равнозначно c=c/3; c%=3; равнозначно c=c%3;

Операция инкремента: i++; постфиксная форма, равнозначно i=i+1; или i+=1; ++i; префиксная форма, равнозначно i=i+1; или i+=1;

Операция декремента: i--; постфиксная форма, равнозначно i=i-1; или i-=1; --i; префиксная форма, равнозначно i=i-1; или i-=1;

Операция инкремента (++) и декремента (--), называемые также

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

В приведенном выше примере (i++ и ++i) форма инкремента (префиксная или постфиксная) особого значения не имеют. Но если

24

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

Пример 1 x=10; y=++x; Значение переменной y будет равно 11, так как значение переменной x сначала увеличивается на 1, а затем присваивается переменной y.

Пример 2 x=10; y=x++; Значение переменной y будет равно 10, так как в этом случае значение переменной x сначала присваивается переменной y, а затем увеличивается на 1. В обоих случаях значение переменной x оказывается равным 11. Отличие состоит лишь в том, когда именно это значение станет равным 11: до или после его присваивания переменной y.

2.3 Ввод-вывод в консольном режиме

Программируя на C# в .NET Framework, можно разрабатывать: консольное приложение, Windows-приложение.

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

В языке C# нет операторов ввода и вывода. Вместо них используются функциональные методы класса Console, входящего в библиотеку классов программной платформы Microsoft NET Framework. Эту библиотеку называют Framework Class Library, или сокращенно FCL.

25

Библиотека FCL является одним из важнейших компонентов всей платформы Microsoft NET Framework.

Класс Console определён в пространстве имён System. Почти во всех консольных программах применяются методы этого класса: Write(выводимая строка); WriteLine(выводимая строка); ReadLine() – возвращает введенную строку.

Важное обстоятельство: метод ReadLine() всегда возвращает данные типа string, в случае необходимости преобразования должны быть запрограммированы.

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

Для преобразования типов данных можно использовать методы класса Convert. Например, ToInt32 выполняет перевод в int, ToDouble выполняет перевод в double, ToString выполняет перевод в string. Какие методы имеются в классе Convert можно узнать очень легко: достаточно набрать это слово, поставить точку и на экране появится весь перечень его методов.

Линейные программы

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

Задача 2.1. Ввести два числа, выполнить несложные вычисления и вывести результат.

Программный код: using System; namespace C130 { class Program {

26

static void Main(string[] args) { int i; double x, y, z; Console.Write("Введите i= "); // подсказка при вводе // Ввод, совмещенный с преобразованием, // вводится строка, которая преобразуется в целое число i=Convert.ToInt32(Console.ReadLine()); Console.Write("Введите x= "); x = Convert.ToDouble(Console.ReadLine()); y = i * x; z = Math.Pow((2*i-x), 3); // Вывод с автоматическим преобразованием Console.WriteLine("y=" + y); // Вывод с явным преобразованием Console.WriteLine(Convert.ToString(z)); Console.ReadLine(); } } }

Результаты расчета см. рис.2.2.

Рисунок 2.2 – Результат решения задачи 2.1 Примечание. Если аргумент метода WriteLine() содержит символьную строку

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

2.4 Метки и оператор безусловного перехода goto

Оператор goto представлят собой оператор безусловного перехода.

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

27

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

Задача 2.2. Найти сумму целых чисел от 1 до 100.

Фрагмент программного кода: x=1; loop1: x++; if (x<100) goto loop1;

Оператор goto loop1; передаст управление оператору, перед которым стоит метка loop1.

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

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

2.5 Операторы ветвления: оператор if и оператор switch

Операторы ветвления if и switch применяются для того, чтобы в

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

2.5.1 Условный оператор if

Условный оператор if используется для разветвления процесса

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

28

Рисунок 2.3 – Структурная схема условного оператора Синтаксис оператора: if (условие) оператор_1; else оператор_2; где if, else – зарезервированные слова, условие – это условное выражение, оператор_1, оператор_2 – любые исполняемые операторы или блоки опе-раторов.

Условный оператор работает следующим образом. Вначале вычисля-ется логическое выражение. Если логическое выражение равно true, выполняется оператор_1. В противном случае, когда выражение равно false, выполняется оператор_2.

Ниже приведена общая форма оператора if, в котором используются блоки операторов. if (условие) { последовательность операторов } else { последовательность операторов }

29

Допустима сокращенная форма условного оператора, в которой отсутствует else и оператор_2. В этом случае при ложности проверяемого условия никакие действия не выполняются, например: if(a>0) a=-a;

Оператор_1 и оператор_2 могут быть условными, что позволяет организовать цепочку проверок условий любой глубины вложенности. В этих цепочках каждый из условных операторов (после проверяемого условия и после else) может быть как полным условным, так и иметь сокращенную форму записи. При этом могут возникать ошибки неоднозначного сопоставления if и else. Синтаксис языка предполагает, что при вложениях условных операторов каждое else соответствует ближайшему к нему предшествующему if. Пример фрагмента программы, в котором переменной result необходимо присвоить максимальное из трех значений переменных x, y, z.

if (x<y) if (y<z) result=z; else result=y; else if (x<z) result=z; else result=x;

Конструкция if – else – if

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

рукция if – else – if, состоящая из вложенных операторов if. Ниже приведена ее общая форма:

if (условие) оператор; else if (условие) оператор; else if (условие) оператор; . . .

else оператор;

30

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

Задача 2.3. Определить, является ли число положительным, отрица-

тельным или нулевым.

Программный код: using System;

namespace C129 { class Program { static void Main(string[] args) { double x; Console.WriteLine("Введите число"); x = Convert.ToDouble(Console.ReadLine()); Console.Write("Введено число " + x + "-"); if (x < 0) Console.WriteLine("отрицательное число"); else if (x == 0) Console.WriteLine("нулевое число"); else Console.WriteLine("положительное число"); Console.ReadLine(); } } }

Результаты расчета см. рис.2.4.

31

Рисунок 2.4 – Результаты решения задачи 2.3 Задача 2.4. Вычислить значения функции

2 0, 03 если 0, 0

1 0, 0

a ba bz a b a b

a a b

при 2; 5;

3,5; 7;5; 8;

a ba ba b

Программный код: using System; namespace C135 { class Program { static void Main(string[] args) { double a, b, z; Console.WriteLine(" Введите a= "); a=Convert.ToDouble(Console.ReadLine()); Console.WriteLine(" Введите b= "); b = Convert.ToDouble(Console.ReadLine()); z = 0; if (a > 0 && b > 0) z = 3 * a * a - b; else if (a < 0 && b < 0) z = a + b; else if (a > 0 && b < 0) z = a - 1; Console.WriteLine("a= {0}; b={1}; z={2,5:F2}", a, b, z); Console.ReadLine(); } } }

Результаты расчета см. рис.2.5.

32

Рисунок 2.5 – Результаты решения задачи 2.4

2.5.2 Оператор выбора switch

Оператор switch (переключатель) предназначен для разветвления

процесса вычислений на несколько направлений. Структурная схема оператора приведена на рис.2.6.

Рисунок 2.6 – Структурная схема оператора switch

33

Синтаксис оператора: switch (выражение) { сase константа 1:

последовательность операторов_1; break;

сase константа 2: последовательность операторов_2; break; . . .

сase константа n: последовательность операторов_n; break;

default: последовательность операторов; break;

}

где switch, сase, default – зарезервированные слова.

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

Заданное выражение в операторе switch должно быть целочисленного типа (char, byte, short или int), перечислимого или же строкового. А выражения других типов, например с плавающей точкой, в операторе switch не допускаются. Кроме того, константы выбора должны иметь тип, совместимый с типом выражения.

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

В двух или более ветвях сase разрешается ссылаться с помощью меток на одну и ту же кодовую последовательность. Оператор break является во всех приведенных выше случаях обязательным.

34

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

Программный код: using System; namespace C8a { class Program { static void Main(string[] args) { int M; Console.Write("Введите номер текущего месяца -> "); M = Convert.ToInt32(Console.ReadLine()); switch (M) { case 12: case 1: case 2: Console.WriteLine("Зима"); break;

case 3: case 4: case 5: Console.WriteLine("Весна"); break;

case 6: case 7: case 8: Console.WriteLine("Лето"); break;

case 9: case 10: case 11: Console.WriteLine("Осень"); break;

default: Console.WriteLine("Число должно быть в диапазоне 1..12");

35

break; } Console.ReadLine(); } } }

Результаты расчета см. рис.2.7.

Рисунок 2.7 – Результаты решения задачи 2.5

Задача 2.6. В данной задаче вводится возраст человека и в консоль-

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

Программный код: using System; namespace C133 { class Program { static void Main(string[] args) { int age; // возраст человека Console.WriteLine("Введите возраст: "); age = Convert.ToInt32(Console.ReadLine()); int p = 0; if ((age >= 0) && (age < 7)) p = 1; if ((age >= 7) && (age < 17)) p = 2; if ((age >= 17) && (age < 25)) p = 3; if ((age >= 25) && (age < 50)) p = 4; if ((age >= 50) && (age < 80)) p = 5; if (age>=80) p=6;

36

switch(p) { case 1: Console.WriteLine("ребёнок"); break; case 2: Console.WriteLine("школьник"); break; case 3: Console.WriteLine("юноша"); break; case 4: Console.WriteLine("взрослый человек"); break; case 5: Console.WriteLine("пожилой человек"); break; case 6: Console.WriteLine("старый человек"); break; default: Console.WriteLine("Вы ввели отрицательное число "); break; } Console.ReadLine(); } } }

Результаты расчета см. рис.2.8.

Рисунок 2.8 – Результаты решения задачи 2.6

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

1. Назовите базовые конструкции структурного программирования. 2. Напишите синтаксис оператора присваивания. 3. Какие Вы знаете сокращенные записи арифметических операций? 4. Как осуществляется ввод – вывод в консольном режиме? 5. Какие вы знаете операторы ветвления?

37

ГЛАВА 3 ОПЕРАТОРЫ ЦИКЛА: for, while, do-while

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

многократно. В C# имеется четыре вида циклов:

цикл с параметром for; цикл с предусловием while; цикл с постусловием do-while; цикл foreach.

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

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

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

итерации либо до тела цикла (цикл с предусловием), либо после тела цикла (цикл с постусловием).

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

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

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

цикла в целом. Для этого служат операторы break, continue, return, goto. Передавать управление извне внутрь цикла запрещается.

38

Начальные установки

Условие

Операторы

Модификацияпараметра

цикла

Начальные установки

Операторы

Модификация параметра

цикла

Условие

Блок-схема операторов цикла с

предусловием Блок-схема операторов цикла с

постусловием

Рисунок 3.1 – Блок-схемы операторов цикла

3.1 Цикл с параметром for Синтаксис: for (инициализация; условие; итерация) оператор; или для блока операторов

for (инициализация; условие; итерация) { последовательность операторов }

где инициализация, как правило, представлена оператором присваивания,

39

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

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

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

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

Задача 3.1. Вывести на консоль значения первых десяти целых чисел

при помощи оператора цикла for.

Программный код: using System; namespace C13 { class Program { static void Main(string[] args) { int i; for (i = 1; i <= 10; i++) Console.WriteLine(" " + i); Console.ReadLine(); } } }

Результаты расчета см. рис. 3.2.

40

Рисунок 3.2 – Результаты решения задачи 3.1

Задача 3.2. Программа выводит числа, постепенно уменьшающиеся от 20 до –20 на величину 5.

Программный код: using System; namespace C13a { class Program { static void Main(string[] args) { int k; for (k=20; k>=-20; k=k-5) Console.WriteLine(k); Console.ReadLine(); } } }

Результаты расчета см. рис. 3.3.

Рисунок 3.3 – Результаты решения задачи 3.2

41

Задача 3.3. Использование в операторе for две или более перемен-ных для управления циклом

Программный код: using System;

namespace C14 { class Program { static void Main(string[] args) { int i, j; for (i = 0, j = 10; i < j; i++, j--) Console.WriteLine("i и j: " + i + " " + j); Console.ReadLine(); } } }

Результаты расчета см. рис. 3.4.

Рисунок 3.4 – Результаты решения задачи 3.3

Примечание. Когда цикл начинается, инициализируются обе переменные i и j. Всякий раз, когда цикл повторяется, переменная i инкрементируется, а переменная j декрементируется.

3.2 Цикл с предусловием while

Синтаксис: while (условие) оператор;

или для блока операторов

42

while (условие) { последовательность операторов }

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

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

Задача 3.4. Вывести на консоль значения первых десяти целых чисел

при помощи оператора цикла while.

Программный код: using System; namespace C15 { class Program { static void Main(string[] args) { int i = 1; while (i <= 10) { Console.WriteLine(" " + i); i++; } Console.ReadLine(); } } }

Результаты расчета см. рис. 3.5.

43

Рисунок 3.5 – Результаты решения задачи 3.4

В данной задаче до начала цикла while переменной i присваивается значение 1. В цикле сначала проверяется значение i, если оно меньше или равно 10, то переменная i инкреминируется и значение i выводится на экран. Цикл повторяется до тех пор, пока значение переменной i меньше или равно 10. Как только оно окажется больше 10, цикл завершается.

3.3 Цикл с постусловием do-while

Синтаксис: do { операторы; } while (условие);

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

В отличие от оператора while, в котором условие проверялось в самом начале цикла, в операторе do-while условие выполнения цикла проверяется в самом его конце. Это означает, что цикл do-while всегда выполнится хотя бы один раз.

Цикл do-while выполняется до тех пор, пока условное выражение истинно.

44

Задача 3.5. Вывести на консоль значения первых десяти целых чисел при помощи оператора цикла do-while.

Программный код: using System;

namespace C17 { class Program { static void Main(string[] args) { int i = 1; do { Console.Write(" " + i); i++; } while (i <= 10); Console.WriteLine(); Console.ReadLine(); } } }

Результаты расчета см. рис. 3.6.

Рисунок 3.6 – Результаты решения задачи 3.5

3.4 Оператор break для выхода из цикла

С помощью оператора break можно организовать немедленный

выход из цикла. Задача 3.6. Использование оператора break для выхода из цикла

45

Программный код: using System; namespace C18 { class Program { static void Main(string[] args) { for (int i = -5; i <= 5; i++) { if (i > 0) break; //завершить цикл, как только //переменная i станет положительная Console.Write(i + " "); } Console.WriteLine(); Console.ReadLine(); } } }

Результаты расчета см. рис. 3.7.

Рисунок 3.7 – Результаты решения задачи 3.6

Примечание. В данном примере цикл for организован для выполнения в

пределах от –5 до 5, но несмотря на это, оператор break прерывает его раньше, когда значение переменной i становится положительным.

3.5 Применение оператора continue

Оператор continue осуществляет принудительный переход к

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

Задача 3.7. Оператор continue используется в качестве вспомо-

гательного средства для вывода четных чисел в пределах от 0 до 10.

46

Программный код: using System; namespace C19 { class Program { static void Main(string[] args) { for (int i = 0; i <= 10; i++) { if ((i % 2) != 0) continue; //перейти к след. шагу итерации Console.Write(" " + i); } Console.WriteLine(); Console.ReadLine(); } } }

Результаты расчета см. рис. 3.8.

Рисунок 3.8 – Результаты решения задачи 3.7

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

1. Что такое циклы, для чего они нужны? 2. Какие типы циклов бывают? 3. Какие Вы знаете операторы цикла? 4. Как прервать цикл? 5. Как перейти к следующей итерации, пропустив оставшиеся операторы тела цикла?

47

ГЛАВА 4 ОДНОМЕРНЫЕ МАССИВЫ

4.1 Описание одномерных массивов

Массивы представляют собой совокупность переменных одного типа

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

Пример – одномерный массив из восьми элементов вещественных чисел A(8): i 0 1 2 3 4 5 6 7 Значение элемента

1.5 3.56 4.7 7.14 8.23 10.5 12.7 14.2

Здесь под общим именем A объединено 8 ячеек памяти, содержащих однотипные элементы – вещественные числа; i – индекс (номер) элемента в массиве.

Доступ к отдельному элементу массива осуществляется по индексу (номеру). Элементы массива нумеруются с нуля. Минимальный индекс элемента равен нулю, максимальный индекс элемента равен количеству элементов минус один. Количество элементов называется размером массива.

При обращении к элементам массива указывается имя массива, а в скобках – его индекс, например: A[5]=10.5

Пример – одномерный массив из 12 элементов Fam(12): i Элементы массива i Элементы массива

0 Астахов 6 Литвинов 1 Виноградова 7 Кравченко 2 Воробьев 8 Лысенко 3 Григорьев 9 Мудров 4 Гусева 10 Нестеренко 5 Дудченко 11 Турчин

48

Здесь под общим именем Fam объединено 12 ячеек памяти, содержащих однотипные строковые величины – фамилии; i– индекс (номер) элемента в массиве.

При обращении к элементам массива указывается имя массива, а в скобках – его индекс, например:

Fam[1]= " Виноградова " Fam[9]= " Мудров " В C# массивы реализованы в виде объектов, поэтому перед

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

Пример Создается массив из 8 элементов вещественных чисел. Операция new

выделяет память под 8 вещественных элементов, и они заполняются нуля-ми:

double[] A = new double[8]; Пример Создается массив из 12 строк: string[] Fam = new string[12]; Варианты объявления одномерного массива: тип [] имя; тип [] имя = new тип [размер]; тип [] имя = {список_инициализаторов}; тип [] имя = new тип [] {список_инициализаторов}; тип [] имя = new тип [размер] {список_инициализаторов};

где тип – объявляет конкретный тип элементов массива; тип

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

размер – определяет число элементов массива.

49

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

Примеры объявлений одномерных массивов: Пример 1 int []A; // 1 объявлен массив без выделения памяти // память под элементы массива выделена ниже // в строке 5 . . . int n; // 2 Console.WriteLine(Введите количество элементов); // 3 n = Convert.ToInt32(Console.WriteLine()); // 4 A = new int[n]; // 5 В этом примере сначала описан целочисленный массив А, но объяв-

ление массива ещё не создаёт объект, который можно использовать в программе. Для инициализации массива следует указать количество его элементов (см. строку 5). При инициализации массива ему выделяется нужная память, а элементы массива получают значение 0, которое тракту-ется в зависимости от типа элементов: для числовых массивов это число 0, для строковых – пустая строка, а для символьных – отсутствие символа. После инициализации массив готов к работе.

Пример 2 int []B = new int[30];

Объявляется массив и одновременно инициализируется. Здесь совмещены объявление и инициализация.

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

В переменной В хранится ссылка на область памяти, выделяемую для массива оператором new. Эта область памяти должна быть достаточная для хранения тридцати элементов массива типа int. При этом все 30 элементов автоматически (неявно) инициализируются нулями.

Как и при создании экземпляра класса, приведенное выше объявление массива можно разделить на два отдельных оператора.

50

Пример int [] В; В = new int [30];

Пример 3 int []Q = new int[5] {2, 5, 8, 23, 45}; // 6 или int []Q = new int[] {2, 5, 8, 23, 45}; // 7 или int []Q = {2, 5, 8, 23, 45}; // 8 Одновременно с созданием массива можно наполнить его нужными

значениями. Если при этом не задан размер (строка 7), количество элементов

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

В языке C# массивы рассматривают как классы. Это дает возможность использовать при их обработке свойства. Для работы с одномерным массивом полезным окажется свойство A.Length – возвращает количество элементов массива А.

4.2 Ввод - вывод элементов одномерного массива

Ввести значения элементов одномерного массива можно следующим образом:

поэлементно с помощью оператора присваивания; при объявлении, поместив значения массива в фигурные скобки; элементы массива можно рассчитать по формуле; элементы массива можно задать при помощи генератора

случайных чисел.

Вывод элементов массива можно осуществить для консольного приложения на экран; для Windows- приложения – в поле списка ListBox.

Как уже говорилось, все массивы в C# построены на основе базового класса Array, который содержит свойства и методы, полезные при составлении программ. Ниже в таблице 4.1 приведены некоторые из них.

51

Таблица 4.1 – Основные элементы класса Array Элемент Вид Описание

Length Свойство Количество элементов массива (по всем размерностям)

Copy Статический метод

Копирование заданного диапазона элементов одного массива в другой

CopyTo Метод Копирование всех элементов текущего одномерного массива в другой одномерный массив

IndexOf Статический метод

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

LastIndexOf Статический метод

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

Reverse Статический метод

Изменение порядка следования элементов на обратный

Sort Статический метод

Упорядочивание элементов одномерного массива

Свойство Length позволяет реализовать алгоритмы, которые будут

работать с массивами различной длины. Задача 4.1. Создать целочисленный массив A(10). Элементы массива

вычисляются по формуле iai . Пояснение. Обозначение "одномерный массив A(10)" означает мас-

сив )9,...1,0 ;( iaA i , размер массива (количество элементов) =10. Ниж-ний индекс элементов массива = 0, верхний индекс элементов массива = 9.

Программный код: using System; namespace C101 { class Program { static void Main(string[] args) { int[] A = new int[10]; int i; // Вычисление элементов массива for (i = 0; i <= 9; i = i + 1) A[i] = i; // Вывод элементов массива Console.WriteLine(" Элементы массива: "); Console.WriteLine(); for (i = 0; i <= 9; i = i + 1)

52

Console.WriteLine(" A[{0}]={1} ", i, A[i]); Console.ReadLine(); } } }

Результаты расчета см. рис. 4.1.

Рисунок 4.1 – Результаты решения задачи 4.1 4.3 Накопление суммы и произведения элементов массива

Задача 4.2. Накопление суммы и произведения целочисленных

элементов массива A(10). Элементы массива вычисляются по формуле 2 iai .

Программный код: using System; namespace C102 { class Program { static void Main(string[] args) { int[] A = new int[10]; int i; double s, p; // Вычисление элементов массива for (i = 0; i <= 9; i = i + 1) A[i] = i + 2; // Вывод элементов массива Console.WriteLine(" Элементы массива: "); for (i = 0; i <= 9; i = i + 1)

53

Console.WriteLine(" A[{0}]={1} ", i, A[i]); // Накопление суммы и произведения элементов массива s = 0; p = 1.0; for (i = 0; i <= 9; i = i + 1) { s = s + A[i]; p = p * A[i]; } Console.WriteLine("Сумма элементов массива равна " + s); Console.WriteLine("Произведение элементов массива " + p); Console.ReadLine(); } } }

Результаты расчета см. рис. 4.2.

Рисунок 4.2 – Результаты решения задачи 4.2

4.4 Заполнение элементов массива при помощи генератора случайных чисел

Для заполнения элементов массива часто используются генераторы

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

54

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

Таблица 4.2 – Список методов класса Random, используемых для

генерации случайных чисел Метод Назначение Next() Возвращает неотрицательное случайное целое 32-битное

число со знаком в диапазоне 0..Int32.MaxValue (Int32.MaxValue = 2 147 483 647, или 0х7FFFFFFF в шестнадцатеричном представлении)

Next(MaxVal) Возвращает неотрицательное случайное число, не превышающее максимально допустимое значение, переданное в виде аргумента, которое должно находиться в диапазоне 0..Int32.MaxValue.

Next(MinVal, MaxVal) Возвращает случайное число n в указанном диапазоне MinVal ≤ n < MaxVal. Значения аргументов должны находиться в диапазоне 0..Int32.MaxValue. Второй аргумент должен быть больше или равен первому.

NextDouble() Возвращает случайное число в диапазоне 0,0..1,0. NextBytes(массив) Заполняет элементы указанного массива байтов случайными

числами (0..255). Задача 4.3. В данной программе создается экземпляр rnd класса

Random и на экран в цикле выводятся сгенерированные целые числа.

Программный код: using System; namespace C103 { class Program { static void Main(string[] args) { Random rnd = new Random(); for (int i = 0; i <= 9; i++) Console.WriteLine("{0,4:D} ", rnd.Next(1, 10)); Console.ReadLine(); } } }

Результаты расчета см. рис. 4.3.

55

Рисунок 4.3 – Результаты решения задачи 4.3

Пояснение: rnd.Next(1,10) – генерируется случайное целое число в диа-

пазоне 1..9. Задача 4.4. В данной программе создается экземпляр rnd класса

Random и на экран в цикле выводятся сгенерированные вещественные числа.

Программный код: using System;

namespace C104 { class Program { static void Main(string[] args) { Random rnd = new Random(); for (int i = 0; i <= 9; i++) Console.WriteLine("{0,8:F4} ", rnd.NextDouble()); Console.ReadLine(); } } }

Результаты расчета см. рис. 4.4.

Рисунок 4.4 – Результаты решения задачи 4.4

56

Пояснение: rnd.NextDouble();– генерируется случайное вещественное число в диапазоне 0,0…1,0.

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

Задача 4.5. Программа генерирует и выводит с точностью до трех

знаков вещественные числа в диапазоне –5,0..5,0. Величина указанного диапазона равна 10,0 (MaxVal – MinVal = 5– (–5) =10), поэтому коэффици-ент масштабирования равен десяти. Коэффициент сдвига равен –5,0.

Программный код: using System; namespace C105 { class Program { static void Main(string[] args) { double Scale = 10.0, Shift = -5; Random rnd = new Random(); for (int i = 0; i <= 9; i++) Console.WriteLine(" {0,8:F3} ", rnd.NextDouble() * Scale + Shift); Console.ReadLine(); } } }

Результаты расчета см. рис. 4.5.

Рисунок 4.5 – Результаты решения задачи 4.5

57

Задача 4.6. Программа определяет сумму и количество отрицатель-ных элементов одномерного массива. Программный код: using System; namespace C45a { class Program { static void Main(string[] args) { const int n = 10; int i; int[] A = new int[n] { 1,-4,-7,8,-10,12,-14,-17,20,21 }; Console.WriteLine("Массив А: "); for (i = 0; i <= n - 1; i++) Console.Write(" " + A[i]); Console.WriteLine(); long sum = 0; // сумма отрицательных элементов long num = 0; // количество отрицательных элементов for (i=0; i<=n-1; i++) if (A[i] < 0) { sum = sum + A[i]; num = num + 1; } Console.WriteLine("Сумма отрицательных элементов = " + sum); Console.WriteLine("Кол-во отрицательных элементов = " + num); Console.ReadLine(); } } }

Результаты расчета см. рис.4.6.

Рисунок 4.6 – Результаты решения задачи 4.6

58

4.5 Оператор цикла foreach для работы с одномерными массивами

Оператор foreach служит для циклического обращения к элементам коллекции, представляющей собой группу объектов. В C# определено несколько видов коллекций, каждая из которых является массивом. Синтаксис оператора: foreach (тип имя_переменной_цикла in коллекция) оператор; где коллекция обозначает циклически спрашиваемую коллекцию, кото-рая представляет собой массив. Следовательно, тип переменной цикла должен соответствовать типу элемента массива.

Оператор цикла foreach действует следующим образом. Когда цикл

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

Следует, однако, иметь в виду, что переменная цикла в операторе foreach служит только для чтения. Это означает, что присваивая этой переменной новое значение, нельзя изменить содержимое массива.

Задача 4.7. Создать одномерный массив А(7), элементы массива рассчитать по формуле. Для накопления суммы всех элементов массива использовать оператор цикла foreach.

Программный код: using System; namespace C45 { class Program { static void Main(string[] args) { const int n = 7; int[] A = new int[n];

59

int i; int sum=0; // Заполнение массива значениями и вывод на экран Console.WriteLine(" Массив А: "); for (i = 0; i <= (n - 1); i++) { A[i] = 2 * i +7; Console.Write(" " + A[i]); } Console.WriteLine(); foreach (int k in A) sum = sum + k; Console.WriteLine("\nСумма элементов массива sum = " +sum); Console.ReadLine(); } } }

Результаты расчета см. рис. 4.7.

Рисунок 4.7 – Результаты решения задачи 4.7

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

1. Назовите операторы объявления одномерных массивов. 2. Какие Вы знаете способы наполнения массивов? 3. Как осуществить ввод – вывод элементов одномерного массива? 4. Как осуществить накопление суммы и произведения элементов

одномерного массива? 5. Как произвести сортировку элементов одномерного массива?

60

ГЛАВА 5 ДВУМЕРНЫЕ МАССИВЫ

5.1 Описание двумерных массивов

Двумерный массив соответствует прямоугольной таблице, местопо-

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

Пример двумерного массива А из 5×4 вещественных чисел, i, j – индексы; i – номер строки; j – номер столбца.

j i

0 1 2 3

0 7,8 9 7 15 1 –8 4,5 2 –5 2 8,3 15,7 7,1 5,6 3 10 1,8 –3 –18 4 5 15 4,6 –9,2

Массив, приведенный в качестве примера, может быть объявлен

следующим образом: double [,] A = new double [5, 4]; //объявляется и инициализируется //массив А из 20 (5×4) вещественных чисел типа double или double [][] A = new double [5][4]; //вместо запятых можно указать //нужное количество квадратных скобок

При обращении к элементам массива указываются имя массива, а в скобках – два индекса (номер строки и номер столбца): A[1,2] = 2.0; A[2,3] = 5.6;

Обратите внимание на то, что в скобках сначала описывается нуме-рация строк (0 То 4), а затем – нумерация столбцов (0 То 3), нижняя грани-ца по каждому измерению всегда равна нулю.

Варианты описания двумерного массива:

тип[,] имя; тип[,] имя = new тип [ разм_1, разм_2 ]; тип[,] имя = { список_инициализаторов };

61

тип[,] имя = new тип [,] { список_инициализаторов }; тип[,] имя = new тип [ разм_1, разм_2 ] { список_инициализаторов };

где разм_1 – количество строк; разм_2 – количество столбцов.

Пример int[,] B = new int[2,2]; // объявляется и инициализируется двумерный массив B из 2×2 целых чисел или int[][] B = new int[2][2]; // вместо запятых можно указать нужное количество квадратных скобок

Пример int[,] C = new int[2,3] {{1,2,4}, {3,5,7}}; // объявляется двумерный массив C из 2×3 целых чисел, // одновременно массив наполняется нужными значениями.

5.2 Ввод - вывод элементов двумерного массива

Ввести значения элементов двумерного массива можно следующим образом:

поэлементно с помощью оператора присваивания; при объявлении, поместив значения массива в фигурные скобки; элементы массива можно рассчитать по формуле; элементы массива можно задать при помощи генератора

случайных чисел.

Вывод элементов массива можно осуществить:

для консольного приложения на экран; для Windows- приложения – в поле списка ListBox, в текствое

поле TextBox, на компонент DataGridView.

Для заполнения двумерного массива и вывода его в виде таблицы

62

используются вложенные циклы. Массивы принято заполнять построчно. Задача 5.1. Двумерный массив А размером 3×4 сначала заполняется

числами (элементы рассчитываются по формуле), а затем выводится его содержимое.

Программный код: using System; namespace C106 { class Program { static void Main(string[] args) { int i, j; int[,] A = new int[3, 4]; Console.WriteLine(" Массив А: "); for (i = 0; i <= 2; i++) { for (j = 0; j <= 3; j++) { A[i, j] = i + 4 * j + 1; Console.Write(A[i, j] + " "); } Console.WriteLine(); } Console.ReadLine(); } } }

Результаты расчета см. рис. 5.1.

Рисунок 5.1 – Результаты решения задачи 5.1

63

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

Пример Значения элементов двумерного массива заданы в программном коде: int[,] A= {{1, 2, 3}, {4, 5, 6 }, {7, 8, 9 }};

У многомерных массивов свойство Length возвращает общее количество элементов в массиве.

5.3 Накопление суммы элементов двумерного массива. Сумма элементов главной и побочной диагонали

Сумму всех элементов двумерного массива записывают как A или

с указанием индекса строк и столбцов

1

0

1

0

n

i

m

jijA . В записи заданы два цикла

– внешний и внутренний. Внутренний цикл считает суммы элементов строк, внешний – суммирует их в общую сумму.

Задача 5.2. Вычислить сумму элементов двумерного массива Программный код: using System;

namespace C107 { class Program { static void Main(string[] args) { const int n = 5; int[,] A = new int[n, n]; Random rnd = new Random(); int sum = 0;

64

for (int i = 0; i <= (n - 1); i++) { for (int j = 0; j <= (n - 1); j++) { A[i, j] = rnd.Next(1, 10); sum = sum + A[i, j]; Console.Write("A[{0},{1}] = {2} ", i, j, A[i, j]); } Console.WriteLine(); } Console.WriteLine(); Console.WriteLine("Сумма элементов массива А= " + sum); Console.ReadLine(); } } }

Результаты расчета см. рис. 5.2.

Рисунок 5.2 – Результаты решения задачи 5.2

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

Двумерная таблица – объект, широко используемый в математике. В линейной алгебре его называют матрицей.

Особое место среди матриц занимают такие, у которых одинаковое число строк и столбцов – n. Такие матрицы называю квадратными n-го порядка. Главной диагональю такой матрицы называют совокупность элементов A[0,0], A[1,1], A[2,2], A[3,3],..., A[n,n]. У элементов главной диагонали индексы строк и столбцов равны (i==j). Если элемент располагается ниже главной диагонали, то у него (i < j), а выше (i > j).

65

Пример матрицы

0,0A 1,0A 2,0A 3,0A

0,1A 1,1A 2,1A 3,1A

0,2A 1,2A 2,2A 3,2A

0,3A 1,3A 2,3A 3,3A

Для приведенной выше матрицы A элементами главной диагонали

являются 0,0A , 1,1A , 2,2A , 3,3A . Элементами побочной диагонали являются

3,0A , 2,1A , 1,2A , 0,3A . Отсюда видно, что индекс строк увеличивается, а ин-

декс столбцов уменьшается. В квадратной матрице n×n любую строку, столбец или диагональ можно воспринимать как вектор (одномерный массив) размером n. Для описания расположения элементов на побочной диагонали можно привести условие (i == n – j – 1).

Задача 5.3. Создать и вывести векторы из диагоналей матрицы и вычислить их суммы.

Программный код: using System; namespace C44 { class Program { static void Main(string[] args) { const int n=5; int[,] A = new int[n,n]; int[] C = new int[n]; //элементы главной диагонали int[] S = new int[n]; //элементы побочной диагонали Random rnd = new Random(); int sumC = 0; // сумма элементов главной диагонали int sumS = 0; // сумма элементов побочной диагонали int i,j; // Накопление и вывод элементов массива Console.WriteLine(" Массив А: \n ");

66

for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (n - 1); j++) { A[i, j] = rnd.Next(1, 10); Console.Write(" " + A[i, j]); } Console.WriteLine(); } //Создание одномерных массивов С[n] и S[n] и накопление их сумм for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (n - 1); j++) { if (i == j) { C[i] = A[i, j]; sumC = sumC + C[i]; } if (i == n - j - 1) { S[i] = A[i, j]; sumS = sumS + S[i]; } } } Console.WriteLine(); Console.WriteLine("Элементы главной диагонали: "); for (i = 0; i <= (n - 1); i++) Console.Write(" " + C[i]); Console.WriteLine("\nСумма элементов главной диагонали:" + sumC); Console.WriteLine("\nЭлементы побочной диагонали: "); for (i = 0; i <= (n - 1); i++) Console.Write(" " + S[i]); Console.WriteLine("\nСумма элементов побочной диагонали:"+sumS); Console.ReadLine(); } } }

67

Результаты расчета см. рис. 5.3.

Рисунок 5.3 – Результаты решения задачи 5.3

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

1. Назовите операторы объявления двумерных массивов. 2. Какие Вы знаете способы наполнения двумерных массивов? 3. Как производится ввод – вывод элементов двумерного массива? 4. Как осуществить накопление суммы и произведения элементов

двумерного массива? 5. Опишите алгоритм нахождения максимального элемента двумер-

ного массива.

68

ГЛАВА 6 МЕТОДЫ

6.1 Синтаксис определения метода

Упрощение программ с многократным использованием кода привело

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

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

Синтаксис определения метода: доступ возвращаемый_тип имя_метода (список_параметров) { // Тело метода } где

доступ – необязательный модификатор доступа. Отсутствие подразумевает private, определяет закрытый метод, доступный только внутри класса. Открытый модификатор public позволяет вызывать метод из любой другой части программы. Программы текущей работы выполняются внутри одного класса, поэтому этот модификатор будет пропущен.

возвращаемый_тип определяет, значение какого типа вычисляется с помощью метода. Часто употребляется термин «метод возвращает значение», поскольку после выполнения метода происходит возврат в то место вызывающей функции, откуда был вызван метод, и передача туда значения выражения, записанного в операторе return. Если метод не

69

возвращает никакого значения, в его заголовке задается тип void, а оператор return отсутствует.

список_параметров – последовательность пар, состоящих из типа и идентификатора и разделенных запятыми. При отсутствии параметров список остается пустым. Параметры, задаваемые в описании метода, также называются формальными параметрами (или просто параметрами). Параметры, используемые при вызове метода, называются фактическими параметрами или аргументами.

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

Константы и переменные, заданные вне методов в классе доступны во всех методах класса (и из экземпляров других классов, если описаны с модификатором public) и являются для методов класса глобальными. Переменные (и параметры) внутри методов являются локальными и теряются при выходе из метода. Более того, переменные могут быть локальными внутри программного блока {} в теле метода.

Примечание. Метод, не возвращающий значение, вызывается отдельным оператором, а метод, возвращающий значение, – в составе выражения в правой части оператора присваивания.

Параметры методов

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

1. Вычисляются выражения, стоящие на месте аргументов. 2. Выделяется память под параметры метода в соответствии с их

типом. 3. Каждому из параметров сопоставляется соответствующий аргу-

70

мент (аргументы как бы накладываются на параметры и замещают их). 4. Выполняется тело метода. 5. Если метод возвращает значение, оно передается в точку вызова;

если метод имеет тип void, управление передается на оператор, следующий после вызова.

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

Примечание. Главное требование при передаче параметров состоит в том, что

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

Задача 6.1. Написать метод, который вычисляет площадь поверх-ности параллелепипеда * * * *2S L w L h w h

Программный код: using System; namespace C52a { class Program { // площадь поверхности параллелепипеда static double ps(double L, double w, double h) { return (L * w + L * h + w * h) * 2; } static void Main(string[] args) { double L, w, h; // длина, ширина и высота параллелепипеда double s; // площадь поверхности параллелепипеда Console.WriteLine(" Вычисление площади поверхности параллелепипеда\n "); Console.WriteLine(" Введите исходные данные:"); Console.Write(" Длина (см) -> "); L = Convert.ToDouble(Console.ReadLine()); Console.Write(" Ширина (см) -> "); w = Convert.ToDouble(Console.ReadLine()); Console.Write(" Высота (см) -> ");

71

h = Convert.ToDouble(Console.ReadLine()); s = ps(L, w, h); Console.WriteLine(" \nПлощадь поверхности = {0,5:F2} кв. см.", s); Console.ReadLine(); } } }

Результаты расчета см. рис. 6.1.

Рисунок 6.1 – Результаты решения задачи 6.1

6.2 Способы передачи параметров

Существуют два способа передачи параметров: по значению и по ссылке.

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

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

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

параметры - значения; параметры - ссылки – описываются с помощью ключевого слова

ref; выходные параметры – описываются с помощью ключевого

слова out; массив параметров – описывается с помощью ключевого слова

params.

72

Ключевое слово предшествует описанию типа параметра. Если оно опущено, параметр считается параметром- значением. Массив параметров может быть только один и должен располагаться последним в списке, например:

public int Calculate( int a, ref int b, out int c, params int[] d)…

6.2.1 Параметры – значения

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

тип имя Пример заголовка метода, имеющего один параметр- значение це-

лого типа: void P( int x) Параметр x представляет собой локальную переменную, которая

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

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

6.2.2 Параметры – ссылки

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

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

73

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

Признаком параметра - ссылки является ключевое слово ref перед описанием параметра:

ref тип имя Пример заголовка метода, имеющего один параметр - ссылку целого

типа: void P( ref int x) При вызове метода в область параметров копируется не значение

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

Задача 6.2. Использование параметра- ссылки

Программный код: using System;

namespace C47 { class Program {

static void P(int a, ref int b) { a = 44; b = 33; Console.WriteLine(" внутри метода {0} {1}", a, b); } static void Main(string[] args) { int a = 2, b = 4; Console.WriteLine(" до вызова {0} {1}", a, b); P(a, ref b); Console.WriteLine(" после вызова {0} {1}", a, b); Console.ReadLine(); } } }

74

Результаты расчета см. рис. 6.2.

Рисунок 6.2 – Результаты решения задачи 6.2

В этом примере значение переменной a в функции Main не

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

6.2.3. Выходные параметры

Довольно часто возникает необходимость в методах, которые

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

Задача 6.3. Использование выходного параметра

Программный код: using System; namespace C48 { class Program { static void P(int a, out int b) { a = 44; b = 33; Console.WriteLine(" внутри метода {0} {1}", a, b); } static void Main(string[] args) { int a = 2, b;

75

P(a, out b); Console.WriteLine(" после вызова {0} {1}", a, b); Console.ReadLine(); } } }

Результаты расчета см. рис. 6.3.

Рисунок 6.3 – Результаты решения задачи 6.3

Задача 6.4. Программа демонстрирует некоторые возможности и

отличия методов, которые имеют тип возвращаемого значения и методов, которые его не имеют (имеют тип void).

Программный код: using System; namespace C116 { class Program { static void print(string line) { Console.WriteLine("Длина строки: " + line.Length); Console.WriteLine("Значение строки: " + line); } static string change(string str) { char[] rev = str.ToCharArray(); Array.Reverse(rev); return new string(rev); } static void Main(string[] args) { string numbers = "123456789";

76

print(numbers); numbers = change(numbers); print(numbers); Console.ReadLine(); } } }

Результаты расчета см. рис.6.4.

Рисунок 6.4. – Результаты решения задачи 6.4

Примечание. В классе Program три статических метода. В объявлении каждого метода класса

входит модификатор static, и такой метод называют статическим методом класса. Метод print() с типом void получает исходные данные в виде строки-

параметра и выводит длину и значение этой строки. В точку вызова метод print() ничего не возвращает.

Метод change() имеет тип отличный от void. Он получает в качестве параметра строку, формирует ее перевернутое значение и возвращает в точку вызова этот результат.

В функции Main с типом void определена строка numbers, ее значение "123456789".

В отдельном операторе вызывается метод print(numbers), который выводит сведения о строке. Затем вызывается метод change(numbers) и реверсное значение строки присваивается строковой переменной numbers. Повторное обращение к методу print() иллюстрирует изменения.

Задача 6.5. Иллюстрирует применение выходных параметров

(параметров, имеющих модификаторы ref или out). Метод возвращает целую (int n) и дробную (double tra) части

вещественного числа (double x). В функции Main() определим три переменные: double real –

исходное число, double dPart – дробная часть, int iPart – целая часть.

77

Программный код: using System; namespace C117 { class Program { static void fun(double x, out int n, out double fra) { n = (int)x; fra = x - n; } static void Main(string[] args) { double real = 53.93; double dPart; int iPart; fun(real, out iPart, out dPart); Console.WriteLine("iPart = {0}, dPart = {1}", iPart, dPart); Console.ReadLine(); } } }

Результаты расчета см. рис.6.5.

Рисунок 6.5 – Результаты решения задачи 6.5

Задача 6.6. Написать метод, который находит номер первого

отрицательного элемента в одномерном массиве, при отсутствии отрицательных чисел возвращать сообщение «Отрицательных чисел нет». Программный код: using System; namespace C119 { class Program {

78

static void ps(int[] mas, out int k) { int i; k = -8; for (i = 0; i <= mas.Length - 1; i++) if (mas[i] < 0) { k = i; break; } } static void Main(string[] args) { int[] m = { 5, 9, 2, 6, -7, 56, 100 }; int p; ps( m, out p); if (p < 0) Console.WriteLine("Отрицательных чисел нет"); else Console.WriteLine("Номер элемента " + p); Console.ReadLine(); } } }

Результаты расчета см. рис.6.6.

Рисунок 6.6 – Результаты решения задачи 6.6

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

1. Что такое методы? 2. Какие типы методов применяются в С#, синтаксис метода? 3. Перечислите типы параметров метода. 4. Как осуществляется вызов метода? 5. Каково назначение параметров метода: параметра – значения,

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

79

ГЛАВА 7 СИМВОЛЫ И СТРОКИ

Обработка текстовой информации является одной из самых

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

7.1 Символы

Символьный тип char предназначен для хранения символов в

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

Пример A «обычный символ» \n управляющая последовательность

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

Примеры управляющих последовательностей в C# \a – звуковой сигнал; \n – перевод строки; \t – горизонтальная табуляция; \v – вертикальная табуляция.

Управляющие последовательности могут использоваться и в строко-вых константах. Если требуется вывести несколько строк, можно объединить их в одну константу, отделив одну строку от другой символами \n.

Пример Каждое выражение в программе \n имеет определенный \n тип

Эта константа при выводе будет выглядеть так:

Каждое выражение в программе имеет определенный тип

80

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

Таблица 7.1 – Основные методы класса System.Char

Метод Описание GetNumericValue Возвращает числовое значение символа, если он является

цифрой, и –1 в противном случае

GetUnicodeCategory Возвращает категорию Unicode- символа. Все Unicode- символы разделены на категории, например, десятичные цифры (Decimal- DigitNumber), римские цифры (LetterNumber), разделители строк (LineSeparator), буквы в нижнем регистре (LowercaseLetter) и др.

IsControl Возвращает true, если символ является управляющим

IsDigit Возвращает true, если символ является десятичной цифрой

IsLetter Возвращает true, если символ является буквой

IsLetterOrDigit Возвращает true, если символ является буквой или цифрой

IsLower Возвращает true, если символ задан в нижнем регистре

IsNumber Возвращает true, если символ является числом (десятичным или шестнадцатеричным)

IsPunctuation Возвращает true, если символ является знаком препинания

IsSeparator Возвращает true, если символ является разделителем

IsUpper Возвращает true, если символ записан в верхнем регистре

IsWhiteSpace Возвращает true, если символ является пробельным (пробел, перевод строки и возврат каретки)

Parse Преобразует строку в символ (строка может состоять из одного символа)

ToLower Преобразует символ в нижний регистр

ToUpper Преобразует символ в верхний регистр

MaxValue, MinValue Возвращают символы с максимальным и минимальным кодами (эти символы не имеют видимого представления)

81

Задача 7.1. Применение методов класса System.Char Программный код: using System;

namespace C68 { class Program { static void Main(string[] args) { char b='B', c='\x63', d='\u0032'; Console.WriteLine("{0} {1} {2}", b, c, d); Console.WriteLine("{0} {1} {2}", char.ToLower(b), char.ToUpper(c), char.GetNumericValue(d)); char a; do { Console.Write("Введите символ: "); a = Convert.ToChar(Console.ReadLine()); Console.WriteLine("Введен символ {0}, его код - {1}", a, (int)a); if (char.IsLetter(a)) Console.WriteLine("Буква "); if (char.IsUpper(a)) Console.WriteLine("Верхний регистр"); if (char.IsLower(a)) Console.WriteLine("Нижний регистр"); if (char.IsControl(a)) Console.WriteLine("Управляющий");

if (char.IsNumber(a)) Console.WriteLine("Число "); if (char.IsPunctuation(a)) Console.WriteLine("Разделитель"); Console.WriteLine("\n"); } while (a != 'q'); Console.ReadLine(); } } }

Результаты расчета см. рис. 7.1.

82

Рисунок 7.1 – Результаты решения задачи 7.1 В операторе 1 описаны три символьные переменные. В цикле do

анализируется вводимый с клавиатуры символ. При вводе используется функция преобразования строки, которая должна содержать один символ, в символ типа Char. Поскольку вводится строка, ввод каждого символа следует завершать нажатием клавиши Enter. Цикл выполняется, пока пользователь не введет символ q.

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

7.2 Строки

Значительная часть информации, с которой работает компьютер,

текстовая, т.е. строковая. Строка – это набор символов. Символ – это знак, для которого на

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

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

Длина пустой строки равна нулю. В программах строки играют важную роль. В строках формируется

83

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

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

Для сравнения, Pascal воспринимает строку как массив символов, которые можно читать и записывать отдельно непосредственно в памяти, выделенной для хранения строки. В C# к отдельным символам строки также можно обратиться по индексу (нумерация с нуля), указанному в квадратных скобках, как к элементу символьного массива char[], но в режиме только чтения.

Для работы со строками предназначен тип string, он является встроенным типом C#. Ему соответствует базовый класс System.String библиотеки .NET.

Создание строк: 1. Объявление с инициализацией, используется строковая константа string str = Строки в C# весьма эффективны

2. Символьную строку можно ввести с клавиатуры при помощи опе-ратора Console.ReadLine(), в отличие от ввода единичного символа, который реализует функция Read.

String str = Console.ReadLine();

3. Объект типа string можно также создать из массива типа char Пример char [] charray = { t , e , s , t }; string str = new string(charray);

84

4. Конструктор класса String может сформировать строку, повторяя заданный символ (первый параметр) заданное число раз (второй параметр).

Пример string str2 = new string(3, 2);

Строка формируется двумя подряд записанными двойными кавычками – это так называемая пустая строка, длина которой равна 0.

Задача 7.2. Создать и вывести символьную строку

Программный код: using System;

namespace C69 { class Program { static void Main(string[] args) { char[] charray = { 'Э', 'т', 'о', ' ', 'с', 'т', 'р', 'о', 'к', 'а', '.'}; string str1 = new string(charray); string str2 = "Вторая строка."; Console.WriteLine(str1); Console.WriteLine(str2); Console.ReadLine(); } } }

Результат работы программы см. рис. 7.2:

Рисунок 7.2 – Результаты решения задачи 7.2

85

7.2.1 Операции, которые можно совершать над строками присваивание (=); проверка на равенство (==); проверка на неравенство (!=); обращение по индексу ([]); сцепление (конкатенация) строк (+). 1. Операция конкатенации (соединения) a) с помощью знака «+».

string str= Язык string str1=программирования string str0=str+str1+ C#; Console.WriteLine(str0 + C#);

б) при помощи функции Concat() Форма 1: public static string Concat(string str0, string str1)

Строка str1 присоединяется путем сцепления в конце строки str0.

Форма 2: public static string Concat(string str0, string str1, string str2)

В данной форме функция Concat() возвращает строку, состоящую из последовательного сцепления строк str0, str1, str2).

2. Операция сравнения Строки можно сравнивать с помощью операторов == и !=. Причем

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

if (str==str1)……. if (str!=str1)……. Строки можно также сравнивать с учетом различных особенностей

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

86

называемое сравнение с учетом культурной среды (функция Equals(), где непременно нужно указать способ сравнения в виде аргумента StringComparison.CurrentCulture). Для сравнения строк существует также метод Compare(). Этот метод служит для сравнения строк с целью определить отношение порядка, например, для сортировки. Если же требуется проверить символьные строки на равенство, то для этой цели лучше воспользоваться функцией Equals() или строковыми операторами.

Кроме того, строки можно сравнивать с учетом или без учета ре-гистра.

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

Пример string str = "информатика"; char c = str[2]; Console.WriteLine(c);

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

Строке может быть присвоено новое значение. Новое значение может иметь другое количество элементов. Пример string str= программирование; int L=str.Length; console.writeline(str + L= +L); // присваивание строке нового содержимого string str= программирование на языке C#; int L=str.Length; console.writeline(str + L= +L);

Результат работы программы: программирование L=16 программирование на языке C# L=27 Строка обладает свойством Length string str = "информатика";

87

int L = str.Length; Console.WriteLine(L);

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

Класс типа string содержит ряд методов для обращения со строками.

7.2.2 Методы класса String

1. Метод Copy Копирует строку – аргумент (str1) в строку (str2). Количество

элементов в строках не может быть различным. string str1 = "информатика"; string str2; str2 = string.Copy(str1); // копирование в ранее созданную строку Console.WriteLine(str1); Console.WriteLine(str2);

Результат работы программы: информатика информатика

Копирование можно использовать для инициализации при объявлении новой строки. string str2= string.Copy(str); // инициализация копированием

2. Метод IndexOf Определяет номер элемента строки (индекс) первого вхождения

заданной подстроки в строке (может быть и один символ). Если нужное сочетание не найдено, то возвращается значение –1.

Форма 1: public int IndexOf(char value)

В этой форме метода IndexOf() возвращается первое вхождение символа value в вызывающей строке. Если символ value в ней не

88

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

Форма 2: public int IndexOf(String value)

Форма 3: public int IndexOf(String value, StringComparison comparisonType)

Во второй форме поиск первого вхождения строки, обозначаемой параметром value, осуществляется с учетом культурной среды. А в третьей форме предоставляется возможность указать значение типа StringComparison, обозначающее способ поиска. А если искомая строка не найдена, то во второй и третьей формах данного метода возвращается значение –1.

3. Метод LastIndexOf Применяется для обнаружения последнего вхождения символа или

строки в исходной строке. Если нужное сочетание не найдено, то возвращается значение –1.

Форма 1: public int LastIndexOf(char value)

В этой форме метода LastIndexOf() осуществляется порядковый поиск, а в итоге возвращается последнее вхождение символа value в вызывающей строке или же значение –1, если искомый символ не найден. Вторая и третья формы позволяют искать последнее вхождение одной строки в другой.

Форма 2: public int LastIndexOf(String value)

Форма 3: public int LastIndexOf(String value, StringComparison comparisonType)

89

Во второй форме метода поиск последнего вхождения строки, обозначаемой параметром value, осуществляется с учетом культурной среды. А в третьей форме предоставляется возможность указать значение типа StringComparison, обозначающее способ поиска. А если искомая строка не найдена, то во второй и третьей формах данного метода возвращается значение –1.

Пример string str1 = "информатика"; string str2 = "и"; int k1 = str1.IndexOf(str2); // поиск первого вхождения буквы "и" // в строку str2

int k2=str1.LastIndexOf(str2); // поиск последнего вхождения буквы //"и" в строку str2 Console.WriteLine(k1); Console.WriteLine(k2);

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

Метод IndexOf выполняет поиск с учетом регистра символов. Если нужно выполнить поиск без учета регистра символов, то можно исходный текст и искомый фрагмент привести сначала к одному и тому же регистру с помощью функций ToLower(), ToUpper() и только потом выполнить поиск методом IndexOf.

Задача 7.3. Использование методов обработки строк Программный код: using System;

namespace C81 { class Program {

90

static void Main(string[] args) { // Продемонстрировать поиск в строке string str="C# обладает эффективными средствами обработки строк"; int idx; Console.WriteLine("Строка str: " + str); idx=str.IndexOf('о'); Console.WriteLine("\nИндекс первого вхождения символа 'о':" + idx); idx = str.LastIndexOf('о'); Console.WriteLine("\nИндекс последнего вхождения символа 'о':"+ idx); idx = str.IndexOf("ми", StringComparison.Ordinal); Console.WriteLine("\nИндекс первого вхождения подстроки \"ми\":"+ idx); idx = str.LastIndexOf("ми", StringComparison.Ordinal); Console.WriteLine("\nИндекс последнего вхождения подстроки \"ми\": " + idx); char[] chrs = {'а', 'б','в' }; idx = str.IndexOfAny(chrs); Console.WriteLine("\nИндекс первого вхождения символов " + " 'а', 'б' или 'в': " + idx); if(str.StartsWith("C# обладает", StringComparison.Ordinal)) Console.WriteLine("\nСтрока str начинается с подстроки \"C# обладает\""); if(str.EndsWith("строк", StringComparison.Ordinal)) Console.WriteLine("\nСтрока str оканчивается подстрокой \"строк\""); Console.ReadLine(); } } }

Результаты расчета см. рис. 7.3.

91

Рисунок 7.3 – Результаты решения задачи 7.3 4. Методы StartsWith() и EndsWith

public bool StartsWith(string value) public bool EndsWith(string value)

Метод StartsWith() возвращает логическое значение true, если вызывающая строка начинается с подстроки, переданной ей в качестве аргумента value. А метод EndsWith возвращает логическое значение true, если вызывающая строка оканчивается подстрокой, переданной ему в качестве аргумента value. В противном случае оба метода возвращают логическое значение false. В обоих этих методах поиск осуществляется с учетом культурной среды. Для того чтобы указать конкретный способ поиска подстроки можно воспользоваться приведенными ниже вариантами этих методов с дополнительным параметром типа StringComparison.

public bool StartsWith(string value, StringComparison comparisonType) public bool EndsWith(string value, StringComparison comparisonType)

В этих формах можно явно указать конкретный способ поиска.

5. Метод ToLower() – возвращает вариант вызывающей строки в нижнем регистре (делает строчными все буквы в вызывающей строке) public string ToLower

6. Метод ToUpper() – возвращает вариант вызывающей строки в

92

верхнем регистре (все буквы в вызывающей строке делает прописными) public string ToUpper Пример text = text.ToUpper;

7. Метод Substring() – для получения части строки. Ниже приведены две ее формы. public string Substring (int startIndex) public string Substring (int startIndex, int length)

В первой форме метода Substring()подстрока извлекается, начиная с места, обозначенного параметром startIndex, и до конца вызывающей строки.

Во второй форме данного метода извлекается подстрока, состоящая из количества символов, определяемых параметром length, начиная с места, обозначаемого параметром startIndex.

В обеих формах возвращается получающаяся в итоге подстрока.

Задача 7.4. Использование метода Substring() Программный код: using System;

namespace C74 { class Program { static void Main(string[] args) { string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Console.WriteLine("строка str: " + str); Console.WriteLine(); // выделение подстроки Console.Write("подстрока str.Substring(15) "); string substr = str.Substring(15); Console.WriteLine(substr); Console.WriteLine(); // выделение подстроки

93

Console.Write("подстрока str.Substring(0, 15) "); substr = str.Substring(0, 15); Console.WriteLine(substr); Console.ReadLine(); } } }

Результаты расчета см. рис. 7.4.

Рисунок 7.4 – Результаты решения задачи 7.4

8. Метод Insert() – для вставки одной строки в другую public string Insert (int startIndex, string value)

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

Задача 7.5. Использование метода Insert()

Программный код: using System; namespace C76 { class Program { static void Main(string[] args) { string str = "это тест"; Console.WriteLine("Исходная строка: " + str); // вставить строку str = str.Insert(4, "простой "); Console.WriteLine("Новая строка: " + str); Console.ReadLine(); } } }

94

Результаты расчета см. рис. 7.5.

Рисунок 7.5 – Результаты решения задачи 7.5 9. Метод Remove() – для удаления части строки. Ниже приведены

две формы метода. public string Remove (int startIndex) public string Remove (int startIndex, int Count))

В первой форме метода Remove() удаление выполняется, начиная с места, указываемого по индексу startIndex, и продолжается до конца строки.

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

Задача 7.6. Использование метода Remove() Программный код: using System; namespace C71 { class Program { static void Main(string[] args) { string str = "это простой тест"; Console.WriteLine("Исходная строка: " + str); // удалить часть строки str = str.Remove(4,5); Console.WriteLine("Новая строка: " + str);

95

Console.ReadLine(); } } }

Результаты расчета см. рис. 7.6.

Рисунок 7.6 – Результаты решения задачи 7.6 10. Метод Replace() – для замены части строки. Ниже приведены

две формы метода. public string Replace (char oldChar, char newChar) public string Replace (string oldValue, string newValue)

В первой форме метода Replace() все вхождения символа oldChar в вызывающей строке заменяются символом newChar.

Во второй форме данного метода все вхождения строки oldValue в вызывающей строке заменяются строкой newValue. В обеих формах возвращается получающаяся в итоге строка.

Задача 7.7. Использование метода Replace() Программный код: using System; namespace C70 { class Program { static void Main(string[] args) { string str = "это простой тест"; Console.WriteLine("Исходная строка: " + str); // заменить строку str = str.Replace("простой", "непростой"); Console.WriteLine("Новая строка: " + str); // заменить символы в строке str = str.Replace('е', 'о');

96

Console.WriteLine("Новая строка: " + str); Console.ReadLine(); } } }

Результаты расчета см. рис. 7.7

Рисунок 7.7 – Результаты решения задачи 7.7 11. Метод Contains() Возвращает логическое значение true, если вызывающая строка

содержит подстроку, обозначаемую параметром value, в противном случае – логическое значение false. Поиск указываемой подстроки осуществляется порядковым способом. Этот метод особенно полезен, если требуется только выяснить, находится ли конкретная подстрока в другой строке. Форма метода: public bool Contains(string value)

Задача 7.8. Использование метода Contains()

Программный код: using System; namespace C82 { class Program { static void Main(string[] args) { //Применение метода Contains() string str = "C# сочетает эффективность с производительностью."; if(str.Contains("эффективность")) Console.WriteLine("Обнаружена подстрока \"эффективность\"."); if (str.Contains("эффе")) Console.WriteLine("Обнаружена подстрока \"эффе\".");

97

if (!str.Contains("эффективный")) Console.WriteLine("Подстрока \"эффективный\" не обнаружена."); Console.ReadLine(); } } }

Результаты расчета см. рис. 7.8.

Рисунок 7.8 – Результаты решения задачи 3.8 12. Метод Trim() удаляет начальные и конечные пробелы (обрезка

строк). Форма 1: public string Trim()

Форма 2: public string Trim(params char[] trimChars)

В первой форме метода Trim() из вызывающей строки удаляются начальные и конечные пробелы.

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

13. Метод PadLeft() – заполнение строки символами слева, чтобы она имела необходимую минимальную длину. Для заполнения строки слева имеются две формы метода PadLeft(). Форма 1: public string PadLeft(int totalWidth)

Форма 2: public string PadLeft(int totalWidth, char paddingChar)

98

В первой форме метода PadLeft() вводятся пробелы с левой стороны вызывающей строки, чтобы ее общая длина стала равной значению параметра totalWidth. А во второй форме данного метода символы, обозначаемые параметром paddingChar, вводятся с левой стороны вызывающей строки, чтобы ее общая длина стала равной значению параметра totalWidth.

В обеих формах возвращается получающаяся в итоге строка.

14. Метод PadRight() – заполнение строки символами справа, чтобы она имела необходимую минимальную длину. Форма 1: public string PadRight(int totalWidth)

Форма 2: public string PadRight(int totalWidth, char paddingChar)

В первой форме метода PadRigth() вводятся пробелы с правой стороны вызывающей строки, чтобы ее общая длина стала равной значению параметра totalWidth. А во второй форме данного метода символы, обозначаемые параметром paddingChar, вводятся с правой стороны вызывающей строки, чтобы ее общая длина стала равной значению параметра totalWidth.

В обеих формах возвращается получающаяся в итоге строка.

Задача 7.9. Использование методов PadLeft() и PadRight() Программный код: using System; namespace C84 { class Program { static void Main(string[] args) { // Пример обрезки и заполнения строк string str = "тест"; Console.WriteLine("Исходная строка: " + str);

99

// Заполнить строку пробелами слева str = str.PadLeft(10); Console.WriteLine("|" + str + "|");

// Заполнить строку пробелами справа str = str.PadRight(20); Console.WriteLine("|" + str + "|");

// Обрезать пробелы str = str.Trim(); Console.WriteLine("|" + str + "|"); // Заполнить строку символами # слева str = str.PadLeft(10, '#'); Console.WriteLine("|" + str + "|");

// Заполнить строку символами # справа str = str.PadRight(20, '#'); Console.WriteLine("|" + str + "|");

// Обрезать символы # str = str.Trim('#'); Console.WriteLine("|" + str + "|"); Console.ReadLine(); } } }

Результаты расчета см. рис. 7.9.

Рисунок 7.9 – Результаты решения задачи 7.9

15. Метод Split() – разделение строк. При разделении строка

разбивается на составные части.

100

Форма 1: public string[] Split(params char[] separator) Форма 2: public string[] Split(params char[] separator, int count)

В первой форме метода Split() вызывающая строка разделяется на составные части. В итоге возвращается массив, содержащий подстроки, полученные из вызывающей строки. Символы, ограничивающие эти подстроки, передаются в массиве separator. Если массив separator пуст, то в качестве разделителя подстрок используется пробел. А во второй форме данного метода возвращается количество подстрок, определяемых параметром count.

16. Метод Join() – соединение строк. При соединении строка

составляется из отдельных частей Форма 1: public static string Join(string separator, string[] value) Форма 2: public static string Join(string separator, string[] value, int StartIndex, int count)

В первой форме метода Join() возвращается строка, состоящая из сцепляемых подстрок, передаваемых в массиве value. Во второй форме также возвращается строка, состоящая из подстрок, передаваемых в массиве value, но они сцепляются в определенном количестве count, начиная с элемента массива value[StartIndex].

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

Задача 7.10. Применение метода Join()

Программный код: using System; namespace C83 {

101

class Program { static void Main(string[] args) { // Разделить и соединить строки string str = "Один на суше, другой на море."; char[] seps = {' ', '.', ',' }; // Разделить строку на части string[] parts = str.Split(seps); Console.WriteLine("Результат разделения строки: "); for (int i = 0; i <= (parts.Length - 1); i++) Console.WriteLine(parts[i]); // А теперь соединим части строк string whole = string.Join("|", parts); Console.WriteLine("Результат соединения строки: "); Console.WriteLine(whole); Console.ReadLine(); } } }

Результаты расчета см. рис. 7.10

Рисунок 7.10 – Результаты решения задачи 7.10

17. Метод Equals() – проверка символьных строк на равенство. Возвращает значение True или False. Форма 1: public bool Equals(string value)

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

102

Выполняется порядковое сравнение с учетом регистра, но без учета культурной среды. Форма 2: public bool Equals(string value, StringComparison comparisonType)

Возвращает логическое значение True, если вызывающая строка содержит ту же последовательность символов, что и строка value. Параметр comparisonType определяет конкретный способ сравнения строк. Форма 3: public static bool Equals(string a, string b, StringComparison comparisonType)

Возвращает логическое значение True, если строка a содержит ту же последовательность символов, что и строка b. Параметр comparisonType определяет конкретный способ сравнения строк.

Тип StringComparison представляет собой перечисление, в котором определяются значения, приведенные ниже. Добавление параметра типа StringComparison расширяет возможности функций Compare() и Equals(). Это дает также возможность однозначно указывать способ предполагаемого сравнения строк. В силу имеющихся отличий между сравнением строк с учетом культурной среды и порядковым сравнением очень важно быть предельно точным в этом отношении.

Значения, определяемые в перечислении StringComparison 1) Ordinal – сравнение строк производится с использованием порядковых значений символов в строке. При этом лексикографический порядок может нарушиться, а условные обозначения, принятые в отдельной культурной среде, игнорируются. 2) CurrentCulture – сравнение строк производится с использованием текущих настроек параметров культурной среды. 3) CurrentCultureIgnoreCase – сравнение строк производится с ис-пользованием текущих настроек параметров культурной среды, но без учета регистра.

103

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

18. Метод Compare() Сравнение двух строк в лексикографическом (алфавитном) порядке.

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

Несмотря на большую универсальность метода Compare(), для простого порядкового сравнения символьных строк проще пользоваться методом CompareOrdinal().

19. Метод CompareTo() производит сравнение строк только с учетом культурной среды.

Пример string str1; string str2; int k = str1.CompareTo(str2); Сравнение строк str1 и str2: если k=0, строки равны, если k>0, str1>str2, если k<0, str1<str2

Равными считаются идентичные строки. При сравнении

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

7.2.3 Массив строк

Создание массива Способ 1: string [] strArr = null; strArr = new string[3];

104

strArr[0] = first; strArr[1] = second; strArr[2] = third;

Способ 2: применим более короткую инициализационную форму: string [] strArr = new string[3] {first, second, third};

Задача 7.11. Массив строк Программный код: using System; namespace C75 { class Program { static void Main(string[] args) { string[] strArr = new string[3] {"second", "first", "third"}; for (int i = 0; i <= (strArr.Length - 1); i++) Console.WriteLine(strArr[i]); Console.WriteLine("\n"); // отсортируем массив строк Array.Sort(strArr); for (int i = 0; i <= (strArr.Length - 1); i++) Console.WriteLine(strArr[i]); Console.ReadLine(); } } }

Результаты расчета см. рис. 7.11.

Рисунок 7.11 – Результаты решения задачи 7.11

105

Примечание. Если перед выводом содержимого массива строк отсортировать его методом Sort() класса Array, то вывод строк будет осуществлен в лексикографическом порядке.

7.3 Форматирование данных числовых типов

Для форматирования данных числовых типов в C# предусмотрен ряд методов: 1. Console.WriteLine(); 2. String.Format(); 3. ToString().

Форматирование осуществляется с помощью двух компонентов: спецификаторов формата и поставщиков формата.

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

Для того, чтобы отформатировать данные, достаточно включить спецификатор формата в метод, поддерживающий форматирование. Способ 1: с помощью метода Console.WriteLine()

Для форматирования выводимых данных служит следующая форма метода WriteLine()

WriteLine(форматирующая строка, arg0, arg1, …argN);)

В этой форме аргументы метода WriteLine() разделяются запятой, а не знаком +. А форматирующая строка состоит из двух следующих элементов: обычных печатаемых символов, отображаемых в исходном виде, а также команд форматирования. Общая форма команд форматирования: {argnum, width: frm},

где argnum – это номер отображаемого аргумента, начиная с нуля;

106

width – минимальная ширина поля; frm – спецификатор формата.

Параметры width и frm не являются обязательными. Поэтому в своей простейшей форме команда форматирования просто указывает конкретные аргументы для отображения. Например, команда {0} указывает аргумент arg0, команда {1} – аргумент arg1 и т.д.

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

Пример Double v=1723.56345; Console.WriteLine(v={0:F2},v);

Результат: v=1723.56

Таблица 7.2 – Спецификаторы формата числовых данных Специфи-

катор Формат Назначение спецификатора

точности 1 2 3

C или c Денежная единица Задает количество десятичных разрядов

D или d Целочисленный (используется только с целыми числами)

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

E или e Экспоненциальное представление чисел. В обозначении используется прописная буква E или строчная буква e . Непосредственно после спецификатора можно задать целое число, определяющее длину дробной части.

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

F или f Представление чисел с фиксированной точкой. Непосредственно после спецификатора можно задать целое число, определяющее длину дробной части.

Задает количество десятичных разрядов

107

Окончание таблицы 7.2 1 2 3

G или g Формат общего вида. Применяется для вывода значений с фиксированной точностью или в экспоненциальном формате в зависимости от того, какой формат требует меньшего количества позиций. По умолча-нию для типа single – 7 позиций.

см. спецификаторы E и F

N или n Представление чисел с фиксированной точкой (и запятой в качестве разделителя групп разрядов)

Задает количество десятичных разрядов

P или p Вывод числа в процентном формате Задает количество десятичных разрядов

R или r Отмена округления числа при преобразова-нии в строку.

Не используется

X или x Вывод значений в шестнадцатеричном формате.

Задает минимальное количество цифр

Способ 2: применение метода String.Format() для форматирования данных.

Иногда требуется сформировать строку, содержащую отформатированные данные, но не отображать ее сразу. Это дает возможность отформатировать данные заранее, чтобы вывести их в дальнейшем на выбранное устройство. Для этого имеется два способа, один – применение метода String.Format(), а другой – в передаче спецификатора формата методу ToString().

Пример 1 double v=17455.34267; string str=String.Format({0:F2},v); Console.WriteLine(str); Пример 2 string str=String.Format(Сумма:{0,3:D} Произведение:{1,8:D}, sum, prod); Способ 3: применение метода ToString() для форматирования данных. Здесь спецификатор формата передается методу ToString() непосредственно. Пример double v=17455.34267;

108

string str= v.ToString(F2); Console.WriteLine(str);

Определение пользовательского формата числовых данных

В C# предоставляется возможность определить пользовательский, т.е. свой собственный формат, используя средство, называемое форматом изображения. Когда пользователь определяет специальный формат, он задает этот формат в виде примера (или изображения) того, как должны выглядеть выводимые данные. Примеры Console.WriteLine({0:##.###}, a); Console.WriteLine(a={0,6:#.##} b={1,5:#.###}, a, b);

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

1. Для чего предназначен символьный тип данных в языке С#? 2. Что такое строка в языке С#? 3. Как прочитать определенный символ в строке? 4. Методы работы со строками. 5. Как осуществляется форматирование данных числовых типов?

109

ГЛАВА 8 КЛАССЫ, СТРУКТУРЫ, ПЕРЕЧИСЛЕНИЯ

8.1. Классы и объекты

Цель работы: Разобраться в основах объектно-ориентированного програм-

мирования.

Объектно-ориентированное программирование

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

Все программы на С# являются объектно-ориентированными. ООП основано на следующих свойствах: абстракция, инкапсуляция,

полиморфизм и наследование.

Классы, объекты

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

Абстракция

Абстракция – это придание объекту характеристик, которые отличают его от всех других объектов, четко определяя его

110

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

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

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

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

Инкапсуляция

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

Пользователь может взаимодействовать с объектом только через этот интерфейс. Реализуется с помощью ключевого слова: public.

Пользователь не может использовать закрытые данные и методы. Реализуется с помощью ключевых слов: private, protected, internal.

111

Таблица 8.1 Модификаторы доступа, указывающие уровень доступ-ности к членам класса Объявленная доступность Описание public Неограниченный доступ protected Доступ ограничен содержащим классом или

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

internal Доступ ограничен текущей сборкой protectedinternal Доступ ограничен текущей сборкой или типами,

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

private Доступ ограничен содержащим типом Инкапсуляция объединяет в классе описывающие этот объект поля

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

Полиморфизм

Полиморфизм (греч., множество форм) – возможность объектов с

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

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

внешняя общность проявляется как одинаковый набор методов с одинаковыми именами и сигнатурами (именем методов и типами аргументов и их количеством);

112

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

Примером полиморфизма может быть наличие у классов, описывающих графические объекты методов Show(), Hide(), Move() для соответственно отображения, скрытия и перемещения объекта. Объекты точки, прямоугольника и эллипса отрисовываются по-разному, но пользователю понятна запись Ellipse1.Show(), Point1.Show() и т.д. (показать эллипс, показать точку).

Наследование

Наследование – механизм ООП, позволяющий описать новый класс

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

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

Оператор new

Перед обращением к объекту, его нужно создвть, т.к. класс – всего

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

113

Поля и методы, имеющие модификатор static, создаются автоматически при старте программы и описывают статический член, принадлежащий всему типу, а не конкретному объекту. Модификатор static можно использовать с классами, полями, методами, свойствами, операторами, событиями и конструкторами, но нельзя – с индексаторами, деструкторами или типами, отличными от классов. К статическим методам относится метод Main(), который может быть только в одном классе, и с которого начинается программа.

Конструкторы

При создании объекта, обычно сразу заполняют его поля

(присваивают значение), но при большом количестве полей некоторые из них можно пропустить. Такой прием, хотя и не запрещен, не применяют в профессиональном программировании. Для инициализации объектов применяют так называемые конструкторы – код, похожий на методы. У них отсутствует указанный явно возвращаемый тип, и их имя совпадает с именем класса. Кроме присвоения начальных значений полям объекта, конструкторы могут выполнять другие действия для формирования полноценного объекта. В классе могут присутствовать несколько конструкторов, различающихся количеством параметров. В случае отсутствия конструкторов, С# добавляет конструктор по умолчанию, который инициализирует все переменные объекта в значения по умолчанию (числа – в ноль, строки и другие ссылочные типы – в null, логические – false). После определения собственного конструктора, конструктор по умолчанию не используется. Также конструкторами по умолчанию называют явно заданные конструкторы, у которых отсутствуют параметры. У конструктора практически всегда указывается модификатор public для обеспечения доступа к конструктору извне класса. Закрытие (private) конструкторы используется для явного обозначения невозможности создания экземпляра данного класса при отсутствии у класса полей или методов. Статический (static) конструктор используется для инициализации статических данных или выполнения определенного действия, которое необходимо выполнить только один раз, он вызывается автоматически (его нельзя вызвать явно) перед созданием первого

114

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

Задача 8.1 Рассмотрим пример, иллюстрирующий применение объектов (небольшие методы и конструкторы для экономии места записаны в одну строку).

Текст программы: using System; namespace C137 { class Obj1 { public double x, y; public Obj1() : this(0.0, 0.0) { } public Obj1(double X, double Y) { x = X; y = Y; } public Obj1(Obj1 Copy) : this(Copy.x, Copy.y) { } public double Sum() { return x + y; } public double Op() { return Sum() + 1; } } class Obj2 : Obj1 { public Obj2() : base() { } public Obj2(double X, double Y) : base(X, Y) { } public Obj2(Obj2 Copy) : base(Copy) { } new public double Op() { return Sum() + 2; } } class Program { static void Main(string[] args) { Obj1 A1 = new Obj1(); A1.x = 1; A1.y = 2; Obj2 A2 = new Obj2(3, 4); Obj1 A3; Console.WriteLine("Obj1: " + A1.Sum() + " " + A1.Op() + "\nObj2: " + A2.Sum() + " " + A2.Op());

115

A3 = A1; Console.WriteLine("1: " + A3.x + " " + A3.y); A3 = A2; Console.WriteLine("2: " + A3.x + " " + A3.y); A3 = new Obj2(A2); Console.WriteLine("3: " + A3.x + " " + A3.y); Console.ReadLine(); } } }

Результаты расчета см. рис.8.1.

Рисунок 8.1

Пространство имен С137 содержит три класса: Obj1, Obj2 и

Program. Класс Program содержит один статический метод Main(), которому передается управление при запуске программы. Класс Obj1 содержит два вещественных поля данных (x и y), доступных извне класса, т.к. они описаны модификатором public. Ниже описаны три перегружаемых конструктора с различным количеством параметров. Первый, без параметров – конструктор по умолчанию, инициализирует все поля в нули, вызывая конструктор с двумя параметрами. Вызов производится с помощью служебного слова this(), обозначающего текущий класс, и соответственно конструктор класса. После вызова перегружаемого конструктора указываются пустые фигурные скобки, в которых может быть расположен код, выполняемый после кода вызванного конструктора (метода). Второй конструктор – с перечнем переменных в качестве параметров, значения которых присваиваются полям. Третий конструктор – с параметром такого же объекта, что позволяет копировать все значения указанного объекта для получения копии в текущем объекте, получаемые объекты идентичны в момент создания нового объекта, но могут различаться в процессе работы. Также содержаться общие (public) методы

116

Sum() и Op(). Первый возвращает сумму x и y, второй – добавляет к сумме единицу.

Второй класс Obj2 наследуется от класса Obj1, поэтому Obj2 содержит те же поля и методы, что и Obj1. Т.к. конструкторы не наследуются, они описаны явно, но использование ключевого слова base позволяет обратиться к коду родительского объекта с соответствующими параметрами, поэтому сам код конструкторов отсутствует. Для демонстрации в классе Obj2 наследуемый метод класса Obj1 Op() был скрыт модификатором new и переписан с новым кодом (вместо единицы добавляет двойку).

При запуске программы выполняется код статического метода Main(), в котором объявляется ссылочная переменная А1 типа Obj1 и присваивается ей ссылка на созданный в памяти оператором new экземпляр объекта (по шаблону класса Obj1). При создании объекта используется конструктор по умолчанию, обнуляющий значения полей. Затем полям экземпляра объекта А1 присваиваются значения. Имена полей (как и любых других членов) соединяются с именами содержащих их объектов точкой. Такая запись присвоения полям значений допустима, но не приветствуется, т.к. менее понятна, громоздка и прямое обращение к полям может привести к ошибкам.

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

Ссылочная переменная А3 класса Obj1 только описывается, но ей не присваивается никакого значения.

Далее оператором WriteLine выводятся результаты работы методов объектов (для второго объекта результат выводится с новой строки "\n").

Заметьте, что у А2 наследуемый от Obj1 метод Sum() производит вычисления со «своими» данными, как и метод Op().

Далее демонстрируется присвоение ссылки на объекты. Переменной А3 присваивается ссылка на объект, хранящаяся в А1, и выводится значение полей первого объекта. При этом А1 и А3 ссылаются на один и тот же объект. Затем переменной А3 присваивается ссылка на второй объект, хранящаяся в А2 и соответственно выводятся значения полей

117

второго объекта. Соответственно ссылки А2 и А3 ссылаются на один и тот же объект.

И в конце програмы переменной А3 присваивается ссылка на создаваемый новый экземпляр объекта класса Obj2.

Задача 8.2 Тело бросили под углом к горизонту со скоростью 0v .

Найти время движения t, дальность полета L, максимальную высоту подъема h, скорость тела в момент падения kv .

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

02 sinvtg

Время движения

01

sinvtg

Время подъема

2 20 sin

2vh

g

Высота подъема

20 sin 2vL

g

Дальность полета

0kv v Скорость тела в момент падения

Текст программы: using System; namespace C138 { class Obj { public double v0, vk, L, t, t1, h, alfa; public const double g = 9.8; public Obj(double a, double v) { alfa = a * Math.PI / 180; v0 = v; vk = v0; t1 = Time1(); t = Time(); L = Length(); h = Height(); }

118

public double Length() { return v0 * v0 * Math.Sin(2 * alfa) / g; } public double Height() { return v0 * v0 * Math.Pow(Math.Sin(alfa), 2.0) / 2.0 / g; } public double Time1() { return v0 * Math.Sin(alfa) / g; } public double Time() { return Time1() * 2; } } class Program { static void Result(int n, Obj R) { String Format = "A{0} пролетел {1:#.##} м " + "за {2:#.##} с, поднявшись на {3:#.##} м "+ "(v0={4:#.##}, a={5:#.##})"; Console.WriteLine(Format,n,R.L,R.t,R.h,R.v0,R.alfa); } static void Main(string[] args) { Obj A1=new Obj(45.0, 15.0); Obj A2=new Obj(15.0, 45.0); Result(1,A1); Result(2,A2); Console.ReadLine(); } } }

119

Результаты расчета см. рис.8.2.

Рисунок 8.2

Задачи для самостоятельной работы

Задача 1 Объект сфера Написать программу с классом, описывающим сферу. В качестве

параметров конструктора передать радиус и плотность вещества сферы. С помощью методов класса вычислить и из Main() вывести на экран поля, содержащие объем сферы и её массу.

Задача 2 Объект труба Написать программу с классом, описывающим цилиндрическую

трубу. Ввести с клавиатуры и в качестве параметров конструктора передать радиус, толщину стенки, длину трубы. Материалом трубы принять железо, плотность задать константой 37870кг м . С помощью методов класса вычислить и из Main() вывести на экран поля, содержащие внутренний объем трубы и её массу.

8.2. Структуры

Помимо простых типов в языке C# определены ещё две категории

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

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

Структуры объявляются с помощью ключевого слова struct. Объявление структуры (структурного типа) имеет следующий формат:

[спецификаторы] struct имя_структуры [:интерфейсы] тело структуры

где struct – служебное слово;

120

имя_структуры – конкретное имя структуры; спецификаторы – спецификаторы доступа, определяют статус доступа структурного типа.

Из модификаторов доступа допускаются только: public – полная доступность; internal – доступность только внутри содержащей сборки, это стандартная доступность для невложенных типов; private – доступность только внутри содержащего типа. Это стандартная доступность для членов класса или структуры (только для вложенных структур).

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

Довольно часто структуры применяют без методов для хранения данных, аналогично записям в других языках программирования. Запись – именованный набор разнотипных данных, называемых полями, доступ к которым осуществляется по имени поля, отделённого от имени переменной (экземпляра) структуры точкой. Удобство использования записей (структур) обусловлено тем, что такой набор данных соответствует полям заполняемых бланков и является строкой таблицы при использовании в базах данных. Для использования доступа к полям снаружи структуры, члены структуры необходимо описывать с модификатором доступа public.

Структура может быть инициализирована с помощью оператора new для вызова конструктора или же путём простого объявления объекта. Так, если используется оператор new, то поля структуры инициализируются конструктором, вызываемым по умолчанию (в этом случае во всех полях устанавливается задаваемое по умолчанию значение), или же конструктором, определяемым пользователем. А если оператор new не ис-пользуется, то объект структуры не инициализируется, а его поля должны быть установлены вручную перед тем, как пользоваться данным объектом.

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

121

Задача 8.3. Программа демонстрирует применение структуры для хранения информации о книге. Программный код: using System; namespace C115 { // Определить структуру struct Book { public string Author; public string Title; public int Copyright; public int stran; public Book(string a, string t, int c, int s) { Author = a; Title = t; Copyright = c; stran = s; } } // Применение структуры class Program { static void Main(string[] args) { // Создаётся массив структур Book[] X = new Book[30]; X[0].Author = "Павловская Т.А."; X[0].Title = "C#. Программирование на языке высокого уровня"; X[0].Copyright = 2013; X[0].stran=430; X[1] = new Book("Герберт Шилдт", "Полный справочник по C# 4.0", 2010, 900); X[2]= new Book("Лукин С.Н.", "Понятно о Visual Basic.Net. Самоучитель. В трёх томах", 2005, 800); X[3] = new Book("Гусева О.Л.", "Практикум по Visual Basic", 2007, 544); for (int i = 0; i <= 3; i++) Console.WriteLine(X[i].Author + " " + X[i].Title + " "

122

+ X[i].Copyright + "г " + X[i].stran + "с"); Console.ReadLine(); } } }

Результаты расчета см. рис.8.3.

Рисунок 8.3 – Результаты решения задачи 8.3

8.3. Перечисления

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

Формат записи: enum имя {список_перечисления};

где имя – имя типа перечисления, список_перечисления – список идентификаторов, разделяемых

запятыми.

Пример Объявляется перечисление Apple различных сортов яблок: enum Apple { Jonathan, GoldenDel, RedDel, Winesap, Cortland, McIntosh };

Каждая символически обозначаемая константа в перечислении имеет целое значение. Тем не менее неявное преобразование перечислимого типа во встроенные целочисленные типы и обратно в C# не определены, а значит, в подобных случаях требуется явное приведение типов. Но поскольку перечисления обозначают целые значения, то их можно, например, использовать для управления оператором выбора switch или же оператором цикла for.

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

123

предыдущей константы. По умолчанию значение первой символически обозначаемой константы в перечислении равно нулю. Следовательно, в приведенням выше примере перечислення Apple константа Jonathan равна нулю, константа GoldenDel – 1, константа RedDel – 2 и т.д.

Доступ к членам перечисления осуществляется по имени их типа, после которого следует оператор-точка. Например, при выполнении фрагмента кода

Console.WriteLine(Apple.RedDel + "имеет значение" + (int)Apple.RedDel);

Выводится следующий результат: RedDel имеет значение 2

Задача 8.4. Демонстрирует применение перечисления Apple

Программный код: using System; namespace C136 { class Program { enum Apple { Jonathan, GoldenDel, RedDel, Winesap, Cortland, McIntosh }; static void Main(string[] args) { string[] color = { "красный", "желтый", "красный", "красный", "красный", "красновато-зеленый" }; Apple i; //объявить переменную перечислимого типа // Использовать переменную i для циклического // обращения к членам перечисления for (i = Apple.Jonathan; i <= Apple.McIntosh; i++) Console.WriteLine(i + " имеет значение " + (int)i); Console.WriteLine(); // Использовать перечисление для индексирования массива for (i = Apple.Jonathan; i <= Apple.McIntosh; i++) Console.WriteLine("цвет сорта " + i + "-" + color[(int)i]); Console.ReadLine(); } } }

124

Результаты расчета см. рис.8.4.

Рисунок 8.4 – Результаты решения задачи 8.4

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

1. Что такое класс? 2. Что такое объект? 3. Какими свойствами обладает ООП? 4. Для чего используются конструкторы? 5. Какой модификатор позволяет обращаться к членам извне класса? 6. Что такое перегружаемые методы? 7. Что такое скрытие метода и как оно реализуется? 8. Что такое структуры? 9. Что такое перечисления? 10. Приведите примеры перечислений. 11. Приведите примеры структур.

125

ГЛАВА 9 ФАЙЛЫ

Как известно, для долговременного хранения данных в компьютерах

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

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

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

При работе с файлами необходимо подключить пространство имен, в котором описываются стандартные классы для работы с файлами: using System.IO.

Выполнять обмен с внешними устройствами можно на уровне: двоичного представления данных (классы BinaryReader,

BinaryWriter); байтов (класс FileStream); текста, то есть символов (классы StreamWriter, StreamReader). В .NET используется кодировка Unicode, в которой каждый символ

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

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

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

Для того чтобы использовать в программе файлы, необходимо:

126

1. Подключить пространство имен, в котором описываются стандартные классы для работы с файлами (using System.IO).

2. Создать файловый поток и связать его с физическим файлом. 3. Произвести операции обмена (ввод-вывод). 4. Закрыть файл

Открытие и закрытие файла Для того, чтобы начать работать с файлом, нужно открыть

файловый поток, создав для этого объект библиотечного класса FileStrem (определен в пространстве имен System.IO, поэтому в самом начале программы вводится строка using System.IO;). FileStream("FileName", FileMode режим, FileAccess доступ) где "FileName" обозначает имя открываемого файла, включая и полный путь к нему; режим – порядок открытия файла

(FileMode.Open– открывает существующий файл, FileMode.Create – создает новый выходной файл. Существующий файл с таким же именем будет разрушен)

доступ – обозначает конкретный способ доступа к файлу (FileAccess.Read, FileAccess.Write, FileAccess.ReadWrite)

Пример FileStream fs = new FileStream("file1.dat", FileMode.Open, FileAccess.Read); открывается существующий файл для чтения

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

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

Close(): fs.Close();

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

127

правило – проверять факт существования файла перед созданием объекта типа FileStream с помощью статического метода Exists() библиотечного класса File: if (File.Exists (FileName)) { …// здесь и создаем объект типа FileStream }

Если файл с указанным именем не существует, а мы попытаемся открыть его на чтение, то результат будет отрицательным (в смысле возврата логического значения false методом Exists() класса File).

В то же время, попытка открыть файл на запись (в режимах FileMode.Create и FileAccess.Write) всегда будет успешной: при существующем файле его прежнее содержимое аннулируется, а при несуществующем файле он автоматически создается.

Пример FileStream fs = new FileStream("file1.dat", FileMode.Create, FileAccess.Write);

Мы открываем на запись файл с именем file1.dat, которого ранее не существовало.

Если при открытии файла путь к файлу не указан, то файл данных ищется или создается в том же каталоге, где находится исполняемый файл программы: D:\ ProgramVS\ C95\ C95\ bin\ Debug\ file1.dat

При записи в тексте программы пути к файлу следует помнить, что символ \ в строковых константах обозначает начало специальной последовательности символов, например, \n. Поэтому при записи имени файла символ \ следует продублировать, например d:\\C#\\input.txt

9.1 Файловое хранение числовых данных

Для чтения / записи числовых данных типа int или double лучше создать объекты классов BinaryWriter и BinaryReader, чьи методы Write() (перегружен для разных типов данных), ReadInt32() и ReadDouble() как нельзя лучше подходят для этой задачи.

Проиллюстрируем работу методов Write(), ReadInt32() (для

128

чтения целых чисел типа int) и ReadDouble()(для чтения вещественных чисел типа double) на примере следующей программы.

Задача 9.1. Иллюстрация работы методов Write(), ReadInt32() (для чтения целых чисел типа int) и ReadDouble() (для чтения вещественных чисел типа double). Программный код: using System; using System.IO; namespace C95 { class Program { static void Main(string[] args) { int m = 5; double d = 8.34; int iRes = 0; double dRes = 0; // Запись в файл FileStream fsW = new FileStream("file1", FileMode.Create, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fsW); bw.Write(m); bw.Write(d); bw.Close(); fsW.Close(); // Чтение файла if (File.Exists("file1")) { FileStream fsr = new FileStream("file1", FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fsr); iRes = br.ReadInt32(); dRes = br.ReadDouble(); br.Close(); fsr.Close(); } Console.WriteLine("iRes i= {0}; dRes = {1}", iRes, dRes);

129

Console.ReadLine(); } } }

Результаты расчета см. рис. 9.1.

Рисунок 9.1 – Результаты решения задачи 9.1

В этой программе файл с именем file1 сначала открывается на запись, в результате чего объектная ссылка fsW типа FileStream получает актуальное значение. Поверх этой ссылки строится объект bw класса BinaryWriter: BinaryWriter bw = new BinaryWriter(fsW);

С помощью перегруженного метода Write() класса BinaryWriter в открытый файл последовательно записываются значения переменных m и d. Затем пишущий объект и файл закрываются одноименными методами Close().

После этого файл снова открывается, но уже на чтение. Содержимое файла file1 вычитывается от имени объекта br типа BinaryReader методами ReadInt32() и ReadDouble() в переменные iRes и dRes, соответственно: iRes = br.ReadInt32(); dRes = br.ReadDouble();

Для проверки результата значения переменных iRes и dRes выводятся в консольное окно программы с помощью статического метода WriteLine библиотечного класса Console.

Задача 9.2. Запись в файл и чтение из файла массивов Программный код: using System; using System.IO; namespace C96 {

130

class Program { static void Main(string[] args) { int[] iArr = {1,5,7,10,12 }; double[] dArr = {1.34, 3.56, 5.12, 7.45, 9.17}; int[] iArrRes = new int[5]; double[] dArrRes = new double[5]; int i; // Запись в файл FileStream fsW = new FileStream("file2", FileMode.Create, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fsW); for (i = 0; i <= (iArr.Length - 1); i++) bw.Write(iArr[i]); for (i = 0; i <= (dArr.Length - 1); i++) bw.Write(dArr[i]); bw.Close(); fsW.Close(); // Чтение файла if (File.Exists("file2")) { FileStream fsR = new FileStream("file2", FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fsR); for (i = 0; i <= (iArrRes.Length - 1); i++) iArrRes[i] = br.ReadInt32(); for (i = 0; i <= (dArrRes.Length - 1); i++) dArrRes[i] = br.ReadDouble(); br.Close(); fsR.Close(); } for (i = 0; i <= (iArrRes.Length - 1); i++) Console.WriteLine("iArrRes[{0}]={1};" + "\tdArrRes[{0}]={2}", i, iArrRes[i], dArrRes[i]); Console.ReadLine(); } } }

Результаты расчета см. рис. 9.2.

131

Рисунок 9.2 – Результаты решения задачи 9.2

Здесь числовые массивы iArr и dArr циклически поэлементно

записываются в файл file2. После закрытия файла и его повторного открытия для чтения содержимое файла file2 последовательно вычитывается в массивы - приемники iArrRes и dArrRes.

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

Задача 9.3.

Программный код: using System; using System.IO; namespace C97 { class Program { static void Main(string[] args) { int[] iArr = { 1, 5, 7, 10, 12 }; int[] iArrRes = new int[8]; int i; // Запись в файл FileStream fsW = new FileStream("file3", FileMode.Create, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fsW); for (i = 0; i <= (iArr.Length - 1); i++) bw.Write(iArr[i]); bw.Close(); fsW.Close(); // Чтение файла

132

if (File.Exists("file3")) { FileStream fsR = new FileStream("file3", FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fsR); i = 0; while (br.PeekChar() != -1 && i < 8) { iArrRes[i] = br.ReadInt32(); i++; } br.Close(); fsR.Close(); } for (i = 0; i <= (iArrRes.Length - 1); i++) Console.WriteLine("iArrRes[{0}]={1}" , i, iArrRes[i]); Console.ReadLine(); } } }

Результаты расчета см. рис. 9.3.

Рисунок 9.3 – Результаты решения задачи 9.3

В данной программе мы сначала записываем в файл file3

содержимое массива iArr из пяти элементов типа int. Затем файл закрывается и снова открывается на чтение. Но прежде чем читать из файла методом ReadInt32() очередное целое значение, контролируем наличие невычитанных из файла данных методом PeekChar().

Пока метод PeekChar() возвращает не равные –1 значения, в файле file3 еще имеются невычитанные данные, которые мы и продолжаем циклически вычитывать методом ReadInt32(). Как только при очередной

133

попытке чтения метод PeekChar() вернет –1, то условие цикла станет ложным и он перестанет выполняться (другое условие i<8 дополнительно страхует от переполнения принимающего буфера iArrRes).

В принимающий массив iArrRes, размер которого достаточен для приема восьми целых чисел, из файла file3 было прочитано пять целых значений.

9.2 Файловое хранение текстовых данных

Текстовые файлы состоят из строк разной длины, отделенных друг от друга двумя специальными символами – возврат каретки и перевод строки. Это файлы последовательного доступа. Мы можем сохранить любой свой документ, созданный в редакторе Microsoft Word, в виде текстового файла. Для этого в Microsoft Word надо выбрать команду

Файл→Сохранить как, а в списке Тип файла выбрать пункт обычный текст (*.txt). При попытке сохранить документ в виде текстового файла на экране появится предупреждение, что при этом любое форматирование документа пропадет (выберите Да, чтобы все- таки сохранить документ в виде текста). После этого сохраненный документ можно открыть в редакторе C#. Для этого

1. Выберите команду Файл→Открыть файл 2. В списке Объекты типа выбрать Текстовые файлы (*.txt). 3. Выделив нужный файл, нажмите кнопку Открыть. С текстовыми файлами лучше работать с помощью пишущих и

читающих объектов специализированных классов StreamWriter и StreamReader.

Задача 9.4. Создан текстовый файл:

Киев Харьков Одесса

Прочитать содержимое текстового файла.

Создадим файл с помощью простейшего текстового редактора Notepad (Блокнот). Файл назовем "file5.txt". Так как информацион-ная система содержит символы русского алфавита, то файл "file5.txt" нужно сохранять в кодировке UTR–8.

134

Программный код: using System; using System.IO;

namespace C98 { class Program { static void Main(string[] args) { string Str; // Чтение файла if (File.Exists("file5.txt")) { FileStream fsR = new FileStream("file5.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fsR); while ((Str = sr.ReadLine()) != null) Console.WriteLine("Str= {0}", Str); sr.Close(); fsR.Close(); } Console.ReadLine(); } } }

Результаты расчета см. рис. 9.4.

Рисунок 9.4 – Результаты решения задачи 9.4

Программа за один вызов метода ReadLine() читает по одной физической строке. Условие полной вычитки текстового файла – возврат методом ReadLine() значения null.

135

Задача 9.5. Текстовые файлы

Программный код: using System; using System.IO;

namespace C99 { class Program { static void Main(string[] args) { string str1 = "Текстовый"; string str2 = "редактор"; // Запись в файл FileStream fsW = new FileStream("file6", FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fsW); sw.WriteLine(str1); sw.WriteLine(str2); sw.Close(); fsW.Close(); // Чтение из файла FileStream fsR = new FileStream("file6", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fsR); str1 = sr.ReadLine(); str2 = sr.ReadLine(); sr.Close(); fsR.Close(); Console.WriteLine("str1= {0}\nstr2= {1}\n", str1, str2); Console.ReadLine(); } } }

Результаты расчета см. рис. 9.5.

Рисунок 9.5 – Результаты решения задачи 9.5

136

Задача 9.6. Создать простейшую информационную систему – телефонная книга.

Создадим записи телефонной книги с помощью простейшего тексто-вого редактора Notepad (Блокнот).

В одной физической строке текста будем располагать фамилию абонента и его телефон. Отделять фамилию и номер телефона друг от друга будем одним (или двумя) знаками табуляции. Файл назовем "file8.txt".

Т.к. информационная система содержит символы русского алфавита, то файл "file8.txt" нужно сохранять в кодировке UTR–8.

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

На запрос имени абонента мы вводим фамилию, например, павловская и нажимаем клавишу Enter, после чего на дисплее появляется строка из файла "file8.txt", содержащая заданную фамилию и соответствующий номер телефона.

С помощью метода IndexOf() библиотечного класса String мы выявляем потенциальное вхождение заданной фамилии в текущую строку, прочитанную только что из файла "file8.txt" методом Readine(). Если возврат этого метода не равен минус единице, то искомая фамилия в прочитанной строке найдена.

Программный код: using System; using System.IO; namespace C100 { class Program { static void Main(string[] args) { string Name, str; int ind; Console.Write("Введите фамилию: "); Name = Console.ReadLine(); // Чтение файла

137

if (File.Exists("file8.txt")) { FileStream fsR = new FileStream("file8.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fsR); while ((str = sr.ReadLine()) != null) { ind = str.IndexOf(Name, 0); if (ind != -1) { Console.WriteLine("---------------------"); Console.WriteLine("{0}", str); } } sr.Close(); fsR.Close(); } Console.WriteLine("----------------------\n"); Console.WriteLine("Конец"); Console.ReadLine(); } } }

Результаты расчета см. рис. 9.6.

Рисунок 9.6 – Результаты решения задачи 9.6

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

1. Для чего используются файлы? 2. Как осуществляется файловое хранение числовых данных. 3. Как осуществляется файловое хранение текстовых данных.

138

ГЛАВА 10 ЛАБОРАТОРНЫЙ ПРАКТИКУМ

10.1 Составление программ линейной структуры

Цель работы: для консольного приложения: изучить операторы объявления и инициализации переменных и констант; операторы присваивания, комментарии; методы ввода/ вывода: Console.Write(), Console.WriteLine(), Console.Read(), Console.ReadLine()

для Windows-приложения: изучить элементы управления: метка Label, кнопка Button, поле ввода TextBox.

10.1.1 Примеры создания проектов

Задача 10.1. Вычислить значения выражений.

22 ;

sin ( )cos( )a

ay btg xx a

d ae bx a

при a = 3,2; b = 17,5; x = –4,8 Способ 1. Создать консольное приложение (под консолью обычно

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

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

Блок-схема решения задачи представлена на рис. 10.1. Иногда для научных расчетов требуется организовать самый простой

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

Для создания консольного приложения необходимо: 1. Загрузить систему Microsoft Visual Studio 2012.

139

Пуск /Программы /Программирование /Microsoft Visual Studio 2012 / ∞ Microsoft Visual Studio 2012

Загрузить систему можно также при помощи ярлыка на панели быстрого запуска.

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

Начальный пользовательский интерфейс представлен на рис. 10.2.

cos( )ad ae bx a

22sin ( )ay btg xx a

3,217,5

4,8

abx

Рисунок 10.1 – Блок-схема алгоритма к задаче 10.1 (способ 1,2)

140

Рисунок 10.2 – Начальный пользовательский интерфейс Visual C# 2012 2. Создать новый проект. Вызвать команду Создать проект, которая располагается слева

начальной страницы. В окне Создать проект (рис. 10.3) в левой колонке находится список

инсталлированных шаблонов (Installed Templates). Среди них – шаблоны языков программирования, встроенных в Visual Studio, в т.ч. Visual Basic, Visual C#, Visual C++ и др. Нам нужен язык Visual C#. Над центральной панелью должна быть выбрана версия .NET Framework 4.5.

В центральном списке шаблонов выберите проект Консольное приложение Visual C#. В поле Имя снизу введите C1.

Имя: C1 По умолчанию система задает имя ConsoleApplication1и путь, куда

будет записан проект. В Visual Studio можно задать путь по умолчанию для сохранения проектов командой Сервис/ Параметры, затем в разделе Проекты и решения/ Общие, поле Размещение проектов указать путь назначения. Внесите в поле путь D:\ProgramVS. В папке проектов при создании проекта создается соответствующая структура папок, содержащая компоненты проекта. После нажатия клавиши OK попадаем сразу на вкладку программного кода. В окне редактора появится сгенерированный автоматически каркас программы (рис.10.4).

141

Рисунок 10.3 – Окно Создать проект

Рисунок 10.4 – Вкладка программного кода

142

После строки static void Main() начинаем вводить программный код. Программный код : using System; // Подключение стандартных библиотек using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace С1 { class Program { static void Main(string[] args) { // Программа 1 const double a = 3.2, b = 17.5, x = -4.8; double y, d; y = b * Math.Pow(Math.Tan(x),2) - a/Math.Pow(Math.Sin(x/a),2); d = a * Math.Exp(-Math.Sqrt(a)) * Math.Cos(b * x / a); Console.WriteLine("y={0,9:F3}; d={1,8:F4}", y, d); Console.WriteLine("Нажмите Enter для выхода"); Console.ReadLine(); // Задержка консольного окна на дисплее } } }

3. Вызовите контекстное меню редактора, нажав правой кнопкой мыши на пустом месте в окне редактирования кода. Выполните команду Управление директивами using/Удалить неиспользуемые директивы using. Ниже представлена программа после выполнения команды.

Программный код : using System; //Подключение стандартных библиотек namespace С1 { class Program { static void Main(string[] args) { // Программа 1 const double a = 3.2, b = 17.5, x = -4.8;

143

double y, d; y = b * Math.Pow(Math.Tan(x), 2)- a/Math.Pow(Math.Sin(x/a),2); d = a * Math.Exp(-Math.Sqrt(a)) * Math.Cos(b * x / a); Console.WriteLine("y={0,9:F3}; d={1,8:F4}", y, d); Console.WriteLine("Нажмите Enter для выхода"); Console.ReadLine(); } } }

4. Запустить программу командой Отладка/ Начать отладку (F5).

Результаты расчета см. рис. 10.5

Рисунок 10.5 – Результаты решения задачи 10.1 5. Отладка / Остановить отладку 6. Сохранить проект

Файл / Сохранить всё Система сохранит ваш проект D:\ ProgramVS \C1\ C1.sln Откомпилированная программа находится в папке D:\ ProgramVS \C1\ C1\ bin\ Debug\ C1.exe

Пояснение к программе: 1) using System;

Приложение начинается с директив использования пространств имён библиотеки .NET. Строка using System; означает, что в программе используется пространство имён System. В C# пространство имён определяет область объявлений. Мы вынуждены использовать пространства имен тех библиотек, средства которых применяются в наших программах. Пространство имён System объединяет те классы из библиотеки классов среды .NET Framework, которые наиболее часто используются в консольных программах на C#.

144

Применение в программе библиотеки классов предполагает либо создание объектов классов этой библиотеки, либо обращения к статическим полям и методам библиотечных классов. Из пространства имён System в нашей программе используется класс Console и два статических метода этого класса WriteLine() и ReadLine(). Поместив в программу оператор using System, можно обращаться к названным методам с помощью сокращённых составных имён Console.WriteLine() и Console.ReadLine(). Если эту строку не писать, то тогда при записи в программе, например метода Console.WriteLine() надо будет указывать пространство имён, к которому этот метод принадлежит, т.е. System.Console.WriteLine(). Указывать пространство имён System всякий раз, когда используется член этого пространства, – утомительное занятие, и поэтому большинство программистов на C# вводят директиву using System в начале своих программ.

2) namespace С1 Это объявление вводит для программы собственное пространство

имён с обозначением С1. Это имя мы определили при создании проекта. Программа содержит созданный автоматически класс (Program), а в составе этого класса – метод Main().

3) class Program В соответствии с объектной ориентацией языка C# всякая программа

на языке C# представляет собой класс или совокупность классов. В нашей программе ключевым словом class объявляется класс с именем Program. Имя класса можно выбирать произвольно. Далее в фигурных скобках – тело класса. В классе Program только один метод с заголовком static void Main().

4) static void Main() Это статический метод со специальным именем Main. Этот метод

определяет точку входа в программу – именно с выполнения операторов метода Main() начинается исполнение её кода. Обычно программа состоит не из одного метода, но Main (главный) присутствует всегда.

Ключевое слово void указывает на то, что метод Main() не возвращает значение. Пустые круглые скобки после имени метода Main

145

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

5) Размещение операторов на строках Программа состоит из операторов. Операторы заканчиваются точкой

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

6) // Программа 1 Это однострочный комментарий, начинается с символов //, область

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

Многострочные комментарии ограничиваются символами /* */. Пример записи многострочного комментария /* Программа для работы с файлами последовательного доступа */

7) const double a = 3.2, b = 17.5, x = -4.8; Объявление именованных констант типа double – вещественные

двойной точности.

8) double y, d; Объявляются две переменные y и d – вещественные (дробные) числа

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

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

146

9) y = b * Math.Pow(Math.Tan(x), 2) - a / Math.Pow(Math.Sin(x /a),2); Оператор присваивания. Математические функции C# являются

методами класса Math. Их можно увидеть, набрав Math и поставив (.). В выпадающем списке вы увидите множество математических функций: abs, sin, cos… и др. и две константы E=2,71 (основание натуральных логарифмов) и PI=3,14 (число диаметров, уложенных вдоль окружности). Результат вычисления математической функции – тип double, аргументы функций также должны быть типа double, например, sin(double x).

10) Console.WriteLine("y={0,9:F3}; d={1,8:F4}", y, d); Для выполнения операций вывода на консоль используются методы

Console.WriteLine() и Console.Write(). Оба метода выводят строку текста, но Console.Write оставляет курсор в позиции окончания строки вывода, а Console.WriteLine кроме этого добавляет операции перевода строки и возврата каретки, т.е. перемещает курсор в начало следующей строки. Метод Console.WriteLine() с пустым списком параметров добавляет пустую строку.

В данном примере в параметрах метода Console.WriteLine присутствует строка форматирования (шаблон), ограниченная символами <"> и две переменные, которые необходимо вывести – y и d. Так как нумерация начинается с нуля, то номера этих параметров 0 и 1 (0:y, 1:d).

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

Формат {0,9:F3} обозначает следующее: вывести значение параметра 0 (переменной y ), общая длина поля – 9 знаков, использовать формат с фиксированной запятой, с точностью три знака после запятой.

Часто применяется научный формат E, например, {0:E5} означает вывод 0 параметра в научном формате (Е), с точностью 5 знаков после запятой.

11) Console.WriteLine("Нажмите Enter для выхода"); На экран выводится сообщение «Нажмите Enter для выхода»

12) Console.ReadLine();

147

Используется для организации ожидания нажатия клавиши <Enter> после завершения консольной программы (при отладке, чтобы окно результатов не закрывалось сразу после завершения программы).

Два последних оператора используются для задержки консольного окна на дисплее.

Способ 2. Создадим консольное приложение. Исходные данные представлены как переменные, их значения

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

Программный код : using System;

namespace C2 { class Program { static void Main(string[] args) { // Программа 2 double a, b, x, y, d; a = 3.2; b = 17.5; x = -4.8; y = b * Math.Pow(Math.Tan(x), 2) - a/Math.Pow(Math.Sin(x/a),2); d = a * Math.Exp(-Math.Sqrt(a)) * Math.Cos(b * x / a); Console.WriteLine("y={0,9:F3}; d={1,8:F4}", y, d); Console.WriteLine("Нажмите Enter для выхода"); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.6

Рисунок 10.6 – Результаты решения задачи 10.1

148

Пояснение к программе: 1) a = 3.2; b = 17.5; x = -4.8;

Значения исходным данным задаем при помощи операторов присваивания. В коде программы при записи вещественных чисел десятичным разделителем является < . >, но при работе программы в операциях ввода/ вывода используется десятичный разделитель, указанный в настройках системы < , >.

Способ 3. Создать консольное приложение. Значения исходных данных вводятся с консоли (клавиатура),

результаты выводится на консоль (экран монитора). Блок-схема решения задачи представлена на рис. 10.7.

22sin ( )ay btg xx a

cos( )ad ae bx a

Рисунок 10.7 – Блок-схема алгоритма к задаче 10.1 (способ 3, 4)

149

Программный код : using System;

namespace C3 { class Program { static void Main(string[] args) { //Программа 3 double a, b, x, y, d; Console.WriteLine(" Введите a, b, x: "); a = Convert.ToDouble(Console.ReadLine()); b = Convert.ToDouble(Console.ReadLine()); x = Convert.ToDouble(Console.ReadLine()); Console.WriteLine(); y = b * Math.Pow(Math.Tan(x), 2) - a/Math.Pow(Math.Sin(x/a),2); d = a * Math.Exp(-Math.Sqrt(a)) * Math.Cos(b * x / a); Console.WriteLine("y={0,9:F3}; d={1,8:F4}", y, d); Console.WriteLine("Нажмите Enter для выхода"); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.8

Рисунок 10.8 – Результаты решения задачи 10.1 Пояснение к программе: 1) Console.WriteLine(" Введите a, b, x: ");

150

Метод выводит на консоль (экран) строку символов Введите a, b, x:

Курсор переводится на новую строку. 2) a = Convert.ToDouble(Console.ReadLine()); b = Convert.ToDouble(Console.ReadLine()); x = Convert.ToDouble(Console.ReadLine());

Операторы присваивания. Переменным a, b, x присвоить значение, вводимое с консоли (клавиатуры).

Пользователь в ответ на приглашение «Введите a, b, x:» вводит с клавиатуры числа: значения переменных, заканчивая ввод каждого числа нажатием клавиши Enter.

Метод Console.ReadLine() вводит строку символов. Функция Convert.ToDouble конвертирует (преобразует) текст в

числовой тип двойной точности. Когда в программе встречается оператор ReadLine() ее действие

приостанавливается до тех пор, пока не будет введено исходное данное. Способ 4. Создать Windows-приложение. Значения исходных данных

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

1. Загрузить систему Microsoft Visual Studio 2012. Пуск /Программы /Программирование /Microsoft Visual Studio 2012 / ∞ Microsoft Visual Studio 2012

Загрузить систему можно также при помощи ярлыка на панели быстрого запуска.

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

Начальный пользовательский интерфейс представлен на рис. 10.9.

151

Рисунок 10.9 – Начальный пользовательский интерфейс Visual C# 2012

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

начальной страницы. В окне Создать проект (рис. 10.10) в левой колонке находится

список инсталлированных шаблонов (Installed Templates). Среди них – шаблоны языков программирования, встроенных в Visual Studio, в т.ч. Visual Basic, Visual C#, Visual C++ и др. Нам нужен язык VisualC#.

Над центральной панелью должна быть выбрана версия .NET Framework 4. В средней колонке выберем шаблон (Templates) Приложение Windows Forms Visual C#.

Зададим имя: W1 →OK

При создании нового проекта среда сформирует шаблон Windows- приложения. В результате увидим окно, представленное на рис. 10.11. В этом окне изображена экранная форма – Form1, в которой программисты располагают различные компоненты графического интерфейса пользова-теля или, как их иначе называют, элементы управления. Это поля для ввода текста TextBox, командные кнопки Button, метки Label и др.

152

Рисунок 10.10 – Окно Создать проект

Рисунок 10.11 – Окно для проектирования пользовательского интерфейса

153

3. Проверить, чтобы были загружены панель элементов и панель свойств.

Вид / Панель элементов / Стандартные элементы управления Вид / Окно свойств

4. На форме Form1 создайте объекты, как показано на рис. 10.12, 10.13.

На форме расположить: четыре метки (Label), три текстовых поля (TextBox), две командных кнопки (Button).

Рисунок 10.12 – Форма к задаче 10.1

5. Установите значения свойств объектов в соответствии с табл. 10.1.

Таблица 10.1 – Значения свойств объектов к задаче 10.1 Объект Имя объекта по умолчанию

(значение свойства Name) Свойство Значение свойства

1 2 3 4 Форма Form1

Метка Label1 Text a= Метка Label2 Text b=

Метка Label3 Text x=

Метка Label4

154

Окончание таблицы 10.1 1 2 3

Выделить метки Label1-Label4 ( клавиша[Shift] +мышь) и установить одинаковые для всех меток свойства

TextAlign TopCenter Font Times New Roman, обычный, 12

Текстовое поле TextBox1 Name txta Text 3,2

Текстовое поле TextBox2 Name txtb Text 17,5

Текстовое поле TextBox3 Name txtx Text -4,8

Выделить текстовые поля TextBox1 – TextBox3 и установить одинаковые для всех полей свойства

TextAlign Center Font Times New Roman, обычный, 12

Командная кнопка

Button1 Name cmdStart Text Вычислить Font Times New Roman, жирный, 12

Командная кнопка

Button2 Name cmdEnd Text Завершение работы Font Times New Roman, жирный, 12

Рисунок 10.13 – Форма к задаче 10.1

Соглашение об именах объектов Иногда для повышения информативности используемых в проекте

объектов (элементов управления) программисты используют в именах префиксы, которые определяют их принадлежность к определенному классу. Формат имени объекта:

ПрефиксИмя,

155

где Имя – информативное с точки зрения функционального назначения имя объекта.

Ниже приведены примеры использования префиксов для задания имен объектов.

Префикс Элемент управления Пример txt TextBox (текстовое поле) txtA cmd Button (Командная кнопка) cmdStart pic PictureBox (Рисунок) picRis

6. Программирование. Прежде чем приступить к программированию, необходимо

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

Добавление обработчиков событий

Дважды щелкните на кнопке <Вычислить>. Это приведёт непосредственно к обработчику события элемента управления, используемому по умолчанию – для кнопки таким событием является событие Click, поэтому именно его обработчик создаётся. После двойного щелчка на кнопке <Вычислить> откроется Окно программного кода. В окне редактора появится созданный автоматически шаблон обработчика события: private void cmdStart_Click(object sender, EventArgs e) { }

В качестве имени метода присваивается имя элемента управления, за которым следует символ подчеркивания и имя обрабатываемого события – cmdStart_Click (рис. 10.14).

Заполним этот обработчик.

156

Рисунок 10.14 – Вкладка программного кода

Для написания метода cmdEnd_Click обработки события щелчок

мышью по командной кнопке <Завершение работы> дважды щелкните по кнопке <Завершение работы>. Откроется Окно программного кода с созданным автоматически шаблоном обработчика события. Заполним этот обработчик.

Программный код : using System; using System.Windows.Forms; namespace W1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { double a, b, x, y, d;

157

a = Convert.ToDouble(txta.Text); b = Convert.ToDouble(txtb.Text); x = Convert.ToDouble(txtx.Text); y = b*Math.Pow(Math.Tan(x), 2)-a/Math.Pow(Math.Sin(x/a), 2); d = a * Math.Exp(-Math.Sqrt(a)) * Math.Cos(b * x / a); label4.Text = "y= " + y.ToString("F3") + " d= " + d.ToString("F4"); } private void cmdEnd_Click(object sender, EventArgs e) { // Процедура закрытия формы Close(); } } }

7. Запустите программу на выполнение. Отладка/ Начать отладку Щелкните на кнопке <Вычислить> левой кнопкой мыши. Результаты

расчета см. рис. 10.15. 8. Щелкните на кнопке <Завершение работы> левой кнопкой мыши. 9. Сохраните проект Файл/ Сохранить всё Система сохранит ваш проект D:\ ProgramVS \W1\ W1.sln

Рисунок 10.15 – Результаты решения задачи 10.1

158

Пояснение к программе: 1) using System.Windows.Forms;

Пространство System.Windows.Forms содержит огромное количество типов, являющихся строительными блоками Windows- приложений. 2) a = Convert.ToDouble(txta.Text);

Оператор присваивания. Переменной a присвоить значение, вводимое в текстовое поле с именем txta. Visual C# считает содержимое текстового поля текстом, а не числом, если даже оно состоит из цифр. Следовательно, переменные, берущие свое значение из текстового поля, язык Visual C# тоже считает текстовыми, а не числовыми. Функция Convert.ToDouble конвертирует (преобразует) текст в числовое вещественное значение двойной точности (конвертирует строковую переменную txta.Text в число a). 3) label4.Text= "y= " + y.ToString("F3") + " d= " + d.ToString("F4");

Вывод данных в поле label4. Для вывода на метку используется свойство Text – надпись на метке. При выводе числа необходимо преобразовать его в последовательность символов, т.е. в строку. Для этого служит метод ToString().

Если вы хотите, чтобы вывод осуществлялся по формату, тогда в качестве параметра функции ToString() укажите символьную константу, которая задает формат строки-результата. Символьная константа "F3" означает формат F(Fixed) – число с фиксированной точкой, три знака после запятой.

Текст, заключенный в кавычки и не включенный в фигурные скобки, выводится как есть. Для последовательного вывода нескольких значений одним оператором в качестве разделителя списка используется знак < + > (операция конкатенация или сцепление строк). Обратите внимание, что в выражениях с арифметическими операндами знак <+> означает операцию сложения. Эта особенность операций по-разному выполняться для разных типов операндов называется полиморфизмом.

159

10.1.2 Задачи для выполнения лабораторных работ – часть 1

Таблица 10.2 – Варианты задач №

вар. Расчетные формулы Исходные данные

1 2 3

1 2

2

2

2cos( 6)1 2 sin

13 5

xay

zbz

1,4261,22

3,5

xyz

2

3

2( )1 ( )

y xx y x

y zy x

y x

1,82518,225

3,298

xyz

3

2

sin( )

sin( cos2 ) 1

bty e at b bt a

s b at t

0,51,70,44

abt

4 2 2 3

2 3 2 2

sin ( )

cos

x b b x a x

y x x a b

1,515,5

2,9

abx

5 3 2 2

2

tg ( )

1ax

s x x b a x b

bx aQe

16,53,40,61

abx

6 2 2

2 3

( 1) sin ( )

cos ( )

R x x b x a

S xb a x b

0,70,050,5

abx

7 3 2 2

23

sin ( )

cos( )

y x a x b

xz x ba

1,10,0040,2

abx

160

Окончание таблицы 10.2 1 2 3

8 3 tg sin

cos( sin )

f m t c t

z m bt t c

2; 11,2; 0,7

m ct b

9 3 2

2

ln (1 )7 2sin cos3,75

y xxF x

1,45x

10 2 2ln( ) sin ( )

cx

f a x x b

x x az ex x b

10,2; 9,22,2; 0,5

a bx c

10.1.3 Задачи для выполнения лабораторных работ – часть 2

Задача 1. Заданы длины двух катетов прямоугольного треугольника

a и b. Написать программу, которая вычислит длину гипотенузы c и величины двух его углов и (рис.10.16). Значения a и b ввести с клавиатуры. Гипотенуза c вычисляется по формуле:

22 baс Углы треугольника и рассчитываются следующим образом:

baarctg ;

abarctg .

Рисунок 10.16

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

сторонами (угол задан в градусах) sin21

baS .

Пояснение: Аргумент встроенной математической функции Math.Sin(x) должен быть в радианах. Для перевода углов из градусов в радианы необходимо

величину угла в градусах умножить на дробь 180 . При записи дроби 1 2 имеем

целочисленное деление, при котором остаток отбрасывается. Чтобы этого не произошло меняем тип хотя бы одного из операндов: 1.0 2.0 или (double)1 2 .

161

Ниже приведен рекомендуемый вид экрана программы

Вычисление площади треугольника Введите длину стороны треугольника a –> 25 Введите длину стороны треугольника b –> 17 Введите величину угла между сторонами треугольника –> 30

Площадь треугольника: 106.25 кв. см. Таблица 10.3 – Список математических методов класса System.Math

Математические методы

Обозначение в математике

Назначение

Math.Abs(x) x Модуль (абсолютная величина числа x )

Math.Acos(x) arccos x Арккосинус числа x (в диапазоне от –1 до 1)

Math.Asin(x) arcsin x Арксинус числа x (в диапазоне от –1 до 1)

Math.Atan(x) arctg x Арктангенс числа x (в диапазоне от –1 до 1)

Math.Ceiling(x) Округление до большего целого. Возвращение ближайшего целого, большего, чем значение аргумента x.

Math.Cos(x) cos x Косинус угла x . Угол x задается в радианах.

Math.E – константа e Основание натурального логарифма (число e = 2,718)

Math.Exp(x) xe Экспонента. e – основание натурального логарифма, возведенное в степень x .

Math.Floor(x) Округление до меньшего целого. Возвращает ближайшее целое число, меньшее, чем значение аргумента x .

Math.IEERemainder(x,y) Возвращает остаток от деления числа x на число y

Math.Log(x) ln x Натуральный логарифм x , где 0x Math.Log10(x) lg x Десятичный логарифм x

Math.PI – константа Значение числа =3,1415926

Math.Pow(x,y) yx Возведение x в степень y

Math.Round(x) Округление. Округляет заданное число до ближайшего целого (арифметическое округление)

Math.Round(x, n) Округление. Округляет число с плавающей запятой до заданного количества дробных разрядов n

162

Окончание таблицы 10.3 1 2 3

Math.Sign(x) Знак числа. Возвращает значение, определяющее знак

целого числа. 1 0

( ) 0 если 01 0

xSign x x

x

Math.Sin(x) sin x Синус угла x . Угол x задается в радианах.

Math.Sqrt(x) x Корень квадратный из числа x , где 0x

Math.Tan(x) tg x Тангенс угла x . Угол x задается в радианах.

Math.Truncate(x) Вычисляет целую часть заданного десятичного числа.

Rnd(x) Случайное число из диапазона 0 – 1

Таблица 10.4 – Арифметические операции

Операция Знак Запись Действие Арифметическое сложение + a + b Складывает два числа

Унарный плюс + +а

Арифметическое вычитание – a – b Вычитает из одного числа другое

Унарный минус – –a

Умножение * a * b Умножает два числа

Деление / a / b Делит два числа и возвращает результат с плавающей точкой

Деление по модулю (опера-ция вычисления остатка)

% a%b Получение остатка от целочис-ленного деления (7%3 = 1). Можно применять и к типам с плавающей точкой (10.0%3.0=1).

Присваивание = a=b Задает новое значение переменной

Инкремент + + i++; ++i;

постфиксная форма, i = i+1; префиксная форма, i = i+1.

Декремент – – i– –; – – i;

постфиксная форма, i = i–1; префиксная форма, i = i–1.

Доступ к элементу . (точка) Выбор члена (класса или объекта)

Выделение памяти new Создание объекта (создание экземпляра)

163

Таблица 10.5 – Операторы сравнения и логические операторы Операторы сравнения Логические операторы

Оператор Знак Оператор Значение равно == & логическое И (AND) не равно != | логическое ИЛИ (OR) больше > ^ логическое исключающее ИЛИ (XOR) меньше < && условное И (AND) больше или равно >= || условное ИЛИ (OR) меньше или равно <= ! логическое отрицание НЕ (NOT)

Приоритет выполнения операторов: 1) Унарные операции (операции с одним операндом, например изменение

знака); 2) Операторы умножения/ деления; 3) Операторы сложения/ вычитания; 4) Операторы сдвига; 5) Операторы сравнения (причем операторы равно/ не равно имеют

меньший приоритет); 6) Логические. 7) Оператор присваивания выполняется последним. Операторы одного уровня приоритета выполняются слева направо. Порядок вычисления по умолчанию можно изменить с помощью круглых

скобок.

10.2 Составление программ разветвляющейся структуры

Цель работы: для консольного приложения: изучить операторы ветвления if и switch

для Windows-приложения: изучить элементы управления: метка Label, кнопка Button, поле ввода TextBox, список ListBox.

10.2.1 Примеры решения задач

Задача 10.2. Вычислить значения функции

00

еслиесли

12

52

xx

aax

y

при a = 5,2; x = – 3; 0; 34,85 Блок- схема решения задачи приведена на рис.10.17.

164

Начало

a = 5.2

Вводx

x < 0

Выводx, y

Конец

да

нет

2 5y x a ay 12

Рисунок 10.17 – Блок-схема алгоритма к задаче 10.2 Программный код : using System; namespace C4 { class Program { static void Main(string[] args) { double a, x, y; a = 5.2;

165

Console.Write("Введите x= "); x = Convert.ToDouble(Console.ReadLine()); if (x<0) y=x*x+5/a; else y=12+a; Console.WriteLine("x={0,6:F2}; y={1,6:F3}", x, y); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.18.

Рисунок 10.18 – Результаты решения задачи 10.2 Задача 10.3. Вычислить значения функции

1 cos 1( ) 2 если 1 4

1 4

a y yf ay b y

a y

при a=0,2; b=0,001; y= 0,5; 3; 12 Блок-схема решения задачи приведена на рис. 10.19.

166

1 4y 1y

1 cosf a y ( ) 2f ay b 1f a

Рисунок 10.19 – Блок-схема алгоритма к задаче 10.3

Способ 1. Создайте консольное приложение с использованием вложенных операторов if. Программный код: using System; namespace C5 {

167

class Program { static void Main(string[] args) { double a, b, y, f; a = 0.2; b = 0.001; Console.Write(" Введите y= "); y = Convert.ToDouble(Console.ReadLine()); if (y < 1) f = 1 - Math.Cos(a) - y; else if ((1 <= y) && (y <= 4)) f = (a * y + b) / 2; else f = a + 1; Console.WriteLine("y={0,6:F2}; f={1,6:F3}", y, f); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.20.

Рисунок 10.20 – Результаты решения задачи 10.3

168

Пояснение к программе: Математическое выражение 41 y в языке программирования С#

разделяется на два выражения, объединенные оператором && (И): (1 <= y) && (y <= 4).

Т.к. операции сравнения имеют более высокий приоритет чем логические, то скобки можно не ставить: 1 <= y && y <= 4. Способ 2. Создадим Windows-приложение. Значения a и b заданы в программном коде, значение y вводим в текстовое поле TextBox, результаты выводим в поле списка ListBox.

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты, как показано на рис. 10.21, 10.22. На форме расположить: две метки (Label); одно текстовое поле (TextBox); одно поле списка(ListBox); две командных кнопки (Button).

Рисунок 10.21 – Форма к задаче 10.3 2. Установите значения свойств объектов в соответствии с табли-

цей 10.6.

169

Таблица 10.6 – Значения свойств объектов к задаче 10.3 Объект Имя объекта по умолчанию

(значение свойства Name) Свойство Значение свойства

Форма Form1 Метка Label1 Text Введите y= Метка Label2 Text Результаты расчета Текстовое поле TextBox1 Name txty Поле списка ListBox1 Командная кнопка

Button1 Name cmdStart Text Вычислить Font Times New Roman, жирный, 12

Командная кнопка

Button2 Name cmdEnd Text Завершение работы Font Times New Roman, жирный, 12

Рисунок 10.22 – Форма к задаче 10.3

3. Программирование. Напишите обработчики событий щелчок мышью по командной кноп-

ке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.Windows.Forms; namespace W2 {

170

public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { double a, b, y, f; string str; a = 0.2; b = 0.001; y = Convert.ToDouble(txty.Text); if (y < 1) f = 1 - Math.Cos(a) - y; else if (1 <= y && y <= 4) f = (a * y + b) / 2; else f = a + 1; str = String.Format("y= {0,6:F2};\t f= {1,6:F3}", y, f); listBox1.Items.Add(str); } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.23

Рисунок 10.23 – Результаты решения задачи 10.3

171

Пояснение: 1)string str; Объявляется строковая переменная

2)str = String.Format("y= {0,6:F2};\t f= {1,6:F3}", y, f); Формируется строка, содержащая отформатированные данные. Для форматирования данных кроме метода ToString() применяется метод String.Format(). Строковая константа "y= {0,6:F2};\t f= {1,6:F3}" содержит управляющую последовательность символов \t – горизонтальная табуляция

3)listBox1.Items.Add(str); Вывод данных (текстовой строки) в поле ListBox. Элемент управления ListBox – поле списка. Для добавления элементов в список программным способом предназначен метод Add коллекции Items элемента ListBox.

Задача 10.4. Создайте консольное приложение для вычисления значения функции:

2( ) 0, 0

если 0, 05 в остальных случаях

z

x z x z

y x x z

при

x = 3; z = 5 x = –5 z = –4 x = 25 z = –8

Программный код: using System; namespace C6 { class Program { static void Main(string[] args) { double x, z, y; Console.Write(" Введите x= "); x = Convert.ToDouble(Console.ReadLine()); Console.Write(" Введите z= "); z = Convert.ToDouble(Console.ReadLine()); if (x > 0 && z > 0) y = Math.Pow((x * z), 2); else if (x < 0 && z < 0) y = Math.Pow(x, -z); else y = 5;

172

Console.WriteLine("x={0}; z={1}; y={2} ", x, z, y); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.24

Рисунок 10.24 – Результаты решения задачи 10.4

Задача 10.5. Создайте консольное приложение для вычисления

значения функции. Для решения задачи используйте многоступенчатую конструкцию if–else–if, состоящую из вложенных операторов if.

3

2

06 12 если 2 7

0 или 10035 в противном случае

x xx x

y x xx x x

Блок-схема решения задачи приведена на рис. 10.25.

173

3 6y x

2 2y x

y x

3xy

5y

2 7x

Рисунок 10.25 – Блок-схема алгоритма к задаче 10.5 Программный код: using System; namespace С7 {

174

class Program { static void Main(string[] args) { double x, y; Console.Write("Введите x= "); x = Convert.ToDouble(Console.ReadLine()); if (x == 0) y = x; else if (x == 1) y = x * x * x + 6; else if (2 <= x && x <= 7) y = x * x + 2; else if (x < 0 || x > 100) y = x / 3; else y = 5; Console.WriteLine("x={0}; y={1} ", x, y); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.26.

Рисунок 10.26 – Результаты решения задачи 10.5

175

Задача 10.6. Пример программы, которая запрашивает у пользователя номер дня недели и затем выводит его название. Если введены неправильные данные, программа должна вывести сообщение об ошибке. Используется оператор switch.

Программный код: using System; namespace C8 { class Program { static void Main(string[] args) { int nom; Console.Write("Введите номер дня недели -> "); nom = Convert.ToInt32(Console.ReadLine()); switch (nom) { case 1: Console.WriteLine("Понедельник" ); break; case 2: Console.WriteLine("Вторник"); break; case 3: Console.WriteLine("Среда"); break; case 4: Console.WriteLine("Четверг"); break; case 5: Console.WriteLine("Пятница"); break;

176

case 6: Console.WriteLine("Суббота"); break; case 7: Console.WriteLine("Воскресенье"); break; default: Console.WriteLine("Число должно быть в диапазоне 1..7"); break; } Console.ReadLine(); } } }

Результаты расчета см. рис. 10.27.

Рисунок 10.27 – Результаты решения задачи 10.6

Задача 10.7. Написать текст программы, вычисляющей корни

квадратного уравнения 02 cbxax

Программный код: using System; namespace C7a { class Program {

177

static void Main(string[] args) { double a, b, c, D, x1, x2; Console.WriteLine(" Введите a, b, c: "); a = Convert.ToDouble(Console.ReadLine()); b = Convert.ToDouble(Console.ReadLine()); c = Convert.ToDouble(Console.ReadLine()); Console.WriteLine(); D = b * b - 4 * a * c; if (D >= 0 && a != 0) { x1 = (-b + Math.Sqrt(D)) / (2 * a); x2 = (-b - Math.Sqrt(D)) / (2 * a); Console.WriteLine("x1={0}; x2={1}", x1, x2); } else { Console.WriteLine(" Нет решения "); } Console.ReadLine(); } } }

Результаты расчета см. рис. 10.28.

Рисунок 10.28 – Результаты решения задачи 10.7

10.2.2. Задачи для выполнения лабораторных работ – часть 1

Условия задач и исходные данные для выполнения лабораторных работ приведены в табл. 10.7.

178

Таблица 10.7 – Варианты задач №

вар. Функция Исходные данные

1 2 3 1 2 2 0, 0

если 0, 0в ост. случаях

x x y x yz x y x y

x y

0,5; 2,5 2,31; 4,2 5; 7

x yx yx y

2 2

3 2sin 0ln (1 ) если 0

0

x xy x x

x c x

1,573; 2,5; 0

сx

3 3

2

0,3 00 если 0 1

1

y yg y

yy y

2; 3; 1,5; 0

y zz

4

2

( ) 0, 0( 5 ) если 0, 0

0 остальное

zxy y zc x y z y z

1; 0,5; 0 0,5; 1,5; 3 0,5

yzx

5 2

2

( 1) 01/ ( 1) если 0 4

4sin ( 1)

t bc tm t t

tt

0,5; 1,2; 2; 3; 5,67

b ct

6 2 ln 1 21 если 1

2cosat

at t ty t

te bt

0,52

1,5; 0,5; 2,3

abt

7 3

sin если

cosax

x x a x ax ax x a

x ae ax

2,53; 2,5; 1

ax

179

Окончание таблицы 10.7 1 2 3

8 2 0, 042cos ln если 0, 0

12 0, 0

a ba bz a b a b

a a b

2; 5;

3,5; 7;8; 12;

a ba ba b

9

3

2

16 1 2

если 22 20

x xx x

yxxx

0,5; 1,2; 2; 4x

10 3 2

2

cos 00 если

0 и 20

ax a x xxax bxg

x xbxax b

2; 1

2; 0; 3,5; 1,5a bx

10.2.3. Задачи для выполнения лабораторных работ – часть 2

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

c использованием вложенных операторов if; c использованием оператора выбора switch.

Ниже приведен рекомендуемый вид экрана программы. Введите номер месяца (число от 1 до 12) –> 11 Зима

Задача 2. Написать программу, которая позволяет посчитать стоимость заправки автомобиля.

180

Исходные данные: тип топлива (бензин 92, 95, 98 или дизельное топливо); количество литров.

Использовать оператор выбора switch. Ниже приведен рекомендуемый вид экрана программы (данные, введенные пользователем, выделены полужирным). Бензин Марка бензина: 1 – 92 2 – 95 3 – 98 4 – DT Ваш выбор –> 2 Литров –> 25 -------------------------- Цена за литр: 10 грн. Литров: 25 К оплате: 250 грн.

Задача 3. Написать программу, которая позволяет посчитать стоимость печати фотографий. Исходные данные:

размер фотографий (9×12, 10×15 или 18×24); количество фотографий. Если заказанных фотографий больше 10, заказчику предоставляется

скидка – 10%, если заказанных фотографий больше 50, скидка –15%. Использовать оператор выбора switch. Ниже приведен рекомендуемый вид экрана программы (данные,

введенные пользователем, выделены полужирным). Фото Размер: 1 – 9×12 2 – 10×15 3 – 18×24 Ваш выбор –> 1 Количество –> 12 -----------------------

181

Цена: 3.50 грн. Количество: 12 шт. Сумма: 42.00 грн. Скидка: 4.20 грн. К оплате: 37.80 грн.

Задача 4. Написать программу, которая запрашивает у пользователя номер дня недели и выводит одно из сообщений: Рабочий день , Суббота или Воскресенье .Использовать вложенные if.

Задача 5. Написать программу вычисления стоимости разговора по телефону с учетом 20%-ной скидки, предоставляемой по субботам и воскресеньям. Ниже приведен рекомендуемый вид экрана программы: Вычисление стоимости разговора по телефону Введите исходные данные: Длительность разговора (целое количество минут) –> 3 День недели (1– понедельник, ……7 – воскресенье) –> 6 Предоставляется скидка 20% Стоимость разговора: 15,52 грн.

10.3 Циклы

Цель работы: для консольного приложения: изучить операторы цикла: for, while, do-while.

для Windows-приложения: изучить элементы управления: метка Label, кнопка Button, список ListBox.

10.3.1 Примеры решения задач

Задача 10.8. Написать программу, которая выводит таблицу значений функции 354,2 2 xxy в диапазоне от –2 до 2, с шагом 0,5. Таблица должна состоять из двух столбцов: значений аргумента и соответствующих им значений функции. Для решения задачи использовать операторы циклов: for, while, do-while.

Способ 1. Создать консольное приложение с использованием цикла for

182

Программный код: using System; namespace C9 { class Program { static void Main(string[] args) { double x, y; // аргумент и значение функции double xn = -2.0; // начальное значение переменной x double xk = 2.0; // конечное значение переменной x double dx = 0.5; // шаг изменения переменной Console.WriteLine("-------------------"); Console.WriteLine(" x y "); Console.WriteLine("-------------------"); for (x = xn; x <= xk; x = x + dx) { y = -2.4 * x * x + 5 * x - 3; Console.WriteLine("{0,6:F2}\t {1,6:F3}", x, y); } Console.ReadLine(); } } }

Результаты расчета см. рис. 10.29.

Рисунок 10.29 – Результаты решения задачи 10.8 Пояснение: 1) Console.WriteLine("{0,6:F2}\t {1,6:F3}", x, y);

183

Выводит строку результатов в заданном формате в консольное окно. Строковая константа "{0,6:F2}\t {1,6:F3}" содержит управляющую последовательность символов \t – горизонтальная табуляция Примечание. Чтобы остановить зациклившуюся программу используйте клави-ши <Esc> или <Ctrl> + <Break>. Способ 2. Создать консольное приложение с использованием цикла while. Программный код: using System; namespace C10 { class Program { static void Main(string[] args) { double x, y; // аргумент и значение функции double xn = -2.0; // начальное значение переменной x double xk = 2.0; // конечное значение переменной x double dx = 0.5; // шаг изменения переменной Console.WriteLine("-------------------"); Console.WriteLine(" x y "); Console.WriteLine("-------------------"); x = xn; while (x <= xk) { y = -2.4 * x * x + 5.0 * x - 3.0; Console.WriteLine("{0,6:F2}\t {1,6:F3}", x, y); x = x + dx; } Console.ReadLine(); } } }

Результаты расчета см. рис.10.29.

Способ 3. Создать консольное приложение с использованием цикла do-while.

184

Программный код: using System; namespace C11 { class Program { static void Main(string[] args) { double x, y; // аргумент и значение функции double xn = -2; // начальное значение переменной x double xk = 2; // конечное значение переменной x double dx = 0.5; // шаг изменения переменной Console.WriteLine("-------------------"); Console.WriteLine(" x y "); Console.WriteLine("-------------------"); x = xn; do { y = -2.4 * x * x + 5 * x - 3; Console.WriteLine("{0,6:F2}\t {1,6:F3}", x, y); x = x + dx; } while (x <= xk); Console.ReadLine(); } } }

Результаты расчета см. рис.10.29.

Способ 4. Создать Windows-приложение с использованием цикла for

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты, как показано на рис. 10.30, 10.31. На форме расположить: одну метку (Label); одно поле списка (ListBox); две командных кнопки (Button).

185

Рисунок 10.30 – Форма к задаче 10.8

2. Установите значения свойств объектов в соответствии с табл. 10.8. Таблица 10.8 – Значения свойств объектов к задаче 10.8

Объект Имя объекта по умолчанию (значение свойства Name)

Свойство Значение свойства

Форма Form1 Метка Label Text Результаты расчета Поле списка ListBox1 Командная кнопка

Button1 Name cmdStart Text Вычислить

Командная кнопка

Button2 Name cmdEnd Text Завершение работы

Рисунок 10.31 – Форма к задаче 10.8

186

3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.Windows.Forms; namespace W3 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { double x, y; // аргумент и значение функции double xn = -2; // начальное значение переменной x double xk = 2; // конечное значение переменной x double dx = 0.5; //шаг изменения переменной listBox1.Items.Add("-------------------------"); listBox1.Items.Add(" x y "); listBox1.Items.Add("-------------------------"); for (x = xn; x <= xk; x = x + dx) { y = -2.4 * x * x + 5 * x - 3; listBox1.Items.Add(x.ToString("F2") + "\t" + y.ToString("F3")); } } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.32.

187

Рисунок 10.32 – Результаты решения задачи 10.8

Пояснение: 1)listBox1.Items.Add(x.ToString("F2") + "\t" + y.ToString("F3")); Вывод данных в поле listBox. Строковая константа "\t" содержит управляющую последовательность символов \t – горизонтальная табуляция.

Задача 10.9. Создать консольное приложение для вычисления

факториала k!

Программный код: using System;

namespace C12 { class Program { static void Main(string[] args) { int i, k; double p; Console.Write(" Введите k= "); k = Convert.ToInt32(Console.ReadLine()); p = 1; for (i = 1; i <= k; i++) p = p * i; Console.WriteLine("{0}! = {1}", k, p);

188

Console.ReadLine(); } } }

Результаты расчета см. рис. 10.33.

Рисунок 10.33 – Результаты решения задачи 10.9

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

первых n членов ряда: ...41

31

211 .

Количество суммируемых членов ряда задается во время работы программы. Ниже приведен рекомендуемый вид экрана программы. Введите количество суммируемых членов ряда –> 15 Сумма первых 15 членов ряда равна 3.3182 Программный код: using System; namespace C16a { class Program { static void Main(string[] args) { int n; // кол-во суммируемых членов ряда int i; // номер элемента ряда double elem; // значение элемента ряда double sum; // сумма элементов ряда Console.Write("Введите количество суммируемых членов ряда n->"); n = Convert.ToInt32(Console.ReadLine()); Console.WriteLine(" n= " + n); sum = 0; for (i = 1; i <= n; i = i + 1) { elem = 1.0 / i;

189

sum = sum + elem; } Console.WriteLine(); Console.WriteLine(" Сумма первых {0} членов ряда = {1,6:F4} ", n, sum); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.34.

Рисунок 10.34 – Результаты решения задачи 10.10

Задача 10.11. Вывести для аргумента x, изменяющегося в пределах 122 x с шагом 2, таблицу значений следующей функции:

10100

0x если

2

,

xx

txt

ty

при t =5. Программа должна выводить таблицу, состоящую из двух столбцов:

значений аргумента и соответствующих им значений функции.

Программный код: using System; namespace C16 { class Program { static void Main(string[] args) { double x, y, t=5; double xn = -2; // начальное значение аргумента

190

double xk = 12; // конечное значение аргумента double dx = 2; // шаг изменения аргумента // заголовок таблицы Console.WriteLine("------------------"); Console.WriteLine(" x y "); Console.WriteLine("------------------"); // расчет и вывод таблицы for (x = xn; x <= xk; x = x + dx) { if (x<0) y=t; else if (0<=x && x<10) y=t*x; else y=2*t; Console.WriteLine("{0,6:F2}\t {1,6:F3}", x, y); } Console.ReadLine(); } } }

Результаты расчета см. рис. 10.35.

Рисунок 10.35 – Результаты решения задачи 10.11

10.3.2 Задачи для выполнения лабораторных работ – часть 1

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

y x bx Sin L для 0 x 1, с шагом h = 0,1; где b=2,3; L=1,45.

191

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

432 75,05,23 xxxxy для 1 x 4, с шагом h = 0,5;

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

34 5,148 mmmy для 1 x 3, с шагом h = 0,2;

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

22 ;41 22 rSrS для 1 r 1,4; с шагом h = 0,05; Результат получить в виде таблицы

R S1 S2

1.00 12.566 1.571 . . . . . . . . . . . .

1.40 24.630 3.079

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

xy для –4 x 4, с шагом h = 0,5;

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

12 xxy для –4 x 4, с шагом h = 0,5;

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

37,4152 23 xxxy для –3 x 3, с шагом h = 0,5;

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

cos( ) 25 5sin ( ) 3xy x для 1 x 5, с шагом h = 0,5;

192

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

3

33sin ( ) 2,3

2cos ( )xy

x x

для 3 x 9, с шагом h = 0,5;

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

функции:

3 2sin ( ) 0,6y x x для 1 x 10, с шагом h = 1.

10.3.3 Задачи для выполнения лабораторных работ – часть 2

Задача 1. Сумма последовательности. Написать программу: с клавиатуры ввести целое положительное число n. На консоль вывести сумму всех целых чисел от 0 до n.

Задача 2. Произведение последовательности. Написать программу: с клавиатуры ввести два целых положительных числа n1 и n2. На консоль вывести произведение всех целых чисел от n1 до n2 включительно.

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

------------------------------------------ Число Квадрат Куб ------------------------------------------ 1 1 1 2 4 8 3 9 27 . . . . . . 10 100 1000

Задача 4. Сумма последовательности Написать программу: с клавиатуры ввести вещественное

положительное число x с точностью до 0,1. На консоль вывести сумму

193

всех чисел от 0 до x с шагом 0,1. Задачу решить двумя способами – с использованием операторов for и while.

Задача 5. Написать программу, которая выводит таблицу скорости (через каждые 0,5с) свободно падающего тела tgv , где 28,9 смg – ускорение свободного падения. Рекомендуемый вид экрана приведен ниже.

--------------------------------------- Время, с Скорость, см --------------------------------------- 0.0 0.00 0.5 4.90 1.0 9.80 1.5 14.70 2.0 19.60 2.5 24.50 3.0 29.40

Задача 6. Написать программу, которая выводит на экран таблицу соответствия температуры в градусах Цельсия и Фаренгейта ( 9 5 32o oF C ). Диапазон изменения температуры в градусах Цельсия и шаг должны вводиться во время работы программы. Рекомендуемый вид экрана приведен ниже.

t1 → 0 t2 → 10 dt → 1

---------------------------------- С F ---------------------------------- 0.0 32.00 1.00 33.80 2.00 35.60 . . . . 10.00 50.00

Задача 7. Написать программу, которая выводит на экран таблицу умножения, например, на 7. Рекомендуемый вид экрана программы приведен ниже.

7×1=7 7×2=14 7×3=21 7×4=28

194

7×5=35 7×6=42 7×7=49 7×7=56 7×9=63

Задача 8. Сумма последовательности. Написать программу: с клавиатуры ввести целое положительное

число n. Из числа n получить число m – логической операцией установить флаг нечетности (если число нечетное, оно не меняется, если число четное, то оно увеличивается на единицу). На консоль вывести сумму всех нечетных чисел диапазона от m до m 2.

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

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

для Windows-приложения: изучить элементы управления: метка Label, кнопка Button, поле ввода TextBox, список ListBox, комбинированное окно ComboBox.

10.4.1 Примеры решения задач

Задача 10.12. Вычислить 10

4i

iz y

,

где iy – элементы одномерного массива Y(12); i = 0,1,…11; 10

4i

iy

– сумма элементов одномерного массива Y с 4-го по 10-ый.

Пояснение: Обозначение "одномерный массив Y(12)" означает массив

)11,...1,0 ;( iyY i , размер массива (количество элементов) =12. Нижний индекс элементов массива = 0, верхний индекс = 11.

Способ 1. Создадим консольное приложение, в котором элементы массива заданы в программном коде. Размер массива укажем при помощи константы.

195

Программный код: using System; namespace С21 { class Program { static void Main(string[] args) { const int n = 12; // количество элементов массива int i; double z, s; double[] Y = new double[n] { 1.0, 2.5, 3.7, 4.8, 5.0, 6.2, 7.3, 8.0, 9.5, 10.0, 12.0, 14.0 }; Console.WriteLine("Элементы массива: "); // Вывод элементов массива for ( i = 0; i <= n-1; i = i + 1) Console.WriteLine( " " + Y[i]); // Накопление суммы элементов с 4-го по 10-ый s = 0; for (i = 4; i <= 10; i = i + 1) s = s + Y[i]; z = s; Console.WriteLine(); Console.WriteLine("Сумма элементов массива= {0}", z); Console.ReadLine(); } } }

Результаты расчета см. рис.10.36.

Рисунок 10.36 – Результаты решения задачи 10.12

196

Пояснение: 1)double[] Y = new double[n] { 1.0, 2.5, 3.7, 4.8, 5.0, 6.2, 7.3, 8.0, 9.5, 10.0, 12.0, 14.0 }; Одновременно с созданием массива он заполняется нужными значениями. Если указаны и размер n, и список инициализаторов, размер n должен быть только константой.

Способ 2. Создадим консольное приложение, в котором элементы массива рассчитываются по формуле: 70.2 iyi Программный код: using System; namespace C23 { class Program { static void Main(string[] args) { const int n = 12; // количество элементов массива double [] Y = new double[n]; int i; double z, s; Console.WriteLine("Элементы массива: "); Console.WriteLine(); for (i = 0; i <= n-1; i = i + 1) { Y[i] = i / 2.0 + 7; Console.WriteLine("Y[{0}]={1} ", i, Y[i]); } s = 0; for (i = 4; i <= 10; i = i + 1) s = s + Y[i]; z = s; Console.WriteLine("\nСумма элементов массива= {0}", z); Console.ReadLine(); } } }

Результаты расчета см. рис.10.37

197

Рисунок 10.37 – Результаты решения задачи 10.12 Пояснение: 1)double [] Y = new double[n]; Объявляется массив Y из n вещественных чисел типа double , при этом все n элемен-тов автоматически (неявно) инициализируются нулями; n может быть не только константой, но и выражением типа, приводимого к целому.

2)Y[i] = i/2.0 + 7; Если написать Y[i] = i/2+7; получим деление целых чисел. При делении целых чисел остаток будет отброшен, чтобы этого не произошло необходимо менять тип хотя бы одного из них, т.е. i/2.0.

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

Программный код: using System; namespace C24 { class Program { static void Main(string[] args) { const int n = 12; // количество элементов массива double[] Y = new double[n]; int i; double z, s; Console.WriteLine("Ввод элементов массива: ");

198

for (i = 0; i <= n-1; i = i + 1) { Console.Write("Введите " + i + "элемент массива = "); Y[i] = Convert.ToDouble(Console.ReadLine()); } Console.WriteLine(); Console.WriteLine("Вывод элементов массива: "); for (i = 0; i <= n-1; i = i + 1) { Console.WriteLine("Y[{0}]={1} ", i, Y[i]); } s = 0; for (i = 4; i <= 10; i = i + 1) s = s + Y[i]; z = s; Console.WriteLine("Сумма элементов массива= {0} ", z); Console.ReadLine(); } } }

Результаты расчета см. рис.10.38.

Рисунок 10.38 – Результаты решения задачи 10.12

199

Способ 4. Создадим консольное приложение, в котором вещест-венные элементы массива задаются при помощи генератора случайных чисел. Числа должны находиться в диапазоне 0.0…10.0.

Программный код: using System; namespace C26 { class Program { static void Main(string[] args) { const int n = 12; // количество элементов массива double[] Y = new double[n]; int i; double z, s; Random rnd = new Random(); Console.WriteLine("Элементы массива: "); for (i = 0; i <= n-1; i = i + 1) { Y[i] = rnd.NextDouble()*10; Console.WriteLine("Y[{0}]={1,5:F2} ", i, Y[i]); } s = 0; for (i = 4; i <= 10; i = i + 1) s = s + Y[i]; z = s; Console.WriteLine(); Console.WriteLine("Сумма элементов массива= {0,6:F3}", z); Console.ReadLine(); } } }

Результаты расчета см. рис.10.39.

Рисунок 10.39 – Результаты решения задачи 10.12

200

Пояснение: Для того чтобы задать целые элементы массива при помощи генератора случайных чисел, например в диапазоне от 1 до 19 используем оператор: Y[i] = rnd.Next(1,20);

Способ 5. Создадим Windows-приложение, в котором элементы массива рассчитываются по формуле, значения элементов массива выводятся в поле списка. Сумма элементов массива с 4-го по 10-ый выводится на метку.

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты, как показано на рис. 10.40, 10.41. На форме расположить: две метки (Label), одно поле списка

(ListBox), две командных кнопки (Button).

Рисунок 10.40 – Форма к задаче 10.12

2. Установите значения свойств объектов в соответствии с табл. 10.9

Таблица 10.9 – Значения свойств объектов к задаче 10.12 Объект Имя объекта по умолчанию

(значение свойства Name) Свойство Значение свойства

Форма Form1 Метка Label1 text Элементы массива Y Метка Label2 text Поле списка ListBox1 Name ListBox1 Командная кнопка

Button1 Name cmdStart Text Вычислить

Командная кнопка

Button2 Name cmdEnd Text Завершение работы

201

Рисунок 10.41 – Форма к задаче 10.12

3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.Windows.Forms; namespace W4 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { const int n = 12; // количество элементов массива double[] Y = new double[n]; int i; double z, s; for (i = 0; i <= n-1; i = i + 1) { // Вычисление элементов массива Y[i] = i / 2.0 + 7;

202

// Вывод элементов массива в поле списка listBox1.Items.Add( Y[i].ToString("F2")); } s = 0; for (i = 4; i <= 10; i = i + 1) s = s + Y[i]; z = s; Console.WriteLine(); label2.Text=("Сумма элементов массива\n с 4-го по 10-ый = " + z.ToString("F3")); } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис.10.42.

Рисунок 10.42 – Результаты решения задачи 10.12 Пояснение: 1)double[] Y = new double[n];

Объявляется массив Y из n вещественных чисел типа double и одновременно все элементы массива автоматически (неявно) инициализируются нулями.

203

2) listBox1.Items.Add( Y[i].ToString("F2")); Вывод элементов массива Y в поле listBox1. При выводе числа его

необходимо преобразовать в последовательность символов, т.е. в строку. Для этого применяется метод ToString(). В качестве параметра функции ToString() указана символьная константа, которая задаёт формат строки-результата. Символьная константа "F2" означает формат F(Fixed) – число с фиксированной точкой, три знака после запятой.

3) label2.Text = ("Сумма элементов массива\n с 4-го по 10-ый = " + z.ToString("F3"));

Вывод данных в поле label2. Для вывода на метку используется свойство Text – надпись на метке.

Задача 10.13. Создать консольное приложение для решения задачи:

Вычислить

11

0iiaz ,

где ia – элементы одномерного массива A(12); i =0,1,…11;

11

0iia – произведение всех элементов одномерного массива A(12).

Значения элементов массива вычислить по формуле: 0.70.3 iai .

Программный код: using System; namespace С27 { class Program { static void Main(string[] args) { const int n = 12; // количество элементов массива double[] A = new double[n]; int i; double z, p; Console.WriteLine("Элементы массива: "); Console.WriteLine(); for (i = 0; i<=n-1; i = i + 1) { A[i] = (i+3.0)/7.0; Console.WriteLine("A[{0}]={1,5:F2} ", i, A[i]); }

204

p = 1; for (i = 0; i <= n-1; i = i + 1) p = p * A[i]; z = p; Console.WriteLine(); Console.WriteLine("Произведение элементов массива= {0,7:F3} ", z); Console.ReadLine(); } } }

Результаты расчета см. рис.10.43.

Рисунок 10.43 – Результаты решения задачи 10.13

Задача 10.14. Отсортировать элементы одномерного массива. Для сортировки элементов одномерного массива имеется

Array.Sort(a) – метод Sort класса Array. Следующий пример демонстрирует сортировку массива целых чисел

A(10).

Программный код: using System; namespace C28 { class Program { static void Main(string[] args) {

205

const int n = 10; // количество элементов массива int i; int[] A = new int[n] { 12, 4, 7, 9, 10, 5, 15, 2, 3, 1 }; Console.WriteLine("Исходный массив"); // Вывод элементов исходного массива for (i = 0; i <=n-1; i = i + 1) Console.Write(" " + A[i]); Console.WriteLine(); Array.Sort(A); Console.WriteLine(); Console.WriteLine("Отсортированный массив"); // Вывод элементов отсортированного массива for (i = 0; i <= n - 1; i = i + 1) Console.Write(" " + A[i]); Console.WriteLine(); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.44.

Рисунок 10.44 – Результаты решения задачи 10.14

Задача 10.15. Создать консольное приложение для расчета среднего арифметического элементов одномерного массива A(n), где n – количество элементов массива. Значение n задать произвольно, элементы массива создать при помощи генератора случайных чисел.

Программный код: using System; namespace C30 { class Program {

206

static void Main(string[] args) { int n; // количество элементов массива int i; double s; // сумма элементов массива double sr; // среднее арифм. значение элементов массива Console.Write("Введите количество элементов массива= "); n = Convert.ToInt32(Console.ReadLine()); int[] A = new int[n]; Random rnd = new Random(); Console.WriteLine("Элементы массива: "); s = 0; for (i = 0; i <= n-1; i = i + 1) { A[i] = rnd.Next(1, 20); Console.WriteLine("A[{0}]={1} ", i, A[i]); s = s + A[i]; } sr = s / n; Console.WriteLine("Среднее арифметическое элементов массива = {0,6:F3}", sr); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.45.

Рисунок 10.45 – Результаты решения задачи 10.15

207

Задача 10.16. Создать консольное приложение для расчета максимального элемента одномерного массива вещественных чисел A(12) и его индекса (порядкового номера). Значения элементов массива задать в программном коде.

Программный код: using System; namespace C31 { class Program { static void Main(string[] args) { const int n = 12; // количество элементов массива double max; // максимальный элемент int imax; // индекс максимального элемента int i; double[] A = new double[n] { 1.0, -2.5, 3.7, 94.8, 15.0, 65.2, -7.3, 18.0, 29.5, 10.0, 17.0, 14.0 }; Console.WriteLine("Элементы массива: "); Console.WriteLine(); // Вывод элементов массива for (i = 0; i <= (n - 1); i = i + 1) Console.WriteLine("A[{0}]={1} ", i, A[i]); max = A[0]; imax = 0; for (i = 0; i <= (n - 1); i = i + 1) { if (A[i] > max) { max = A[i]; imax = i; } } Console.WriteLine(); Console.WriteLine("Максимальный элемент массива= {0}", max); Console.WriteLine("Индекс максимального элемента= {0}", imax); Console.ReadLine(); } } }

208

Результаты расчета см. рис. 10.46.

Рисунок 10.46 – Результаты решения задачи 10.16

Пояснение: Алгоритм решения задачи следующий. Пусть в переменной с именем max хранится значение максимального элемента массива, а в переменной с именем imax – его номер. Предположим, что первый элемент массива (элемент с индексом 0) является максимальным, и запишем его в переменную max, а в imax – его номер (то есть 0). Затем все элементы, начиная с индекса 1, сравниваем в цикле с максимальным. Если текущий элемент массива оказывается больше максимального, то записываем его в переменную max, а в переменную imax – текущее значение индекса i.

Задача 10.17. Создать Windows-приложение, позволяющее: 1) заполнять одномерный массив A(n) двумя способами:

случайными вещественными числами ; путем расчета элементов массива по формуле.

2) находить среднее арифметическое элементов массива. 3) находить максимальный элемент массива и его индекс (номер).

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты (рис. 10.47, 10.48). На форме расположить: четыре метки (Label), одно текстовое поле (TextBox),

209

один объект комбинированное окно (ComboBox) для выбора способа заполнения массива,

одно поле списка (ListBox) четыре командных кнопки (Button).

Рисунок 10.47 – Форма к задаче 10.17

2. Установите значения свойств объектов в соответствии с табл. 10.10.

Таблица 10.10 – Значения свойств объектов к задаче 10.17

Объект Имя объекта по умолчанию (значение

свойства Name)

Свойство Значение свойства

1 2 3 4 Форма Form1

Метка Label1 text Количество элементов массива

Метка Label2 text Элементы массива Метка Label3 Метка Label4 Текстовое поле TextBox1 Name txtN

Поле списка ListBox1

210

Окончание таблицы 10.10 1 2 3 4

Командная кнопка

Button1 Name cmdMas text Заполнение массива

Командная кнопка

Button2 Name cmdSred text Вычисление среднего

арифметического Командная кнопка

Button3 Name cmdMax text Вычисление максимального

элемента массива и его индекса Командная кнопка

Button4 Name cmdEnd text Завершение работы

Комбинированное окно

ComboBox1 Name ComboBox1 Text Выберите способ заполнения

массива Items Случайными числами

Рассчитать по формуле

Рисунок 10.48 – Форма к задаче 10.17

3. Программирование. 1) Напишите обработчик события щелчок мышью по командной кнопке

<Заполнение массива>. 2) Напишите обработчик события щелчок мышью по командной кнопке

<Вычисление среднего арифметического>. 3) Напишите обработчик события щелчок мышью по командной кнопке

<Вычисление максимального элемента массива и его индекса>.

211

4) Напишите обработчик события щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.Windows.Forms; namespace W7 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } int n; double[] A; private void cmdMas_Click(object sender, EventArgs e) { int i; Random rnd = new Random(); n = Convert.ToInt32(txtN.Text); A = new double[n]; switch (comboBox1.SelectedIndex) { case 0 : for (i = 0; i <= (n-1); i = i + 1) { A[i] = rnd.NextDouble()*10; listBox1.Items.Add(A[i].ToString("F2")); } break; case 1 : for (i = 0; i <= (n-1); i = i + 1) { A[i] = (i+2)/3.0; listBox1.Items.Add(A[i].ToString("F2")); } break; } }

212

private void cmdSred_Click(object sender, EventArgs e) { double s; // сумма элементов массива double sr; // среднее арифметическое элементов массива int i; s = 0; for (i = 0; i <= (n - 1); i = i + 1) { s = s + A[i]; } sr = s / n; label3.Text = "Среднее арифметическое= " +sr.ToString("F3"); } private void cmdMax_Click(object sender, EventArgs e) { double max; // максимальный элемент массива int imax; // индекс максимального элемента int i; max = A[0]; imax = 0; for (i = 1; i <= (n - 1); i = i + 1) { if (A[i]>max) { max=A[i]; imax=i; } } label4.Text= "Максимальный элемент = " + max.ToString("F3") +"\n" + "Индекс макс. элемента = " + imax; } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.49, 10.50.

213

Способ 1. Заполнение массива случайными числами

Рисунок 10.49 – Результаты решения задачи 10.17

Способ 2. Заполнение массива – вычисление по формуле

Рисунок 10.50 – Результаты решения задачи 10.17

Задача 10.18. В одномерном массиве целых чисел A(12) все поло-

жительные числа увеличить вдвое, а также вычислить количество чисел равных 0 и сумму всех отрицательных чисел. Задачу решить в виде консольного приложения. Блок-схема решения представлена на рис. 10.51.

214

Начало

A= (5, 8, 0, 14, -15, 17, 0, -20, 0, 23,

25, -30)

i = 0, n-1

k = 0s = 0

i = 0, n-1

i = 0, n-1

Выводk, s

да

нет

да

нет

n = 12

Конец

Выводia

0ia 0ia

2i ia a 1k k is s a

Выводia

Рисунок 10.51 – Блок-схема алгоритма к задаче 10.18

215

Программный код: using System; namespace C32 { class Program { static void Main(string[] args) { const int n = 12; // количество элементов массива int i, k; double s; int[] A = new int[n] {5,8,0,14,-15,17,0,-20,0,23,25,-30}; // Вывод элементов массива Console.WriteLine("Исходный массив А: "); for (i = 0; i <= n - 1; i = i + 1) Console.Write(" " + A[i]); Console.WriteLine(); Console.WriteLine(); k = 0; s = 0; for (i = 0; i <= (n - 1); i = i + 1) { if (A[i] > 0) A[i] = 2 * A[i]; else if (A[i] == 0) k = k + 1; else s = s + A[i]; } // Вывод элементов нового массива Console.WriteLine("Новый массив А: "); for (i = 0; i <= n - 1; i = i + 1) Console.Write(" " + A[i]); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Количество элементов равных нулю = {0}", k); Console.WriteLine("Сумма всех отрицательных элементов = {0}", s); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.52.

216

Рисунок 10.52 – Результаты решения задачи10.18

Задача 10.19. В одномерном массиве целых чисел A(12) определить сумму элементов кратных трем и их количество.

Программный код: using System; namespace C33 { class Program { static void Main(string[] args) { const int n = 12; // количество элементов массива int i, k; double s; int[] A = new int[n] { 2,3,7,9,11,12,14,15,16,17,18,20 }; // Вывод элементов массива Console.WriteLine("Массив А: "); for (i = 0; i <= n - 1; i = i + 1) Console.Write(" " + A[i]); Console.WriteLine("\n"); k = 0; s = 0; Console.WriteLine("Элементы кратные трем: "); for (i = 0; i <= (n - 1); i = i + 1) { if (A[i] % 3 == 0) { k = k + 1; s = s + A[i]; Console.Write(" " + A[i]); } } Console.WriteLine("\n"); Console.WriteLine("Количество элементов кратных трем = {0}", k);

217

Console.WriteLine("Сумма элементов кратных трем = {0}", s); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.53.

Рисунок 10.53 – Результаты решения задачи 10.19

Задача 10.20. Вычислить значение выражения:

9

05,6i i

iP x y

,

где ix – элемент одномерного массива X(10); i=0,1,…9;

iy – элемент одномерного массива Y(10); i=0,1,…9.

Способ 1. Создать консольное приложение. Блок-схема решения задачи представлена на рис. 10.55.

Программный код: using System; namespace C35 { class Program { static void Main(string[] args) { const int n = 10; // кол-во элементов каждого массива double s, p; double[] X = new double[n]; double[] Y = new double[n]; //Вычисление и вывод элементов массива X Console.WriteLine(" Массив X ");

218

for (int i = 0; i <= (n - 1); i = i + 1) { X[i] = i / 3.0; Console.WriteLine("X[{0}]={1,7:F3} ", i, X[i]); } Console.WriteLine(); //Вычисление и вывод элементов массива Y Console.WriteLine(" Массив Y "); for (int i = 0; i <= (n - 1); i = i + 1) { Y[i] = i / 2.0 + 4; Console.WriteLine("Y[{0}]={1,7:F3} ", i, Y[i]); } Console.WriteLine(); //Накопление суммы s = 0; for (int i = 0; i <= (n - 1); i = i + 1) { s = s + (X[i] + 5.6 * Y[i]); } p = s; Console.WriteLine("p= {0,7:F3}", p); Console.ReadLine(); } } }

Результаты расчета см. рис.10.54.

Рисунок 10.54 – Результаты решения задачи 10.20

219

Вывод ix

Вывод iy

Ввод ib

( 5.6* ( ))is s x y i

3ix i

2 4iy i

Рисунок 10.55 – Блок-схема алгоритма к задаче 10.20 (способ 1)

Способ 2. Для данной задачи создать Windows-приложение. Блок-схема решения задачи представлена на рис. 10.56.

220

Вывод в поле списка ListBox1

ix

Вывод в поле списка ListBox2

iy

Ввод ib

( 5.6* ( ))is s x y i

3ix i

2 4iy i

Блок-схемы обработчиков событий cmdMas_Click и cmdP_Click

Рисунок 10.56 – Блок-схема алгоритма к задаче 10.20 (Способ 2)

221

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты, как показано на рис. 10.57, 10.58. На форме расположить: три метки (Label), два поля списка (ListBox),

три командных кнопки (Button).

Рисунок 10.57 – Форма к задаче 10.20 2. Установите значения свойств объектов в соответствии с

табл. 10.11.

Таблица 10.11 – Значения свойств объектов к задаче 10.20 Объект Имя объекта по умолчанию

(значение свойства Name) Свойство Значение свойства

Форма Form1

Метка Label1 text Массив X Метка Label2 text Массив Y Метка Label3 Поле списка ListBox1 Поле списка ListBox2 Командная кнопка

Button1 Name cmdMas text Вычисление и вывод

элементов массивов X и Y Командная кнопка

Button2 Name cmdP text Вычисление P

Командная кнопка

Button3 Name cmdEnd text Завершение работы

222

Рисунок 10.58 – Форма к задаче 10.20

3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычисление и вывод элементов массивов X и Y>, щелчок мышью по командной кнопке <Вычисление P>, щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.Windows.Forms; namespace W9 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } const int n = 10; // количество элементов каждого массива double[] X = new double[n]; double[] Y = new double[n]; private void cmdMas_Click(object sender, EventArgs e) { //Вычисление и вывод элементов массива X for (int i = 0; i <= (n - 1); i = i + 1) { X[i] = i / 3.0;

223

listBox1.Items.Add( X[i].ToString("F3")); } //Вычисление и вывод элементов массива Y for (int i = 0; i <= (n - 1); i = i + 1) { Y[i] = i / 2.0 + 4.0; listBox2.Items.Add(Y[i].ToString("F3")); } } private void cmdP_Click(object sender, EventArgs e) { double s, p; //Накопление суммы s = 0; for (int i = 0; i <= (n - 1); i = i + 1) { s = s + (X[i] + 5.6 * Y[i]); } p = s; label3.Text = "p= " + p.ToString("F3"); } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.59.

Рисунок 10.59 – Результаты решения задачи 10.20

224

Задача 10.21. Вычислить значения элементов одномерного массива Q(10) по формуле:

2( )xi i iq e a b k ,

где x = 2; k = 3,5; ia – элемент одномерного массива A(10); 9,...1,0i ;

ib – элемент одномерного массива B(10); 9,...1,0i ;

iq – элемент одном. массива Q(10) 9,...1,0i . Значения элементов массивов A и B задать в программном коде. Блок-схема представлена на рис. 10.60.

Способ 1. Создать консольное приложение для решения данной задачи. Программный код: using System;

namespace C34 { class Program { static void Main(string[] args) { const int n = 10; // кол-во элементов каждого массива const double x = 2.0, k = 3.5; double[] A = new double[n] {1.0, 3.0, 5.0, 7.0, 8.0, 9.0, 10.0, 11.0, 13.0, 15.0 }; double[] B = new double[n] { 2.0, 5.0, 7.0, 8.0, 9.0, 12.0, 14.0, 15.0, 17.0, 18.0 }; double[] Q = new double[n]; //Вычисление элементов массива Q и вывод массивов Console.WriteLine(" Массивы: "); Console.WriteLine(" A B Q "); for (int i = 0; i <= (n - 1); i = i + 1) { Q[i] = Math.Exp(x) * Math.Pow((A[i] - B[i]),2) + k; Console.WriteLine("{0,6:F3}\t {1,6:F3}\t {2,6:F3}\t ", A[i], B[i], Q[i]); } Console.ReadLine(); } } }

225

2( )xi i iQ e A B k

Вывод, ,i i iA B Q

Рисунок 10.60 – Блок-схема алгоритма к задаче 10.21

226

Результаты решения см. рис. 10.61.

Рисунок 10.61 – Результаты решения задачи 10.21 Способ 2. Для данной задачи создать Windows-приложение. Блок-схема обработчика событий cmdStart_Click представлена на

рис. 10.60.

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты, как показано на рис. 10.62, 10.63. На форме расположить: три метки (Label), три поля списка (ListBox),

две командных кнопки (Button).

Рисунок 10.62 – Форма к задаче 10.21

227

2. Установите значения свойств объектов в соответствии с табл. 10.12.

Таблица 10.12 – Значения свойств объектов к задаче 10.21

Объект Имя объекта по умолчанию (значение свойства Name)

Свойство Значение свойства

Форма Form1 Метка Label1 text Массив A Метка Label2 text Массив B Метка Label3 text Массив Q Поле списка ListBox1 Поле списка ListBox2 Поле списка ListBox3 Командная кнопка

Button1 Name cmdStart text Вычислить

Командная кнопка

Button2 Name cmdEnd text Завершение работы

Рисунок 10.63 – Форма к задаче 10.21

3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

228

Программный код: using System; using System.Windows.Forms;

namespace W8 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { const int n = 10; //количество элементов каждого массива const double x = 2.0, k = 3.5; double[] A = new double[n] { 1.0, 3.0, 5.0, 7.0, 8.0, 9.0, 10.0, 11.0, 13.0, 15.0 }; double[] B = new double[n] { 2.0, 5.0, 7.0, 8.0, 9.0, 12.0, 14.0, 15.0, 17.0, 18.0 }; double[] Q = new double[n]; //Вычисление элем. массива Q и вывод массивов в поля списков for (int i = 0; i <= (n - 1); i = i + 1) { Q[i] = Math.Exp(x) * Math.Pow((A[i] - B[i]), 2) + k; listBox1.Items.Add(A[i].ToString("F3")); listBox2.Items.Add(B[i].ToString("F3")); listBox3.Items.Add(Q[i].ToString("F3")); } } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.64.

229

Рисунок 10.64 – Результаты решения задачи 10.21

Задача 10.22. Вычислить значение выражения:

9

3

0i

iF c x a

,

где a = 7,5; c = 2.45; ix – элемент одномерного массива X(10); i = 0,1,…9.

Блок-схема решения задачи представлена на рис. 10.66.

Способ 1. Создать консольное приложение. Программный код: using System;

namespace C36 { class Program { static void Main(string[] args) {

230

const int n = 10; // количество элементов массива const double a = 7.5, c = 2.45; int i;

double p, F; double[] X = new double[n] { 1.5, 2.3, 3.5, 4.8, 5.8, 6.1, 7.3, 8.2, 9.3, 10.5 }; Console.WriteLine("Элементы массива: "); Console.WriteLine(); // Вывод элементов массива for (i = 0; i <= (n - 1); i = i + 1) Console.WriteLine("X[{0}]={1} ", i, X[i]); // Накопление произведения p=1; for (i = 0; i <= (n-1); i = i + 1) p=p*(X[i]+a); F = c * Math.Pow(p, (1.0 / 3.0)); Console.WriteLine(); Console.WriteLine("F= {0,7:F3}", F); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.65.

Рисунок 10.65 – Результаты решения задачи 10.22

231

Вывод iX

*( )ip p X a

3 pcF

Рисунок 10.66 – Блок-схема алгоритма к задаче 10.22

232

Способ 2. Для данной задачи создать Windows-приложение. Блок-схема обработчика событий cmdStart_Click представлена на

рис. 10.66.

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты, как показано на рис. 10.67, 10.68. На форме расположить: две метки (Label), одно поле списка

(ListBox), две командных кнопки (Button).

Рисунок 10.67 – Форма к задаче 10.22 2. Установите значения свойств объектов в соответствии с

табл.10.13.

Таблица 10.13 – Значения свойств объектов к задаче 10.22 Объект Имя объекта по умолчанию

(значение свойства Name) Свойство Значение свойства

Форма Form1 Метка Label1 text Массив X Метка Label2 Поле списка ListBox1 Командная кнопка

Button1 Name cmdStart text Вычислить

Командная кнопка

Button2 Name cmdEnd text Завершение работы

233

Рисунок 10.68 – Форма к задаче 10.22

3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.Windows.Forms; namespace W10 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { const int n = 10; // количество элементов массива

234

const double a = 7.5, c = 2.45; int i; double p, F; double[] X = new double[n] { 1.5, 2.3, 3.5, 4.8, 5.8, 6.1, 7.3, 8.2, 9.3, 10.5 }; // Вывод элементов массива for (i = 0; i <= (n - 1); i = i + 1) listBox1.Items.Add( X[i]); // Накопление суммы элементов с 4-го по 10-ый p = 1; for (i = 0; i <= (n - 1); i = i + 1) p = p * (X[i] + a); F = c * Math.Pow(p, (1.0 / 3.0)); label2.Text= "F= " + F.ToString("F3"); } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.69.

Рисунок 10.69 – Результаты решения задачи 10.22

235

10.4.2 Задачи для выполнения лабораторных работ (часть 1)

Задача 10.23. a) Создать одномерный массив A(12). Элементы массива ia

вычисляются по формуле: 11,...1,0 ;)1sin(12 iiiai

b) Вычислить сумму элементов массива с n-го по k-й (при 5; 7n k )

Вычисление суммы осуществить с помощью операторов цикла FOR, WHILE или DO.

c) Вывести элементы массива: в обратном порядке (по убыванию индекса) с k-го по n-й; четные (нечетные) по индексу или каждый n-й элемент массива.

Способ 1. Решим задачу в виде консольного приложения.

Программный код: using System; namespace C37 { class Program { static void Main(string[] args) { const int n = 12; // количество элементов массива double[] A = new double[n]; int i; double s; // Вычисление и вывод элементов массива Console.WriteLine(" Массив A: "); Console.WriteLine(); for (i = 0; i <= (n - 1); i = i + 1) { A[i] = 12 + i / Math.Sin(i + 1); Console.WriteLine("A[{0}]={1,7:F4} ", i, A[i]); } Console.WriteLine(); // Вычисление суммы элементов массива с 5-го по 7-ой Console.WriteLine("Сумма элементов массива с 5-го по 7-ой ");

236

s = 0; for (i = 5; i <= 7; i = i + 1) s = s + A[i]; Console.WriteLine("s= {0,7:F4}", s); Console.WriteLine(); //Вывод элем. массива в обратном порядке с 7-го по 5-ый Console.WriteLine("Вывод элементов массива в обратном порядке с 7-го по 5-ый" ); for (i = 7; i >= 5; i = i - 1) Console.WriteLine("A[{0}]={1,7:F4} ", i, A[i]); Console.WriteLine(); //Вывод четных по индексу элементов массива Console.WriteLine("Вывод четных по индексу элементов массива"); for (i = 2; i <= 10; i = i + 2) Console.WriteLine("A[{0}]={1,7:F4} ", i, A[i]); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.70.

Рисунок 10.70 – Результаты решения задачи 10.23

237

Варианты задач для решения задачи 10.23 представлены в табл. 10.14.

Таблица 10.14 – Варианты задач №

вар. Выражение для вычисления элементов массива Значения n и k

1 2 3

1 11,...1,0 ;3121 ia iii 3; 5n k

2 11,...1,0 ;212 iia ii 2; 4n k

3 11,...1,0 ;13231 iiiai 4; 6n k

4 11,...1,0 ;110 iia ii 5; 8n k

5 11,...1,0 ;10 iia ii 2; 5n k

6 11,...1,0 ;)2ln( 2 iiiai 3; 6n k

7 11,...1,0 ;)5ln()1ln( iiia iii 7; 9n k

8 11,...1,0 ;310 iiai 8; 11n k

9 11,...1,0 ;5 iiea ii 6; 9n k

10 11,...1,0 ;3 2 ieia ii 3; 6n k

Способ 2. Создадим Windows-приложение для решения данной задачи.

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты, как показано на рис. 10.71, 10.72. На форме расположить: одно поле списка (ListBox) две командных кнопки (Button).

238

Рисунок 10.71 – Форма к задаче 10.23

2. Установите значения свойств объектов в соответствии с табл.10.15.

Таблица 10.15 – Значения свойств объектов к задаче 10.23 Объект Имя объекта по умолчанию

(значение свойства Name) Свойство Значение свойства

Форма Form1 Поле списка ListBox1 Командная кнопка

Button1 Name cmdStart text Вычислить

Командная кнопка

Button2 Name cmdEnd text Завершение работы

Рисунок 10.72 – Форма к задаче 10.23

239

3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.Windows.Forms; namespace W11 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { const int n = 12; // количество элементов массива double[] A = new double[n]; int i; double s; // Вычисление и вывод элементов массива listBox1.Items.Add(" Массив A: "); listBox1.Items.Add(" "); for (i = 0; i <= (n - 1); i = i + 1) { A[i] = 12 + i / Math.Sin(i + 1); listBox1.Items.Add("A[" + i + "]= " + A[i].ToString("F4")); } listBox1.Items.Add(" "); // Вычисление суммы элементов массива с 5-го по 7-ой listBox1.Items.Add("Сумма элементов массива с 5-го по 7-ой"); s = 0; for (i = 5; i <= 7; i = i + 1) s = s + A[i]; listBox1.Items.Add("s= " + s.ToString("F4")); listBox1.Items.Add(" "); //Вывод элементов массива в обратном порядке с 7-го по 5-ый listBox1.Items.Add("Вывод элементов массива в обратном порядке с 7-го по 5-ый");

240

for (i = 7; i >= 5; i = i - 1) listBox1.Items.Add("A[" + i + "]= " + A[i].ToString("F4")); listBox1.Items.Add(" "); //Вывод четных по индексу элементов массива listBox1.Items.Add("Вывод четных по индексу элементов массива"); for (i = 2; i <= 10; i = i + 2) listBox1.Items.Add("A[" + i + "]= " + A[i].ToString("F4")); listBox1.Items.Add(" "); } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.73.

Рисунок 10.73 – Результаты решения задачи 10.23

241

10.4.3 Задачи для выполнения лабораторных работ (часть 2) Задача 1. Вычислить значение выражения по формуле

20

0i i

iy a b

,

где ia – элементы одномерного массива A(21); i = 0,1,…20;

ib – элементы одномерного массива B(21); i = 0,1,…20.

Задача 2. Вычислить элементы массива jz :

( )/j j jz x y p ,

где: j = 0,1,…9; = 23p .

jx – элементы одномерного массива X(10);

jy – элементы одномерного массива Y(10);

jz – элементы одномерного массива Z(10).

Задача 3. Вычислить значение выражения

9

0510

iiaY ,

где

ia – элементы одномерного массива A(10); i=0,1,…9.

Задача 4. Вычислить значение выражения 9 9

0 0i i

i iP a b

,

где

ia – элементы одномерного массива A(10); i=0,1,…9;

ib – элементы одномерного массива B(10); i=0,1,…9.

Задача 5. Вычислить сумму всех нечетных по индексу элементов массива A(30).

242

Задача 6. Вычислить значение выражения

8

1 3

0i i

id a b

,

где

ia – элементы одномерного массива A(9); i = 0,1,…8;

ib – элементы одномерного массива B(9); i = 0,1,…8.

Задача 7. Вычислить значение выражения 1 2

20

0( )j j

jZ y x

,

где

jx – элементы одномерного массива X(21); i = 0,1,…20;

jy – элементы одномерного массива Y(21); i = 0,1,…20.

Задача 8. Найти сумму первых пятнадцати элементов массива B(40).

Задача 9. Найти произведение последних 10 элементов массива X(30).

Задача 10. Вычислить значение выражения

20

5cos sini i

iR x y

,

где

ix – элементы одномерного массива X(21); i = 0,1,…20;

iy – элементы одномерного массива Y(21); i = 0,1,…20.

Задача 11. Вычислить значение выражения 15

3

2( )i

iX z a

,

где a = 4,65;

243

iz – элементы одномерного массива Z(16); i = 0,1,…15.

Задача 12. Вычислить значение выражения 8

2 2

21 ( )i

iF c y x

,

где c = 12; x = 1,5;

iy – элементы одномерного массива Y(9); i = 0,1,…8.

Задача 13. Вычислить сумму всех четных по индексу элементов массива A(20), i = 0,1,…19.

Задача 14. Вычислить сумму всех нечетных по индексу элементов массива A(15), i = 0,1,…14.

10.4.4 Задачи для выполнения лабораторных работ (часть 3) Задача 1. Написать программу, в которой вычислить среднее

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

Задача 2. Написать программу, в которой вывести с точностью до четырех знаков частное суммы и произведения ( ii aa ) всех

элементов целого массива из пяти элементов, заполненного случайными числами в диапазоне 1..9.

10.4.5 Задачи для выполнения лабораторных работ (часть 4)

Задача 1. Вычислить произведение положительных элементов массива A(15).

Задача 2. Вычислить сумму отрицательных элементов массива B(20).

Задача 3. В одномерном массиве D(20) вычислить количество элементов равных нулю и определить их индексы.

244

Задача 4. В одномерном массиве C(15) вычислить количество положительных элементов.

Задача 5. В одномерном массиве D(20) все элементы, равные нулю заменить на число 10.

Задача 6. Вычислить среднее арифметическое значение элементов одномерного массива A(15).

Задача 7. Определить максимальный элемент одномерного массива B(15) и его порядковый номер.

Задача 8. Вычислить минимальный элемент одномерного массива C(15) и его порядковый номер.

Задача 9. Определить сумму элементов массива N(20), кратных трём.

Задача 10. Переписать подряд в массив Y положительные и в массив Z отрицательные элементы массива X(20).

Задача 11. В одномерном массиве D(20) максимальный элемент заменить на число 100.

Задача 12. В одномерном массиве M(20) минимальный элемент заменить на число 200.

Задача 13. Найти максимальный и минимальный элементы одномерного массива D(20) и поменять их местами.

Задача 14. В одномерном массиве A(20) определить сумму и количество элементов, которые меньше –5.

Задача 15. В одномерном массиве B(20) найти наибольший элемент среди отрицательных чисел.

Задача 16. В одномерном массиве X(15) найти среднее арифметическое значение положительных элементов массива.

245

10.5 Двумерные массивы Цель работы: для консольного приложения: изучить операторы объявления двумерных

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

для Windows- приложения: изучить элементы управления: метка Label, кнопка Button, поле ввода TextBox, список ListBox, один компонент для представления таблицы на форме DataGridView.

10.5.1. Примеры решения задач

Задача 10.24. Создать двумерный массив A размером 46,

где 4 – количество строк, 6 – количество столбцов массива. ( ; 0,1,...3; 0,1,...5)ijA a i j .

Нижний индекс массива по 1-му и 2-му измерению = 0, верхний индекс массива по 1-му измерению =3, верхний индекс массива по 2-му измерению =5. Элементы массива вычислить по формуле:

2( 5) ( 1)ija i i j

Вычислить сумму положительных и количество отрицательных эле-ментов двумерного массива A. Для решения задачи создать консольное приложение. Блок-схема решения задачи приведена на рис. 10.75.

Программный код: using System; namespace C38 { class Program { static void Main(string[] args) { const int n=4; // количество строк массива А const int m=6; // количество столбцов массива А int i, j, k; double s; double[,] A = new double[n,m]; //Вычисление элементов массива по формуле и вывод их на экран

246

Console.WriteLine("Массив А "); for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (m - 1); j++) { A[i, j] = (double)(i * i - 5) / (i + j + 1); Console.Write( A[i, j].ToString("F3") + "\t "); } Console.WriteLine(); } Console.WriteLine(); // Вычисление суммы положительных и количества // отрицательных элементов массива s = 0; k = 0; for (i = 0; i <= (n - 1); i++) { for (j=0; j<=(m-1); j++) { if (A[i,j] >=0) s=s+A[i,j]; else k=k+1; } } Console.WriteLine("Сумма полож. элементов= {0,7:F3}",s); Console.WriteLine("Количество отриц. элементов= {0}", k); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.74.

Рисунок 10.74 – Результаты решения задачи 10.24

247

Пояснение: 1) double[,] A = new double[n,m]; Объявляется двумерный массив А из nm вещественных чисел типа double. Одновременно массив инициализируется (заполняется нулями); n и m должны быть или константами или выражениями типа, приводимого к целому.

2) A[i, j] = (double)(i * i - 5) / (i + j + 1); При делении целых чисел остаток будет отброшен, чтобы этого не произошло необходимо менять тип хотя бы одного из них.

2 51ij

iai j

Выводija

00

sk

0ija

ijs s a

Рисунок 10.75 – Блок-схема алгоритма к задаче 10.24 Задача 10.25. Создать целочисленный двумерный массив A разме-

ром 34. Элементы массива задать в программном коде. Определить

248

среднее арифметическое ее элементов и количество положительных элементов в каждой строке. Программный код: using System; namespace C40 { class Program { static void Main(string[] args) { const int n = 3, m = 4; int i, j; int[,] A = new int[n, m] {{2, -2, 8, 9}, {-4, -5, 6, -2}, {7, 0, 1, 1}}; Console.WriteLine("Массив A: "); for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= m - 1; j++) Console.Write("{0}\t", A[i, j]); Console.WriteLine(); } Console.WriteLine(); double sum = 0; //сумма всех элементов int k; //количество положит. элементов в каждой строке double sr; //среднее арифметическое всех элементов for (i = 0; i <= (n - 1); i++) { k = 0; for (j = 0; j <= m - 1; j++) { sum = sum + A[i, j]; if (A[i, j] > 0) k = k + 1; } Console.WriteLine("В строке {0} положит. элементов {1} ", i, k); } sr = sum / (n * m);

249

Console.WriteLine("Среднее арифметическое всех элементов= {0,7:F3} ",sr); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.76.

Рисунок 10.76 – Результаты решения задачи 10.25 Пояснение: int[,] A = new int[n, m] {{2, -2, 8, 9}, {-4, -5, 6, -2}, {7, 0, 1, 1}}; Объявляется двумерный массив А из nm целых чисел типа int. Одновременно массив наполняется нужными значениями. В данном случае когда задан список инициализации n и m должны быть только константами.

Задача 10.26. а) Создать двумерный массив A размером 46,

( ; 0,1,...3; 0,1,...5)ijA a i j

Массив содержит данные типа double. Элементы массива задать в программном коде.

б) Получить одномерный массив (4)SA , численные значения элементов равны среднему арифметическому элементов строк. Вывести на экран одномерный массив (4)SA . Вычислить произведение элементов

одномерного массива (4)SA .

250

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

Для решения задачи создать консольное приложение.

Программный код: using System;

namespace C39 { class Program { static void Main(string[] args) { const int n = 4; // количество строк массива А const int m = 6; // количество столбцов массива А int i, j; double s, p; double[,] A = new double[n,m] {{1,2,3,4,5,6}, {7,8,9,10,11,12}, {13,14,15,16,17,18}, {19,20,21,22,23,24}}; double[] SA = new double[n]; // Вывод элементов массива А на экран Console.WriteLine(" Массив А: "); for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (m - 1); j++) Console.Write("{0,5:F2}\t", A[i, j]); Console.WriteLine(); } Console.WriteLine(); //Создание и вывод одномерн. массива, элементы которого равны //среднему арифметическому элементов строк двумерн. массива А Console.WriteLine(" Массив CA: "); for (i = 0; i <= (n - 1); i++) { s = 0; for (j = 0; j <= (m - 1); j++) s = s + A[i, j];

251

// Вычисление элементов одномерного массива SA[i] = s / m; // Вывод элементов одномерного массива Console.WriteLine("SA[{0}]= {1,6:F2}", i, SA[i]); } Console.WriteLine(); //Вычисление произведения элементов одномерного массива p = 1; for (i = 0; i<=(n-1); i++) p = p * SA[i]; Console.WriteLine("Произведение элементов одном. массива = {0,7:F3}", p); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.77.

Рисунок 10.77 – Результаты решения задачи 10.26 Задача 10.27. Создать квадратную матрицу A размером n n,

)1,...(1,0 );1...(1,0 ;( njniaA ij .

Вещественные элементы матрицы А задаются при помощи генератора случайных чисел.

Получить новую матрицу B размером nn. Новая матрица будет рав-на матрице A, у которой надо заменить элементы нечетных строк на заданное число X. Для решения задачи создать консольное приложение.

252

Программный код: using System;

namespace C41 { class Program { static void Main(string[] args) { const int n = 5; // количество строк и столбцов матрицы const double x = 7; int i, j; double[,] A = new double[n, n]; double[,] B = new double[n, n]; Random rnd = new Random(); // Заполнение матрицы А for (i=0; i<=(n-1); i++) { for (j=0; j<=(n-1); j++) A[i,j] = rnd.NextDouble()*10+7; } // Вывод элементов исходной матрицы А Console.WriteLine(" Матрица A: "); for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (n - 1); j++) Console.Write("{0,5:F3}\t", A[i, j]); Console.WriteLine(); } Console.WriteLine(); // Вычисление элементов матрицы В for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (n - 1); j++) if (i % 2 == 0) B[i, j] = A[i, j]; else B[i, j] = x; } Console.WriteLine();

253

// Вывод новой матрицы В Console.WriteLine(" Матрица В: "); for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (n - 1); j++) Console.Write("{0,5:F3}\t", B[i, j]); Console.WriteLine(); } Console.ReadLine(); } } }

Результаты расчета см. рис. 10.78.

Рисунок 10.78 – Результаты решения задачи 10.27

Пояснение:

if (i % 2 == 0) B[i, j] = A[i, j]; else B[i, j] = x;

Если остаток от деления номера строки равен нулю (т.е. строка четная) элементу матрицы В присваивается значение элемента матрицы А, иначе элементу матрицы В присваивается значение x.

Задача 10.28. Создать двумерный массив A размером 45,

( ; 0,1,...3; 0,1,...4)ijA a i j

254

Элементы массива вычислить по формуле: 2 3 5ija i j

Вычислить произведение элементов каждого столбца матрицы. Результат получить в виде вектора D, т.е. вычислить

3

0j ij

id a

, где 0,1,...4j

Для решения задачи создать Windows- приложение.

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты (см. рис. 10.79, 10.80). На форме расположить: четыре метки (Label); два текстовых поля (TextBox); два поля списка (ListBox); две командных кнопки (Button).

Рисунок 10.79 – Форма к задаче 10.28

2. Установите значения свойств объектов в соответствии с

табл. 10.16.

255

Таблица 10.16 – Значения свойств объектов к задаче 10.28 Объект Имя объекта по умолчанию

(значение свойства Name) Свойство Значение свойства

Форма Form1 Метка Label1 text Количество строк Метка Label2 text Количество столбцов Метка Label3 text Матрица А Метка Label4 text Массив D Текстовое поле TextBox1 Name txtN

TextAlign Center Текстовое поле TextBox2 Name txtM

TextAlign Center Поле списка ListBox1 Поле списка ListBox2 Командная кнопка

Button1 Name cmdStart text Вычислить

Командная кнопка

Button2 Name cmdEnd text Завершение работы

Рисунок 10.80 – Форма к задаче 10.28 3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

256

Программный код: using System; using System.Windows.Forms; namespace W12 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { int n; // количество строк матрицы А int m; // количество столбцов массива D int i, j; double p; string z; n = Convert.ToInt32(txtN.Text); m = Convert.ToInt32(txtM.Text); //Объявление массивов double[,] A = new double[n, m]; double[] D = new double[m]; // Вычисление и вывод элементов массива А в поле списка listBox // z- строка из элементов строки массива А z = " "; Console.WriteLine(" Массив А "); for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (m - 1); j++) { A[i, j] = (2 * i + 3 * j + 5); z = z + A[i,j].ToString("F2") + " "; } listBox1.Items.Add(z); z = " "; } // Вычисление произведения элементов столбцов массива А, // вывод элементов массива P в поле списка listBox2

257

for (j = 0; j <= (m-1); j++) { p = 1; for (i = 0; i <= (n-1); i++) p = p * A[i, j]; D[j] = p; listBox2.Items.Add(D[j].ToString("F2")); } } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.81.

Рисунок 10.81 – Результаты решения задачи 10.28

Задача 10.29. Форматированный ввод-вывод двумерного массива. Создать двумерный массив A размером 34,

( ; 0,1,..2; 0,1,..3)ijA a i j

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

258

Способ 1. Элементы матрицы вывести на компонент DataGridView. Этот компонент служит для представления таблицы (по сути двумерного массива) на форме.

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты (см. рис. 10.82, 10.83). На форме расположить: три метки (Label); два текстовых поля (TextBox); один компонент для представления таблицы на форме

(DataGridView); две командных кнопки (Button).

Рисунок 10.82 – Форма к задаче 10.29

2. Установите значения свойств объектов в соответствии с

табл. 10.17. Таблица 10.17 – Значения свойств объектов к задаче 10.29 Объект Имя объекта по

умолчанию (значение свойства Name)

Свойство Значение свойства

1 2 3 4 Форма Form1 Метка Label1 text Количество строк n= Метка Label2 text Количество столбцов m=

259

Окончание таблицы 10.17 1 2 3 4

Метка Label3 text Текстовое поле TextBox1 Name txtn Текстовое поле TextBox2 Name txtm Компонент для представления таблицы на форме

DataGridView1

Командная кнопка Button1 Name cmdStart text Вычислить

Командная кнопка Button2 Name cmdEnd text Завершение работы

Рисунок 10.83 – Форма к задаче 10.29 3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.Drawing; using System.Windows.Forms; namespace W12d { public partial class Form1 : Form {

260

public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { int n; // количество строк матрицы int m; // количество столбцов матрицы int nn = 0; // количество положительных элементов float summ = 0; // сумма положительных элементов float sr; n = Convert.ToInt32(txtn.Text); m = Convert.ToInt32(txtm.Text); // Объявление массива int[,] A = new int[n, m]; Random rnd = new Random(); //Заполняем массив случайными значениями for (int i = 0; i <= n - 1; ++i) { for (int j = 0; j <= m - 1; ++j) { A[i, j] = rnd.Next(-20, 20); } } //устанавливаем количество строк и столбцов таблицы dataGridView1.RowCount = n; dataGridView1.ColumnCount = m; //два цикла перебирают все элементы таблицы for (int i = 0; i <= n - 1; i++) { for (int j = 0; j <= m - 1; j++) { //заполняем ячейки таблицы элементами массива dataGridView1.Rows[i].Cells[j].Value = A[i, j]; } } //устанавливаем ширину ячейки таблицы for (int j = 0; j <= m - 1; j++) dataGridView1.Columns[j].Width = 50; //подсчитываем сумму всех положительных элементов

261

for (int i = 0; i <= n - 1; ++i) { for (int j = 0; j <= m - 1; ++j) { if (A[i, j] > 0) { summ = summ + A[i, j]; //увеличиваем на 1 кол-во просуммированных элементов nn = nn + 1; } } } //Рассчитываем среднее арифметическое и выводим на метку sr = summ / nn; label3.Text = "Среднее арифметическое = " + sr; } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис.10.84.

Рисунок 10.84 – Результаты решения задачи 10.29

Способ 2. Элементы матрицы задать при помощи компонента DataGridView (компонент служит для представления таблицы на форме).

262

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты (см. рис. 10.85, 10.86). На форме расположить: три метки (Label); два текстовых поля

(TextBox); один компонент для представления таблицы на форме (DataGridView); три командных кнопки (Button).

Рисунок 10.85 – Форма к задаче 10.29 2. Установите значения свойств объектов в соответствии с

табл. 10.18. Таблица 10.18 – Значения свойств объектов к задаче 10.29 Объект Имя объекта по

умолчанию (значение свойства Name)

Свойство Значение свойства

1 2 3 4 Форма Form1 Метка Label1 text Количество строк n= Метка Label2 text Количество столбцов m= Метка Label3 text Текстовое поле TextBox1 Name txtn Текстовое поле TextBox2 Name txtm Компонент для представления таблицы на форме

DataGridView1

263

Окончание таблицы 10.18 1 2 3 4

Командная кнопка Button1 Name cmdMas text Ввод массива

Командная кнопка Button2 Name cmdStart text Вычислить

Командная кнопка Button2 Name cmdEnd text Завершение работы

Рисунок 10.86 – Форма к задаче 10.29

3. Программирование. Напишите обработчики событий: щелчок мышью по командной

кнопке <Ввод массива>, щелчок мышью по командной кнопке <Вычислить>, щелчок мышью по командной кнопке <Завершение работы>. Программный код: using System; using System.Drawing; using System.Windows.Forms; namespace W12c { public partial class Form1 : Form { public Form1() { InitializeComponent(); }

264

int n; // количество строк матрицы int m; // количество столбцов матрицы int[,] A; private void cmdMas_Click(object sender, EventArgs e) { n = Convert.ToInt32(txtn.Text); m = Convert.ToInt32(txtm.Text); //устанавливаем количество строк и столбцов таблицы dataGridView1.RowCount = n; dataGridView1.ColumnCount = m; for (int j = 0; j <= m - 1; j++) { //устанавливаем ширину ячейки таблицы dataGridView1.Columns[j].Width = 50; } } private void cmdStart_Click(object sender, EventArgs e) { int nn = 0; // количество положительных элементов float summ = 0; // сумма элементов float sr; // Объявление массива A = new int[n, m]; //два цикла перебирают все элементы таблицы for (int i = 0; i <= n - 1; ++i) { for (int j = 0; j <= m - 1; ++j) { //заполняем элементы массива, данные берём из ячеек таблицы A[i, j]= Convert.ToInt32(dataGridView1.Rows[i].Cells[j].Value); } } //подсчитываем сумму всех положительных элементов for (int i = 0; i <= n - 1; ++i) { for (int j = 0; j <= m - 1; ++j) { if (A[i, j] > 0) {

265

summ = summ + A[i, j]; //увеличиваем на 1 кол-во просуммированных элементов nn = nn + 1; } } } //Рассчитываем среднее арифметическое и выводим на метку sr = summ / nn; label3.Text = "Среднее арифметическое = " + sr; } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис.10.87.

Рисунок 10.87 – Результаты решения задачи 10.29 10.5.2. Задачи для выполнения лабораторных работ (часть 1)

Задача 1 Создать двумерный массив A размером 46,

( ; 0,1,...3; 0,1,...5)ijA a i j

Элементы массива рассчитать по формуле:

266

2( 5)( 3)ij

iai j

.

Вычислить сумму положительных и произведение отрицательных элементов массива.

Задача 2 Создать двумерный массив A размером 48, ( ; 0,1,...3; 0,1,...7)ijA a i j

Элементы массива рассчитать по формуле: 23 35

1,2 2ijja

i j

.

Вычислить количество положительных и количество отрицательных элементов массива.

Задача 3 Создать двумерный массив A размером 56, ( ; 0,1,...4; 0,1,...5)ijA a i j

Элементы массива рассчитать по формуле:

22,5 1iji jai j

.

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

Задача 4 Создать двумерный массив A размером 84, ( ; 0,1,...7; 0,1,...3)ijA a i j

Элементы массива рассчитать по формуле: 3 25 1,8ija i j .

Определить сумму элементов каждой строки матрицы.

Задача 5 Создать двумерный массив A размером 75, ( ; 0,1,...6; 0,1,...4)ijA a i j

Элементы массива рассчитать по формуле: 22 15i

ija j .

Определить произведение элементов каждой строки матрицы.

267

Задача 6 Создать двумерный массив A размером 105, ( ; 0,1,...9; 0,1,...4)ijA a i j

Элементы массива рассчитать по формуле: 2 8 35ija j i .

Определить сумму элементов каждого столбца матрицы.

Задача 7 Создать двумерный массив A размером 96, ( ; 0,1,...8; 0,1,...5)ijA a i j

Элементы массива рассчитать по формуле: 2 29 50ija i j .

Определить произведение элементов каждого столбца матрицы.

Задача 8 Создать двумерный массив A размером 3 4.

( ; 0,1,...2; 0,1,...3)ijA a i j .

Элементы массива задать в программном коде.

12,8 40 34,8 56102 78,4 140 112178 40 65 95,4

A

Определить сумму элементов по периметру матрицы.

Задача 9 Создать двумерный массив A размером 47, ( ; 0,1,...3; 0,1,...6)ijA a i j

Элементы массива рассчитать по формуле:

10 2i jija .

Найти максимальный элемент массива и его индексы.

Задача 10 Создать двумерный массив A размером 85, ( ; 0,1,...7; 0,1,...4)ijA a i j

Элементы массива рассчитать по формуле: 220 (0,5 )ija i j .

268

Найти минимальный элемент массива и его индексы.

Задача 11 Создать двумерный массив A размером 66, ( ; 0,1,...5; 0,1,...5)ijA a i j

Элементы массива рассчитать по формуле: 3 2 15ija i j .

Найти сумму всех элементов, расположенных на главной диагонали матрицы.

Задача 12 Создать двумерный массив A размером 55, ( ; 0,1,...4; 0,1,...4)ijA a i j

Элементы массива рассчитать по формуле: 1

7 1ijja

i j

.

Найти максимальный элемент на главной диагонали матрицы.

Задача 13 Создать двумерный массив A размером 88, ( ; 0,1,...7; 0,1,...7)ijA a i j

Элементы массива рассчитать по формуле:

2 3 jija i .

Найти сумму элементов, расположенных выше главной диагонали.

Задача 14 Создать двумерный массив A размером 4 4.

( ; 0,1,...3; 0,1,...3)ijA a i j .

Элементы массива задать в программном коде.

1 7 9 128 21 7 11

15 42 18 202 12 31 14

A

Найти сумму элементов, расположенных ниже главной диагонали.

269

Задача 15 Создать двумерный массив A размером 58, ( ; 0,1,...4; 0,1,...7)ijA a i j

Элементы массива рассчитать по формуле: 2 25 30ija i j .

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

; 0,1,..7; 0,1,...4ij jib a i j

10.5.3. Задачи для выполнения лабораторных работ (часть 2)

Задача 1 Создать двумерный массив A размером 3 5.

( ; 0,1,...2; 0,1,...4)ijA a i j .

Элементы массива задать в программном коде. 2 7,5 12 45 34

70 85,5 56 92 102115 78 74 100 80

A

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

Задача 2 Создать двумерный массив A размером 3 6. ( ; 0,1,...2; 0,1,...5)ijA a i j .

Элементы массива задать в программном коде. 2 5,4 9 12 15 21,345 51,25 80 85,3 91 102,7

147 125 13,2 15,8 21 34A

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

Задача 3 Создать двумерный массив A размером 3 6. ( ; 0,1,...2; 0,1,...5)ijA a i j .

Элементы массива задать в программном коде.

270

1 3 5,4 8,1 10,3 157 21 15 23 27,5 3454 23,7 100 45,8 22,5 105

A

Вычислить среднее арифметическое значение положительных элементов массива.

Задача 4 Создать двумерный массив A размером 3 4. ( ; 0,1,...2; 0,1,...3)ijA a i j .

Элементы массива задать в программном коде. 3 5,2 8,4 157 21 18,5 21,7

28,3 20,4 69,5 98A

Вычислить среднее арифметическое значение отрицательных элементов массива.

Задача 5 Создать двумерный массив A размером 4 5. ( ; 0,1,...3; 0,1,...4)ijA a i j .

Элементы массива задать в программном коде. 1 2 1 4 542 10 45 31 142 5 1 3 1

80 18 22 35 40

A

Определить количество строк, произведение элементов которых меньше 40.

Задача 6 Создать двумерный массив A размером 4 5. ( ; 0,1,...3; 0,1,...4)ijA a i j .

Элементы массива задать в программном коде. 1 2 1 4 5

150 10 45 31 142 5 1 3 1

80 18 220 35 40

A

Определить количество столбцов, сумма элементов которых больше 200.

271

Задача 7 Создать двумерный массив A размером 4 3. ( ; 0,1,...3; 0,1,...2)ijA a i j .

Элементы массива задать в программном коде. 2 15 8

15 34,8 120 2 15

45,4 15 3

A

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

Задача 8 Создать двумерный массив A размером 3 8. ( ; 0,1,...2; 0,1,...7)ijA a i j .

Элементы массива задать в программном коде. 1 4 8 12 14 17 19 2123 12 14 17 18 19 24 2552 54 58 61 67 100 80 95

A

Определить столбцы, которые содержат только положительные элементы. Выпечатать эти столбцы и найти произведение элементов этих столбцов.

Задача 9 Создать двумерный массив A размером 4 6. ( ; 0,1,...3; 0,1,...5)ijA a i j .

Элементы массива задать в программном коде. 2 5 7,3 9,2 10,5 15

17,3 21 25 27,1 31,7 4953,3 55 57,3 62 75 8091 95,2 100 102,5 127 140

A

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

Задача 10 Создать двумерный массив A размером 4 5. ( ; 0,1,...3; 0,1,...4)ijA a i j .

Элементы массива задать в программном коде.

272

2 7 12 8 214 10 15 31 145 9 11 21 173 18 22 35 40

A

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

Задача 11 Создать двумерный массив A размером 4 6. ( ; 0,1,...3; 0,1,...5)ijA a i j .

Элементы массива задать в программном коде. 1 4 12,7 15 19 23,427 0 15 0 107 5067,5 170 125 18 45 805 9 12 0 26 30

A

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

Задача 12 Создать двумерный массив A размером 4 5. ( ; 0,1,...3; 0,1,...4)ijA a i j .

Элементы массива задать в программном коде. 5,2 20 25 0 4015 0 20 45,8 67,599 20 105 0 157,5

145 117 135 20 70

A

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

Задача 13 Создать двумерный массив A размером 4 5. ( ; 0,1,...3; 0,1,...4)ijA a i j .

Элементы массива задать в программном коде. 3 5 11 8 7

42 10 45 31 145 2 12 3 14

80 18 22 35 40

A

273

Определить количество строк, среднее арифметическое элементов которых меньше 15.

Задача 14 Создать двумерный массив A размером 4 4. ( ; 0,1,...3; 0,1,...3)ijA a i j .

Элементы массива задать в программном коде. 1 12 2 215 20 4 329 25 6 287 30 8 45

A

Определить количество столбцов, среднее арифметическое элементов которых меньше 10.

Задача 15 Создать двумерный массив A размером 4 4. ( ; 0,1,...3; 0,1,...3)ijA a i j .

Элементы массива задать в программном коде. 1 15 2 275 22 1 302 25 7 253 30 4 47

A

Определить количество столбцов, произведение элементов которых меньше 60.

10.5.4. Задачи для выполнения лабораторных работ (часть 3)

Задача 1. Написать программу, в которой создать и заполнить

случайными значениями в диапазоне 0..9 квадратную матрицу размером n=4, вычислить и вывести на консоль среднее арифметическое элементов, расположенных

а) выше (или ниже) главной диагонали; б) выше (или ниже) побочной диагонали.

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

274

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

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

10.6 Методы

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

метода, вызов метода.

для Windows- приложения: изучить элементы управления: метка Label, кнопка Button, поле ввода TextBox, список ListBox.

10.6.1 Примеры решения задач

Методы, возвращающие одно значение.

Передача параметров по значению.

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

Задача 10.30. Написать метод для вычисления среднего арифметического трех действительных чисел.

Программный код: using System; namespace C50 { class Program { static double Aver(double x, double y, double z) { return (x + y + z) / 3; }

275

static void Main(string[] args) { double res, x1, x2, x3; x1 = 4.5; x2 = 5.6; x3 = 7.8; res = Aver(x1, x2, x3); Console.WriteLine(" x1 = {0,5:F2}; x2 = {1,5:F2}; x3 ={2,5:F3}", x1,x2,x3); Console.WriteLine(" Среднее арифметическое трех чисел = {0,6:F3}", res ); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.88.

Рисунок 10.88 – Результаты решения задачи 10.30 Пояснение: static double Aver(double x, double y, double z) – это

заголовок метода; Aver – имя метода; (double x, double y, double z) – параметры -значения. Фактически вычисление среднего арифметического значения из трех

заданных чисел осуществляется из тела главного метода Main с помощью вызова метода Aver:

res = Aver(x1, x2, x3); При вызове этого метода передаются в качестве аргументов (фактических

параметров) переменные x1, x2, x3 типа double. Соответственно, в определении метода Aver идентификаторы x,y и z называются формальными параметрами.

Задача 10.31. Написать метод, который вычисляет объем цилиндра

hrV 2 .

276

Программный код: using System; namespace C52 { class Program { // Объем цилиндра static double ps(double h, double r) { return Math.PI * r * r * h; } static void Main(string[] args) { double h, r; // высота и радиус основания цилиндра double v; // объем цилиндра Console.WriteLine(" Вычисление объема цилиндра \n "); Console.Write(" Введите высоту цилиндра h= "); h = Convert.ToDouble(Console.ReadLine()); Console.Write(" Введите радиус основания цилиндра r= "); r = Convert.ToDouble(Console.ReadLine()); Console.WriteLine(); v = ps(h, r); Console.WriteLine(" Объем цилиндра v= {0,7:F3}", v); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.89.

Рисунок 10.89 – Результаты решения задачи 10.31 Пояснение: Фактически вычисление объема цилиндра осуществляется из тела

главного метода Main с помощью вызова метода ps(): v = ps(h, r);

277

При вызове этого метода передаются в качестве фактических параметров переменные h и r типа double. Соответственно, в определении метода ps:

static double ps(double h, double r) идентификаторы h и r называются формальными параметрами.

Задача 10.32. Написать метод пересчета температуры из градусов

Фаренгейта в градусы Цельсия ( )32(95 FС ) и программу, использующую этот метод, которая выводит на экран таблицу соответствия температур в шкалах Фаренгейта и Цельсия. Программный код: using System; namespace C51 { class Program { // пересчитывает температуру // из градусов Фаренгейта в градусы Цельсия static double ps(double f) { double c; c = (double)5 / 9 * (f - 32); return (c); } static void Main(string[] args) { double f; // температура в градусах Фаренгейта double c; // температура в градусах Цельсия double f1, f2; // диапазон изменения температуры double df; // шаг изменения температуры f1 = 32.0; f2 = 50.0; df = 2.0; Console.WriteLine("----------------"); Console.WriteLine(" F C "); Console.WriteLine("----------------"); for (f = f1; f <= f2; f = f + df) { c = ps(f); Console.WriteLine("{0,5:F1} {1,5:F1}", f, c); }

278

Console.ReadLine(); } } }

Результаты расчета см. рис. 10.90.

Рисунок 10.90 – Результаты решения задачи 10.32

Задача 10.33. Создать консольное приложение для вычисления

выражения: 2 2 2 2 2 2 2 2 2sin sin sin21,87; 35,13; 9,87.

W x y xy y z yz z x xzпри x y z

В виде метода оформим выражение вида 2 2 2sina b ab .

Программный код: using System; namespace C59 { class Program { static double ps(double a, double b) { return Math.Sqrt(a*a+b*b+ Math.Pow(Math.Sin(a*b),2)); } static void Main(string[] args) { double x, y, z, W; x = 21.87; y = 35.13; z = 9.87; W = ps(x, y) + ps(y, z) + ps(z, x);

279

Console.WriteLine(" x= {0,5:F2}; y= {1,5:F2}; z={2,5:F2}", x,y,z); Console.WriteLine(" W= {0:F3}", W); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.91.

Рисунок 10.91 – Результаты решения задачи 10.33 Задача 10.34. Написать метод вычисления факториала числа K!. Способ 1. Создать консольное приложение.

Программный код: using System; namespace C53 { class Program { static double factorial(int K) { double p=1; for (int i = 2; i <= K; i++) p = p * i; return(p); } static void Main(string[] args) { int N; double f; Console.Write(" Введите N= "); N = Convert.ToInt32(Console.ReadLine()); f = factorial(N); Console.WriteLine(" {0}!={1} ", N, f);

280

Console.ReadLine(); } } }

Результаты расчета см. рис. 10.92.

Рисунок 10.92 – Результаты решения задачи 10.34 Способ 2. Создать Windows-приложение.

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты, как показано на рис. 10.93, 10.94. На форме расположить: три метки (Label); одно текстовое поле (TextBox); две командных кнопки (Button).

Рисунок 10.93 – Форма к задаче 10.34 2. Установите значения свойств объектов в соответствии с

табл. 10.19.

281

Таблица 10.19 – Значения свойств объектов к задаче 10.34 Объект Имя объекта по

умолчанию (значение свойства Name)

Свойство Значение свойства

Форма Form1 Метка Label1 text Вычисление факториала

числа Метка Label2 text Введите число Метка Label3 Текстовое поле TextBox1 Name txtN Командная кнопка

Button1 Name cmdStart text Вычислить

Командная кнопка

Button2 Name cmdEnd text Завершение работы

Рисунок 10.94 – Форма к задаче 10.34

3. Программирование. Напишите обработчики событий щелчок мышью по командной кноп-

ке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.Windows.Forms; namespace W13 { public partial class Form1 : Form {

282

public Form1() { InitializeComponent(); } static double factorial(int K) { double p = 1; for (int i = 2; i <= K; i++) p = p * i; return (p); } private void cmdStart_Click(object sender, EventArgs e) { int N; double f; Console.Write(" Введите N= "); N = Convert.ToInt32(txtN.Text); f = factorial(N); label3.Text = N + "!= " + f; } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.95.

Рисунок 10.95 – Результаты решения задачи 10.34

283

Задача 10.35. Написать метод для расчета суммы целых чисел от M до N. Программный код: using System;

namespace C57 { class Program { static int MySum(int M, int N) { int i, sum; sum = 0; for (i = M; i <= N; i++) sum = sum + i; return sum; } static void Main(string[] args) { int M, N, S; Console.Write(" Введите M= "); M = Convert.ToInt32(Console.ReadLine()); Console.Write(" Введите N= "); N = Convert.ToInt32(Console.ReadLine()); S = MySum(M, N); Console.WriteLine(" Сумма = {0}", S); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.96.

Рисунок 10.96 – Результаты решения задачи 10.35

284

Задача 10.36. Написать метод, который возвращает среднее арифметическое элементов массива Программный код: using System;

namespace C58 { class Program { static double ps(int n, int[] A) { int i; double sum = 0; for ( i = 0; i <= (n - 1); i++) sum = sum + A[i]; return sum / n; }

static void Main(string[] args) { const int n=15; // количество элементов массива double sr; // среднее арифметическое элементов массива int[] A = new int[n] { 1, 3, 6, 7, 8, 9, 10, 12, 15, 17, 20, 22, 25, 28, 30 }; Console.WriteLine(" Массив А "); for (int i = 0; i <= (n - 1); i++) Console.WriteLine(" A[{0}]={1}", i, A[i]); sr = ps(n, A); Console.WriteLine("Среднее арифметическое = {0} ", sr); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.97.

285

Рисунок 10.97 – Результаты решения задачи 10.36 Задача 10.37. 1. Создать двумерный массив A размером 45,

( ; 0,1,...3; 0,1,...4)ijA a i j

Элементы массива вычислить по формуле:

220 0,5 1ija i j

2. Вычислить сумму элементов массива, причем вычисление суммы элементов строк массива оформить в виде метода.

3. Откорректировать программу для случая, когда в виде метода требуется оформить вычисление суммы элементов столбцов (выполнить самостоятельно).

Программный код: using System; namespace C62 { class Program { static double ps(int i, int m, double[,] B) {

286

// Функция накапливает сумму элементов по данной строке int j; double c; c = 0; for (j = 0; j <= (m - 1); j++) c = c + B[i, j]; return c; } static void Main(string[] args) { const int n = 4; // количество строк const int m = 5; // количество столбцов double[,] A = new double[n, m]; int i, j; double s; // Вычисление и вывод элементов масива Console.WriteLine(" Массив А: "); for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (m - 1); j++) { A[i, j] = 20 * i - Math.Pow((0.5 * j), 2) + 1; Console.Write("{0,5:F2} \t", A[i, j] ); } Console.WriteLine(); } Console.WriteLine(); s = 0; for (i = 0; i <= (n - 1); i++) s = s + ps(i, m, A); Console.WriteLine("Сумма элементов массива= {0,5:F2}", s); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.98.

287

Рисунок 10.98 – Результаты решения задачи 10.37 Задача 10.38. Вычислить выражение:

5 8 10

2 4 3

1 1 01,78 5,4 0,1 1,25 8,2 17,02i i i

i i iF a a a

,

где

ia – элементы одномерного массива A(12); i = 0,1,…11.

Вычисление суммы вида 2

3

11 2

nk

ii n

k a k

оформить в виде метода.

Создать консольное приложение. Блок- схема решения задачи представлена на рис. 10.100.

Программный код: using System;

namespace C60 { class Program { static double ps(int n1, int n2, double k1, double k2, double k3, double [] A) { int i; double s=0; for ( i=n1; i<=n2; i++) s= s + Math.Pow((k1*A[i]+k2),k3); return s; }

288

static void Main(string[] args) { const int n = 12; // Количество элементов масива double[] A = new double[n]; int i; double r1, r2, r3, f; Console.WriteLine(" Массив A: "); for (i = 0; i <= (n - 1); i++) { A[i] = (i + 2) / 7.0; Console.WriteLine("A[{0}]={1:F3} ", i, A[i]); } r1 = ps(1, 5, 1.78, 5.4, 2, A); r2 = ps(1, 8, 0.1, 1.25, 4, A); r3 = ps(0, 10, 8.2, -17.02, 3, A); f = r1 + r2 - r3; Console.WriteLine(); Console.WriteLine(" f= {0:F3}" , f ); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.99.

Рисунок 10.99 – Результаты решения задачи 10.38

289

72 iAi

Вывод iA

321 ki kAkss

метод Main() (для консол. прил.) метод ps() обработчик события cmdStart_Click (для Windows-прил.)

Рисунок 10.100 – Блок-схема алгоритма к задаче 10.38

290

Задача 10.39. Вычислить

7

1

9

3

11

034,84

i i iiii zyxF ,

где

ix – элементы одномерного массива X(8); i = 0,1,…7.

iy – элементы одномерного массива Y(10); i = 0,1,…9;

iz – элементы одномерного массива Z(12); i = 0,1,…11.

Элементы массивов вычислить по формулам:

13i

ix ;

2 57i

iy ; 2

81i

izi

.

В виде метода оформить вычисление произведения вида 2

11

n

ii n

F k a

.

Создать консольное приложение для решения данной задачи. Программный код: using System;

namespace C66 { class Program { static double ps(int n1, int n2, double k1, double[] A) { int i; double p=1; for (i = n1; i <= n2; i++) p = p * A[i]; p = k1 * p; return p; }

291

static void Main(string[] args) { double[] X = new double[8]; double[] Y = new double[10]; double[] Z = new double[12]; double F, r1, r2, r3; int i; Console.WriteLine(" Массив X: "); for (i = 0; i <= 7; i++) { X[i] = (i + 1) / 3.0; Console.Write("{0,5:F2} ", X[i]); } Console.WriteLine("\n"); Console.WriteLine(" Массив Y: "); for (i = 0; i <= 9; i++) { Y[i] = (i * i + 5.0) / 7.0; Console.Write("{0,5:F2} ", Y[i]); } Console.WriteLine("\n"); Console.WriteLine(" Массив Z: "); for (i = 0; i <= 11; i++) { Z[i] = (i + 8.0) / (i * i + 1); Console.Write("{0,5:F2} ", Z[i]); } Console.WriteLine("\n"); r1= ps(1, 7, 4, X); r2= ps(3, 9, 8.34, Y); r3= ps(0, 11, 1, Z); F = r1 + r2 - r3; Console.WriteLine(" F={0,6:F3} ", F); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.101.

292

Рисунок 10.101 – Результаты решения задачи 10.39

Методы, которые изменяют значения передаваемых в него величин.

Параметры-ссылки, выходные параметры. Часто применяются методы, которые не возвращают значение (тип

void), но позволяют изменить в методе переданные параметры. Для этих целей используются параметры-ссылки (с использованием ключевого слова ref) и выходные параметры (с использованием ключевого слова out).

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

Выходные параметры позволяют получить в методе новое значение для параметра.

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

Способ 1. Использовать параметры-ссылки (описываются с помощью ключевого слова ref). Программный код: using System; namespace C63 { class Program {

293

static void ps(double radius, ref double ploshad, ref double dlina) { ploshad = Math.PI * radius * radius; dlina = 2 * Math.PI * radius; } static void Main(string[] args) { double r, s, L; Console.Write(" Введите радиус r= "); r = Convert.ToDouble(Console.ReadLine()); //Перед вызовом функции аргументам необходимо присвоить значения s = 1; L = 1; ps(r, ref s, ref L); Console.WriteLine("Площадь круга ={0,5:F2} \nДлина окружности ={1,5:F2}", s, L); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.102.

Рисунок 10.102 – Результаты решения задачи 10.40

Пояснение: static void ps(double radius, ref double ploshad, ref double

dlina) – это заголовок метода; В списке параметров метода имеются параметры- значения и параметры-

ссылки. Признаком параметра-ссылки является ключевое слово ref перед описанием параметра.

double radius – параметр-значение, он не может быть изменен функцией;

ref double ploshad, ref double dlina – параметры- ссылки.

294

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

Модификатор ref указывается перед объявлением параметра в самом методе и перед аргументом при вызове метода. Параметр типа ref должен быть инициализирован определённым значением до вызова метода.

При вызове метода из главного метода Main() ему передается в качестве входного параметра значение радиуса: R=5.

Способ 2. Использовать выходные параметры (описываются с помощью ключевого слова out).

Программный код: using System; namespace C63a { class Program { static void ps(double radius, out double ploshad, out double dlina) { ploshad = Math.PI * radius * radius; dlina = 2 * Math.PI * radius; } static void Main(string[] args) { double r, s, L; Console.Write(" Введите радиус r= "); r = Convert.ToDouble(Console.ReadLine()); ps(r, out s, out L); Console.WriteLine("Площадь круга ={0,5:F2} \nДлина окружности ={1,5:F2}", s, L); Console.ReadLine(); } } }

295

Результаты расчета см. рис. 10.103.

Рисунок 10.103 – Результаты решения задачи 10.40

Пояснение: Методы могут возвращать в вызывающую программу одно или несколько

значений с помощью списка аргументов. В данном случае метод ps() static void ps(double radius, out double ploshad, out double

dlina) предназначен для вычисления площади круга и длины окружности; ps – имя метода, после имени в скобках указываются параметры с нужным

типом данных Среди них есть параметры- значения и выходные параметры. Признаком выходного параметра является ключевое слово out перед описанием параметра.

double radius – параметр-значение, он не может быть изменен функцией;

out double ploshad, out double dlina – выходные параметры. Модификатор параметра out служит только для передачи значения за

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

При вызове метода из главного метода Main ему передается в качестве входного параметра значение радиуса: R=5.

Задача 10.41. Вычислить значение выражения

7 10

3

1 01,5 8,2i i

i iF x a y b

,

где 3; 7a b ;

296

ix – элементы одномерного массива X(12); i = 0,1,…11;

iy – положительные элементы одномерного массива Y(12); i = 0,1,…11.

Элементы массивов вычислить по формулам:

2 5ix i ;

4 1iy i .

В виде метода оформить вычисление суммы 2

2

11 3

nk i

i nk z k

и

расчет количества суммируемых элементов.

Способ 1. Создать консольное приложение. Блок-схема к задаче 10.41, способ 1 приведена на рис. 10.105.

Программный код: using System;

namespace С65 { class Program { static void sum(double k1, double k2, int n1, int n2, double []Z, double k3, out double s, out int q) { int i; s = 0; q = 0; for (i = n1; i <= n2; i++) { s = s + (Z[i] + k3); q = q + 1; } s = k1 * Math.Pow(s, (1 / k2)); } static void Main(string[] args) { const int n = 12; // Количество элементов массива

297

const double a = 3.0, b = 7.0; double[] X = new double[n]; double[] Y = new double[n]; double F, s1, s2; int i, q1, q2; Console.WriteLine(" Массив X: "); for (i = 0; i <= (n - 1); i++) { X[i] = i / 2.0 + 5; Console.Write("{0,5:F2} ", X[i]); } Console.WriteLine("\n"); Console.WriteLine(" Массив Y: "); for (i = 0; i <= (n - 1); i++) { Y[i] = i / 4.0 + 1; Console.Write("{0,5:F2} ", Y[i]); } Console.WriteLine("\n"); sum(1.5, 3, 1, 7, X, a, out s1, out q1); sum(8.2, 2, 0, 10, Y, b, out s2, out q2); F = s1 - s2; Console.WriteLine("F={0,6:F3} q1={1} q2={2}", F, q1, q2); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.104.

Рисунок 10.104 – Результаты решения задачи 10.41

298

2 5iX i

4 1iy i

Вывод iY

Вывод iX

4 1iY i

( 3)1

is s Z kq q

1 21 ks k s

метод Main() метод Sum()

Рисунок 10.105 – Блок-схема алгоритма к задаче 10.41, способ 1

299

Способ 2. Cоздать Windows-приложение. Блок- схема решения зада-чи представлена на рис. 10.106.

2 5ix i

4 1iy i

Вывод iy

Вывод ix

4 1iy i

( 3)is s z k

1 21 ks k s

Обработчики событий cmdMas_Click, cmdF_Click и метод Sum()

Рисунок 10.106 – Блок-схема алгоритма к задаче 10.41, способ 2

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты см. рис. 10.107, 10.108.

300

На форме расположить: три метки (Label), два поля списка (ListBox), три командных кнопки (Button).

Рисунок 10.107 – Форма к задаче 10.41

2. Установите значения свойств объектов в соответствии с

табл. 10.20. Таблица 10.20 – Значения свойств объектов к задаче 10.41

Объект Имя объекта по умолчанию (значение

свойства Name)

Свойство Значение свойства

Форма Form1 Name Form1

Метка Label1 text Массив X Метка Label2 text Массив Y Метка Label3 Поле списка ListBox1

Поле списка ListBox2

Командная кнопка

Button1 Name cmdMas text Вычисление и вывод

элементов массивов Командная кнопка

Button2 Name cmdF text Вычисление F

Командная кнопка

Button3 Name cmdEnd text Завершение работы

301

Рисунок 10.108 – Форма к задаче 10.41 3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычисление и вывод элементов массивов>, щелчок мышью по командной кнопке <Вычисление F>, щелчок мышью по командной кнопке <Завершение работы>. Программный код: using System; using System.Windows.Forms; namespace W16 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } const int n=12; // Количество элементов массива double[] X = new double[n]; double[] Y = new double[n]; const double a=3.0, b=7.0; static void sum(double k1, double k2, int n1, int n2, double[] Z, double k3, out double s, out int q) {

302

int i; s = 0; q = 0; for (i = n1; i <= n2; i++) { s = s + (Z[i] + k3); q = q + 1; } s = k1 * Math.Pow(s, (1 / k2)); } private void cmdMas_Click(object sender, EventArgs e) { int i; for (i = 0; i <= (n - 1); i++) { X[i] = i / 2.0 + 5; listBox1.Items.Add(X[i].ToString("F3")); } for (i = 0; i <= (n - 1); i++) { Y[i] = i / 4.0 + 1; listBox2.Items.Add(Y[i].ToString("F3")); } } private void cmdF_Click(object sender, EventArgs e) { double F, s1, s2; int q1, q2; sum(1.5, 3, 1, 7, X, a, out s1, out q1); sum(8.2, 2, 0, 10, Y, b, out s2, out q2); F = s1 - s2; label3.Text= "F=" + F.ToString("F3") + " q1=" +q1 + " q2=" +q2; } private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

303

Пояснение const int n=12; // Количество элементов массива double[] X = new double[n]; double[] Y = new double[n]; const double a=3.0, b=7.0;

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

Результаты расчета см. рис. 10.109.

Рисунок 10.109 – Результаты решения задачи 10.41 Задача 10.42. Вычислить значение выражения z

14

0

12

3

2 82,02,035,0i

ii

i bbz ,

где ib – элементы одномерного массива B(15); i = 0,1,…14.

В виде метода оформить вычисление произведения вида

2

3

11 2

nk

ii n

k b k

и количество перемножаемых элементов. Блок-схема

представлена на рис. 10.110.

304

1p k p

Вывод iB

3( 2)1

kip p B k

q q

метод Main() (для консол. прил.) метод ps() обработчик события cmdStart_Click (для Windows-прил.)

Рисунок 10.110 – Блок- схема алгоритма к задаче 10.42

305

Способ 1. Создать консольное приложение Программный код. using System; namespace C61a { class Program { static void ps(int n1, int n2, double k1, double k2, double k3, double[] B, out double p, out int q) { int i; p = 1; q = 0; for (i = n1; i <= n2; i++) { p = p * Math.Pow((B[i] + k2), k3); q = q + 1; } p = k1 * p; } static void Main(string[] args) { const int n = 15; // Количество элементов массива double[] B = new double[n] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 }; double z, p1, p2; int q1, q2; Console.WriteLine(" Массив B: "); for (int i = 0; i <= (n - 1); i++) Console.WriteLine(" B[{0}]={1,5:F2}", i, B[i]); Console.WriteLine(); ps(3, 12, 0.5, -3, 2, B, out p1, out q1); ps(0, 14, 0.2, 0.82, 1, B, out p2, out q2); z = p1 + p2; Console.WriteLine(" z= {0} q1={1} q2={2}", z, q1, q2); Console.ReadLine(); } } }

306

Результаты расчета см. рис. 10.111.

Рисунок 10.111 – Результаты решения задачи 10.42

Способ 2. Создать Windows-приложение. Блок-схема решения задачи приведена на рис. 10.111.

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты см. рис. 10.112, 10.113. На форме расположить: две метки (Label); одно поле списка

(ListBox); две командных кнопки (Button).

Рисунок 10.112 – Форма к задаче 10.42

307

2. Установите значения свойств объектов в соответствии с табл. 10.21.

Таблица 10.21 – Значения свойств объектов к задаче 10.42

Объект Имя объекта по умолчанию (значение

свойства Name)

Свойство Значение свойства

Форма Form1 Метка Label1 text Массив В Метка Label2 Поле списка ListBox1 Командная кнопка

Button1 Name cmdStart text Вычислить

Командная кнопка

Button2 Name cmdEnd text Завершение работы

Рисунок 10.113 – Форма к задаче 10.42 3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>. Программный код. using System; using System.Windows.Forms;

308

namespace W15 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } static void ps(int n1, int n2, double k1, double k2, double k3, double[] B, out double p, out int q) { int i; p = 1; q = 0; for (i = n1; i <= n2; i++) { p = p * Math.Pow((B[i] + k2), k3); q = q + 1; } p = k1 * p; }

private void cmdStart_Click(object sender, EventArgs e) { const int n = 15; // Количество элементов массива double[] B = new double[n] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 }; double p1, p2, z; int q1, q2; Console.WriteLine(" Массив B: "); Console.WriteLine(); for (int i = 0; i <= (n - 1); i++) listBox1.Items.Add( B[i].ToString("F2")); Console.WriteLine(); ps(3, 12, 0.5, -3, 2, B, out p1, out q1); ps(0, 14, 0.2, 0.82, 1, B, out p2, out q2); z = p1 + p2; label2.Text= "z= " + z + "\n" + "q1= " + q1 + " q2= " + q2; }

309

private void cmdEnd_Click(object sender, EventArgs e) { Close(); } } }

Результаты расчета см. рис. 10.114.

Рисунок 10.114 – Результаты решения задачи 10.42 Задача 10.43. Создать проект, в котором для выполнения

повторяющихся действий используются методы а) Организовать двумерный массив A размером 5 5 ,

( ; 0,1,...4; 0,1,...4)ijA a i j ,

элементы массива задать в программном коде. б) Получить два одномерных массива: 1(5)SS – сумма элементов

столбцов; 1(5)PS – произведение элементов строк. Вывести массивы

1SS (5) и 1PS (5) на экран. в) Найти максимальные элементы массивов 1SS (5) и 1PS (5),

индексы максимальных элементов, разность между максимальными элементами массивов 1SS (5) и 1PS (5).

г) отсортировать массивы 1SS (5) и 1PS (5)по возрастанию.

310

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

Программный код: using System;

namespace C67 { class Program { const int n = 5; // Количество элементов массива // Метод для вычисления суммы элементов столбцов матрицы static void ss(double[,] B, int j, out double s) { int i; s = 0; for (i = 0; i <= (n - 1); i++) s = s + B[i, j]; } // Метод для вычисления произведения элементов строк матрицы static void ps(double[,] B, int i, out double p) { int j; p = 1; for (j = 0; j <= (n - 1); j++) p=p*B[i, j]; } //Метод для нахождения макс. элемента одн. массива и его индекса static void MAXIM(double[] B, out double max, out int index) { int i; max=B[0]; index=0; for(i=1; i<=(n-1); i++) {

311

if (max<B[i]) { max=B[i]; index=i; } } } static void Main(string[] args) { double[] SS1 = new double[n]; double[] PS1 = new double[n]; double smax, pmax, r; int i, j, indexss, indexps; // Заполнение и вывод элементов массива double[,] A = new double[n, n] {{1.00, 5.00, -3.00, 2.00, 4.00}, {6.00, -10.00, 7.00, 8.00, 9.00}, {10.00, 9.00, 6.00, 7.00, 8.00}, {-4.00, 3.00, 1.00, -2.00, 5.00}, {3.00, 7.00, 6.00, 2.50, -3.10}}; // Вывод элементов массива Console.WriteLine("Массив A: "); for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= n - 1; j++) Console.Write("{0,5:F2}\t", A[i, j]); Console.WriteLine(); } Console.WriteLine("\n"); // Обращение к методу для получения сумм элементов столбов Console.WriteLine("Массив SS1: сумма элементов столбцов"); for (j = 0; j <= (n - 1); j++) { ss(A, j, out SS1[j]); Console.Write("{0,5:F2} ",SS1[j]); } Console.WriteLine("\n"); // Обращение к методу для получения произведения // элементов строк

312

Console.WriteLine("Массив PS1:произведение элементов строк"); for (i = 0; i <= (n - 1); i++) { ps(A, i, out PS1[i]); Console.Write("{0,5:F2} ", PS1[i]); } Console.WriteLine("\n"); // Нахождение макс. элементов массивов и их индексов MAXIM(SS1, out smax, out indexss); Console.WriteLine("Максимальный элемент в массиве SS1:"); Console.WriteLine("SS1[{0}]={1,5:F2} ", indexss, smax); Console.WriteLine(); MAXIM(PS1, out pmax, out indexps); Console.WriteLine("Максимальный элемент в массиве PS1:"); Console.WriteLine("PS1[{0}]={1,5:F2} ", indexps, pmax); Console.WriteLine(); // Определение разности между максимальными элементами r = smax - pmax; Console.WriteLine("Разность между максимальными элементами r= {0,5:F2}" , r); Console.WriteLine(); // Сортировка массива SS1 Console.WriteLine(" Отсортированный массив SS1"); Array.Sort(SS1); // Вывод элементов отсортированного массива SS1 for (i = 0; i <= (n - 1); i = i + 1) Console.Write("{0,5:F2} ", SS1[i]); Console.WriteLine("\n"); // Сортировка массива PS1 Console.WriteLine(" Отсортированный массив PS1"); Array.Sort(PS1); // Вывод элементов отсортированного массива PS1 for (i = 0; i <= (n - 1); i = i + 1) Console.Write("{0,5:F2} ", PS1[i]); Console.WriteLine(); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.115.

313

Рисунок 10.115 – Результаты решения задачи 10.43

Задача 10.44. Методы с переменным количеством аргументов.

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

Программный код: using System; namespace C118 { class Program { public static double ps(params double[] A) { double sum = 0; for (int i = 0; i <= (A.Length-1); i++) sum = sum + A[i]; return sum / A.Length; } static void Main(string[] args) { double p, z, k, s1, s2, s3;

314

p = 15.8; z = 4.5; k = 8.0; double[] b = {10.0, 20.5, 30.2, 38.0}; s1 = ps(p, z, k); s2 = ps(5.2, 15.7, 24.8, 27.0, 32.5); s3 = ps(b); Console.WriteLine("s1={0:F3} s2={1:F3} s3={2:F3}",s1,s2,s3); Console.ReadLine(); } } }

Результаты расчета см. рис.10.116

Рисунок 10.116 – Результаты решения задачи 10.44

Пояснение: Иногда требуется создать метод, в который можно передавать разное количество аргументов. Язык C# предоставляет такую возможность с помощью ключевого слова params. Параметр с ключевым словом params размещается в списке параметров последним и обозначает массив заданного типа неопределенной длины. Число элементов массива параметров будет равно числу аргументов, передаваемых методу. Количество элементов массива получают с помощью его свойства Length.

10.6.2. Задачи для выполнения лабораторных работ (часть 1) Задача 1. Несколько треугольников заданы своими сторонами.

Вывести площади этих треугольников. Нахождение площади треугольника по формуле Герона оформить как метод.

))()(( zppyppxppppS ;

zyxp ;

2ppp ;

где x, y, z – стороны треугольника (входные параметры); p и s – периметр и площадь (выходные параметры).

315

Задача 2. Написать метод, обеспечивающий решение квадратного уравнения.

Задача 3. Напишите метод, который будет менять в массиве целых

чисел все элементы, которые равны указанному значению (аргумент) на противоположное значение по знаку. Например, все элементы массива, которые равны 5, будут меняться на –5.

Задача 4. Определить значение F и выдать результат на экран, если

( 1 2)* 1 ( 1 2) * 2F K K M S S M ,

где: 1K – количество отрицательных чисел массива ( )A n , 2K – количество отрицательных чисел массива ( )B k

1S – сумма отрицательных чисел массива ( )A n , 2S – сумма отрицательных чисел массива ( )B k , 1M – максимальный элемент массива ( )A n , 2M – максимальный элемент массива ( )B k

Примечание: 1) Значения n , k , способ создания массива, тип элементов выбрать самостоятельно. 2) Для определения значений 1K , 2K , 1M , 1S , 2S , 2M разработать методы.

Задача 5. Написать метод для расчета среднего арифметического

значения элементов двумерного массива.

10.6.3. Задачи для выполнения лабораторных работ (часть 2) Написать программный код для определения значения выражения.

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

Условия задач и значения величин даны в табл.10.22.

316

Таблица 10.22 – Условия задач и значения величин №

вар. Задания

1 2 1

11 9

0 31,5 3i i

i iF m a m a

,

где 3,45m ; ia – элементы одномерного массива (12)A ; 0,1,...11i .

В виде метода оформить вычисление суммы и расчет количества суммируемых элементов.

2

9 82 2

0 22,5i i

i iF y a y b

,

где 0,25; 0,78;a b

iy – элементы одномерного массива (10)Y ; 0,1,...9i . В виде метода оформить вычисление суммы и расчет количества суммируемых элементов.

3 14 12 102 3 1 2

0 2 51,9 7 0,4i i i

i i iP b b b

,

где ib – положительные элементы одномерного массива (15)B ; 0,1,...14i .

В виде метода оформить вычисление суммы и расчет количества суммируемых элементов.

4 11 9 8

0 0 02 1,3i i i

i i iY a b c

,

где ia – элементы одномерного массива (12)A ; 0,1,...11i ;

ib – элементы одномерного массива (10)B ; 0,1,...9i ;

ic – элементы одномерного массива (9)C ; 0,1,...8i . В виде метода оформить вычисление суммы и расчет количества суммируемых элементов.

317

Продолжение таблицы 10.22 1 2

5 11 103 2

0 210,1 3i i

i iP x a x a

,

где 3;a

ix – элементы одномерного массива (12)X ; 0,1,...11i ; В виде метода оформить вычисление произведения и расчет количества перемножаемых элементов.

6 11 9 102 3 4

0 1 34,5i i i

i i iY x i x i x i

,

где ix – элементы одномерного массива (12)X ; 0,1,...11i ;

В виде метода оформить вычисление суммы и расчет количества суммируемых элементов.

7 8 7

0 20,018 0,4i i

i iY a b

,

где ia – элементы одномерного массива (9)A ; 0,1,...8i ;

ib – элементы одномерного массива (9)B ; 0,1,...8i ; В виде метода оформить вычисление произведения и расчет количества перемножаемых элементов.

8 9 7

32

0 27 2,5i i

i iY b b

,

где ib – элементы одномерного массива (10)B ; 0,1,...9i ;

В виде метода оформить вычисление произведения и расчет количества перемножаемых элементов.

9 11 9

0 312,5 3i i

i iZ b a

,

где ia – элементы одномерного массива (10)A ; 0,1,...9i ;

ib – элементы одномерного массива (12)B ; 0,1,...11i ; В виде метода оформить вычисление суммы и расчет количества суммируемых элементов.

318

Окончание таблицы 10.22 1 2

10

11 102 2

3

0 30,75 i i

i iZ x a x a

,

где 0,02a ; ix – элементы одномерного массива (12)X ; 0,1,...11i .

В виде метода оформить вычисление суммы и расчет количества суммируемых элементов.

11

14 42

10 12 2 0,5i i

i iZ Cos p Cos p

где ip – элементы oдномерного массива (16)P ; 0,1,...15i В виде метода оформить вычисление суммы и расчет количества суммируемых элементов.

12 20 18

3 1( 1) ( 3)i i

i iF b a b a

,

где 2,15b ;

ia –элементы одномерного массива (21)A ; 0,1,...20i . В виде метода оформить вычисление суммы и расчет количества суммируемых элементов.

10.7 Строки

Цель работы: изучить методы работы со строками.

10.7.1. Примеры решения задач

Задача 10.45. Операции со строками

Программный код: using System; namespace C77 { class Program {

319

static void Main(string[] args) { string s1 = "Типы данных в языке программирования C#"; string s2 = "C#"; string s3 = string.Copy(s1); string s4 = new string('-', 70); // Вывод строки s1 Console.WriteLine("Строка:\t\t" + s1); // Вывод длины строки Console.WriteLine("Длина строки:\t" + s1.Length); //Вывод строки в нижнем регистре - все строчные Console.WriteLine("Все строчные:\t" + s1.ToLower()); //Вывод строки в верхнем регистре - все прописные Console.WriteLine("Все прописные:\t" + s1.ToUpper()); // Сравнение двух строк Console.WriteLine("Сравнение:\t" + String.Equals(s1, s2)); // Строка s1 содержит подстроку s2? Console.WriteLine("s1 содержит s2? " + s1.Contains(s2)); //С какой позиции строка s2 входит в строку s1 Console.WriteLine("s2 вх. в s1 c п." + s1.IndexOf(s2)); //Все вхождения строки s2 в строке s1 заменить строкой "C++" Console.WriteLine("Замена:\t\t" +s1.Replace(s2,"C++")); //Извлекается подстрока длиной 16 символов, начиная с 20 Console.WriteLine("Подстрока:\t" +s1.Substring(20,16)); // Удаляет 23 символа, начиная с 14-го Console.WriteLine("Удаление:\t" +s1.Remove(14,23)); //В строку s1 вставляет строку "высокого уровня " по индексу 37 Console.WriteLine("Вставка:\t" + s1.Insert(37,"высокого уровня "));

320

Console.WriteLine(s4); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.117.

Рисунок 10.117 – Результаты решения задачи 10.45 Пояснение: Строки s1 и s2 инициализируются с помощью строковых

констант, строковая переменная s3 образована копией s1, но является отдельным экземпляром. Строка s4 образована набором символов. В программе производятся операции со строками.

Задача 10.46. Выпечатать строку отдельно каждый символ

Программный код: using System; namespace C73 { class Program { static void Main(string[] args) { string str = "Информатика"; int len = str.Length; for (int i = 0; i <= (len - 1); i++) { char ch=str[i]; Console.WriteLine("Символ на {0} позиции есть \t {1}", i, ch); }

321

Console.ReadLine(); } } }

Результаты расчета см. рис. 10.118.

Рисунок 10.118 – Результаты решения задачи 10.46

Задача 10.47. Поиск количества слов в предложении. Написать программу, в которой ввести строку с клавиатуры,

вычислить количество слов, разделенных пробелом (в качестве разделителя допускаются только одиночные пробелы). Результат вывести на консоль. Программный код: using System; namespace C80 { class Program { static void Main(string[] args) { Console.Write(" Введите текст: "); string s1 = Console.ReadLine(); int word = 0; int i; for (i = 0; i <= (s1.Length - 1); i++) if (s1[i] == ' ') word = word + 1; Console.WriteLine(" Количество слов: " + (word+1));

322

Console.ReadLine(); } } }

Результаты расчета см. рис. 10.119.

Рисунок 10.119 – Результаты решения задачи 10.47

Задача 10.48. В данном тексте заменить все буквы а на о, а буквы м на н.

Способ 1.

Программный код: using System; namespace C88 { class Program { static void Main(string[] args) { string a = "информатика"; string b; Console.WriteLine("Исходный текст:\t" +a ); b=a.Replace('а', 'о'); b=b.Replace('м', 'н'); Console.WriteLine("Новый текст:\t" + b); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.120.

Рисунок 10.120 – Результаты решения задачи 10.48

323

Способ 2. Программный код: using System;

namespace C85 { class Program { static void Main(string[] args) { string a = "информатика", b = ""; char c; int L = a.Length; Console.WriteLine("Исходный текст:\t" + a ); for (int i = 0; i <= (L - 1); i++) { c = a[i]; if (c == 'а') b = b + 'о'; else if (c == 'м') b = b + 'н'; else b = b + c; } Console.WriteLine("Новый текст:\t" + b); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.121.

Рисунок 10.121 – Результаты решения задачи 10.48

324

Способ 3. Программный код: using System; namespace C87 { class Program { static void Main(string[] args) { string a = "информатика", b = ""; string c; Console.WriteLine("Исходный текст:\t" +a); int L = a.Length; for (int i = 0; i <= (L - 1); i++) { c = a.Substring(i,1); if (c == "а") b = b + "о"; else if (c == "м") b = b + "н"; else b = b + c; } Console.WriteLine("Новый текст:\t" + b); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.122.

Рисунок 10.122 – Результаты решения задачи 10.48 Задача 10.49. Посимвольный перебор. В заданной строке подсчитать количество гласных букв.

325

Программный код: using System; namespace C108 { class Program { static void Main(string[] args) { string s1 = "МАРТЫНОВ АНТОН ГРИГОРЬЕВИЧ"; char[] c = { 'а', 'А', 'у', 'У', 'о', 'О', 'ы', 'Ы', 'и', 'И', 'э', 'Э', 'я', 'Я', 'ю', 'Ю', 'е', 'Е' }; int n = 0; // количество гласных букв // Вычисление количества гласных букв for (int i = 0; i <= (s1.Length - 1); i++) { char c0 = s1[i]; for (int j = 0; j <= (c.Length - 1); j++) { if (c0 == c[j]) { n = n + 1; break; } } } Console.WriteLine(s1); Console.WriteLine("Количество гласных символов= " + n); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.123.

Рисунок 10.123 – Результаты решения задачи 10.49

326

Пояснение: Задан символьный массив c, содержащий гласные буквы, строка s1 перебирается посимвольно в цикле до длины строки, обращаясь к элементам строки по индексу. Каждый символ во вложенном цикле по очереди сравнивается с элементами массива гласных букв. В случае сравнения значение счетчика n увеличивается и внутренний цикл прерывается оператором break для исключения бессмысленного продолжения цикла, т.к. сравнение уже выполнено успешно и совпадений далее быть не может.

Задача 10.50. Реверс строки. Написать программу, преобразующую заданную строку в обратном

порядке (первый символ становится последним, последний – первым и т.д.). Результат вывести на консоль.

Программный код: using System; namespace C79 { class Program { static void Main(string[] args) { Console.WriteLine("Введите слово: "); string s1 = Console.ReadLine(); char[] s2 = s1.ToCharArray(); Array.Reverse(s2); s1 = new string(s2); Console.WriteLine(s2); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.124.

Рисунок 10.124 – Результаты решения задачи 10.50

327

10.7.2. Задачи для выполнения лабораторных работ Задача 1. Ввести фамилию, имя и отчество как одно данное

строкового типа. Определить длину строки и количество букв а в ней. Выполнить дополнительно задание своего варианта.

1. Вывести имя и количество букв в третьем слове. 2. Определить, сколько букв а есть в фамилии. 3. Вывести три буквы (свои инициалы) с точками. 4. Вывести длины фамилии и имени. 5. Вывести фамилию и инициалы. 6. Вывести имя и количество букв в фамилии. 7. Определить сколько букв о есть в имени. 8. Вывести самое длинное слово. 9. Изъять все буквы а и о из фамилии. 10. Вывести имя в столбик. 11. Начинается ли хотя бы одно слово с буквы М? 12. Все буквы и в имени продублировать. 13. Вывести фамилию и количество букв в имени. 14. Вывести имя в обратном порядке. 15. Вывести фамилию в столбик. 16. Вывести имя, отчество и количество букв в фамилии. 17. Вывести самое короткое слово. 18. Вывести строку без пропусков. Сколько букв в имени? 19. Вывести длины трех слов. 20. Вывести имя и количество букв в фамилии. 21. Вывести имя и фамилию. 22. Каждую букву имени продублировать. 23. Вывести фамилию в обратном порядке. 24. Определить, сколько букв а и б в фамилии. 25. Вывести третье слово и количество букв в фамилии. 26. Вывести отдельно каждое слово. Определить длину имени.

Вывести первую букву отчества.

328

Ниже приведено решение задачи для варианта №26. Программный код: using System; namespace C92 { class Program { static void Main(string[] args) { string str = "АСТАХОВА АННА ВЛАДИМИРОВНА"; string f1; // Фамилия string f2; // Имя string f3; // Отчество int i; int k; // Длина строки int k1; // Длина имени int n; // Количество букв "А" в строке string[] strWords; k = str.Length; Console.WriteLine("Длина строки = " + k + "\n "); // Определяем количество букв "А" в строке n = 0; for (i = 0; i <= (k - 1); i++) { if ((str[i] == 'А') || (str[i] == 'а')) n = n + 1; } Console.WriteLine("В строке количество букв <А> равно " + n + "\n"); // Строку разделяем на составные части. // В итоге возвращается массив, содержащий подстроки strWords = str.Split(" ".ToCharArray()); f1 = strWords[0]; // Фамилия f2 = strWords[1]; // Имя f3 = strWords[2]; // Отчество Console.WriteLine(f1 + "\n" + f2 + "\n" + f3 + "\n"); //Определяем длину имени k1 = f2.Length;

329

Console.WriteLine("Длина имени = " + k1); // Выводим первую букву отчества Console.WriteLine(f3[0]); Console.ReadLine(); } } }

Результаты расчета см. рис. 10.125.

Рисунок 10.125 – Результаты решения задачи 1 Задача 2. Составить программу, которая из некоторой текстовой

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

Задача 3. Поиск количества слов в предложении Написать программу, в которой ввести строку с клавиатуры,

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

Задача 4. Поиск самого длинного слова Написать программу, в которой ввести строку с клавиатуры. Найти

самое длинное слово. Результат вывести на консоль. Задача 5. Написать программу, в которой ввести строку с

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

330

10.8 Структуры, перечисления

10.8.1 Примеры решения задач

Задача 10.51. Программный код: using System; namespace C114 { struct Stud { public string Name, Group, Addr, PhoneNum; public DateTime BirthDate, EntryDate; public double CurrentAverageScore; public Stud(string n, string g, string a, string p, DateTime b, DateTime e, double c) { Name = n; Group = g; Addr = a; PhoneNum = p; BirthDate = b; EntryDate = e; CurrentAverageScore = c; } } class Program { static void Main(string[] args) { Stud[] X = new Stud[30]; X[0].Name = "Сидоров Петр Иванович"; X[0].Group = "IT-41"; X[0].BirthDate = new DateTime(1992, 9, 1); Console.WriteLine(X[0].Group); DateTime TD = DateTime.Today; int Y = TD.Year - X[0].BirthDate.Year; if (X[0].BirthDate > TD.AddYears(-Y)) Y--; Console.WriteLine("{0}, {1} лет", X[0].Name, Y); X[1] = new Stud("Николаенко Олег Михайлович", "ИТ-41",

331

"ул.Центральная 3,8", "7771234", new DateTime(1992, 5, 28), new DateTime(2011, 7, 15), 4.3); Y = TD.Year - X[1].BirthDate.Year; if (X[1].BirthDate > TD.AddYears(-Y)) Y--; Console.WriteLine("{0}, {1} лет", X[1].Name, Y); Console.ReadLine(); } } }

Результаты расчета см. рис.10.126

Рисунок 10.126 – Результаты решения задачи 10.51 Пояснение: В программе описан тип структуры Stud, имеющий

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

В основной программе (метод Main) создан массив из 30 элементов структуры Stud. Вручную инициализированы поля нулевого элемента – имя, группа и дата рождения. Ниже высчитан возраст как разница между годом рождения и текущей датой. Если вычитание полученного года из текущей даты даёт дату меньшую, чем дата рождения, то значение возраста уменьшается на единицу. Имя и возраст выводятся с помощью строки формата. Далее приводится инициализация первого элемента с помощью конструктора. Заметьте, что необходимо указать значения для всех полей.

Задача 10.52.

Программный код: using System; namespace C113 { class Program {

332

enum Colors { Black, Blue, Green, Cyan, Red, Magenta, Brown, White, Gray, LtBlue, LtGreen, LtCyan, LtRed, LtMagenta, Yellow, LtWhite } static void Main(string[] args) { string[] NColors ={"Чёрный", "Синий", "Зелёный", "Циан", "Красный", "Малиновый", "Коричневый", "Белый", "Серый", "Св.Синий", "Св.Зелёный", "Св.Циан", "Св.Красный", "Св.Малиновый", "Жёлтый", "Ярк.Белый"}; for (Colors i=Colors.Black; i<=Colors.LtWhite; ++i) Console.WriteLine("{0,2} {1,10} {2,12}", (int)i, i, NColors[(int)i]); Console.ReadLine(); } } }

Результаты расчета см. рис.10.127

Рисунок 10.127 – Результаты решения задачи 10.52 Пояснение: В задаче 10.52 приводится пример перечислення Colors. В

программе задан строковый массив с описанием цветов. В цикле, где счётчиком цикла является переменная i перечислимого типа Colors, выводится на консоль

333

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

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

Пример enum Colors { Black = 2, Blue, Green, Cyan, Red, Magenta, Brown, White, Gray, LtBlue, LtGreen, LtCyan, LtRed, LtMagenta, Yellow, LtWhite }

В этом примере все последующие после Black элементы будут иметь номер на единицу больше предыдущего.

Задавать номер элемента можно также и внутри списка:

Пример enum Colors { Black, Blue, Green, Cyan, Red, Magenta, Brown, White, Gray = 31, LtBlue, LtGreen, LtCyan, LtRed, LtMagenta, Yellow, LtWhite }

Если номер элемента White равен семи, то номер элемента Gray равен 31 и, соответственно, все последующие за ним элементы имеют номер, на единицу больше предыдущего.

10.8.2 Задачи для выполнения лабораторных работ

Задача 1. Описать структуру с именем STUDENT, содержащую

следующие поля: фамилия и инициалы; номер группы; успеваемость (массив из пяти элементов).

Написать программу, выполняющую следующие действия: ввод с клавиатуры данных в массив, состоящий из десяти

структур типа STUDENT (записи должны быть упорядочены по возрастанию номера группы);

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

334

средний балл студента больше 4,0 студенты имеют оценки 4 и 5 студенты имеют хотя бы одну оценку 2.

Если таких студентов нет, вывести соответствующее сообщение.

Задача 2. Описать структуру с именем NOTE, содержащую следующие поля:

фамилия, имя; номер телефона; дата рождения (массив из трёх чисел).

Написать программу, выполняющую следующие действия: ввод с клавиатуры данных в массив, состоящий из восьми

элементов типа NOTE (записи должны быть упорядочены по дате рождения);

вывод на экран информации: о людях, чьи дни рождения приходятся на месяц, значение

которого введено с клавиатуры (если такого нет, вывести соответствующее сообщение);

о человеке, чья фамилия введена с клавиатуры (если такой нет, вывести соответствующее сообщение);

о человеке, номер телефона которого введен с клавиатуры (если такого нет, вывести соответствующее сообщение).

10.9 Файлы

10.9.1. Примеры решения задач

Задача 10.53. Написать программу, которая: 1. Создаёт файл массива вещественных чисел

имя файла: F:\\file1.dat; количество элементов массива n=15; элементы массива вычисляются по формуле:

2 15.0 12if i i , где 0,1...( 1)i n .

2. Считывает данные из файла F:\\file1.dat, вычисляет сумму элементов файла. Программный код: using System; using System.IO;

335

namespace C124 { class Program { static void Main(string[] args) { const int n = 15; // количество элементов массива double[] F = new double[n]; double[] FRES = new double[n]; int i; double s; // Файл открывается для записи FileStream fsW = new FileStream("F:\\file1.dat", FileMode.Create, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fsW); Console.WriteLine("Вычисленные элементы массива"); for (i = 0; i <= (n - 1); i++) { F[i] = i * i + i / 15.0 - 12; // Вычисленные элементы массива выводятся на экран Console.WriteLine(F[i].ToString("F3")); // Элементы массива записываются в файл bw.Write(F[i]); } Console.WriteLine(); bw.Close(); fsW.Close(); s = 0; // Файл открывается для чтения FileStream fsR = new FileStream("F:\\file1.dat", FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fsR); Console.WriteLine("Прочитанные элементы файла"); for (i = 0; i <= (n - 1); i++) { // Элементы файла вычитываются и записываются // в элементы массива FRES[i] = br.ReadDouble(); Console.WriteLine(FRES[i].ToString("F3")); s = s + FRES[i]; }

336

br.Close(); fsR.Close(); Console.WriteLine(); Console.WriteLine("s={0,7:F3} ", s); Console.ReadLine(); } } }

Результаты расчета см. рис.10.128

Рисунок 10.128 – Результаты решения задачи 10.53 Пояснение: 1) Для того чтобы использовать в программе файлы, необходимо:

а) Подключить пространство имен, в котором описываются стандартные классы для работы с файлами (using System.IO).

б) Создать файловый поток и связать его с физическим файлом.

337

в) Произвести операции обмена (ввод-вывод). г) Закрыть файл Для работы с числовыми данными типа int или double лучше создать

объекты классов BinaryWriter и BinaryReader, чьи методы Write() (перегружен для разных типов данных), ReadInt32() и ReadDouble() как нельзя лучше подходят для этой задачи. 2) FileStream fsW = new FileStream("F:\\file1.dat", FileMode.Create, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fsW);

Файл с именем ("F:\\file1.dat") сначала открывается на запись, в результате чего объектная ссылка fsW типа FileStream получает актуальное значение. Поверх этой ссылки строится объект bw класса BinaryWriter: BinaryWriter bw = new BinaryWriter(fsW);

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

Если при открытии файла путь к файлу не указан, то файл данных ищется или создается в том же каталоге, где находится исполняемый файл программы:

D:\ ProgramVS\ C124\ C124\ bin\ Debug\ file1.dat

3) bw.Write(F[i]); С помощью перегруженного метода Write() класса BinaryWriter в

открытый файл циклически поэлементно записываются элементы массива.

4) bw.Close(); fsW.Close(); Пишущий объект и файл закрываются одноименными методами Close().

5) FileStream fsR = new FileStream("D:\\file1.dat", FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fsR);

Файл "F:\\file1.dat" снова открывается, но уже на чтение.

6) FRES[i] = br.ReadDouble(); Содержимое файла "F:\\file1.dat" последовательно «вычитывается»

338

от имени объекта br типа BinaryReader методом ReadDouble() в массив- приёмник FRES.

Для проверки результата, значения элементов массива выводятся в консольное окно программы с помощью статического метода WriteLine() библиотечного класса Console: Console.WriteLine(FRES[i].ToString("F3"));

7) br.Close(); fsR.Close(); Читающий объект и файл закрываются одноименными методами Close(). В табл. 10.23 представлены варианты задач.

Таблица 10.23 – Варианты задач

№ вар.

Количество элементов файла (значение n)

Формула, по которой вычисляются элементы файла

1 12n 31,2 7 94, где 0,1,..if i i i n 2 14n 22,5 3 50, где 0,1,..if i i i n 3 15n ( 8)( 5,7), где 0,1,..if i i i n 4 12n ( 9,3)(3 5), где 0,1,..if i i i n 5 15n ( 10)(5 9), где 0,1,..if i i i n 6 14n 32 9 100, где 0,1,..if i i i n 7 12n 31,7 12 70, где 0,1,..if i i i n 8 15n 214 105 60, где 0,1,..if i i i n 9 12n 29 87 60, где 0,1,..if i i i n 10 15n 2 +15 90, где 0,1,..if i i i n

Задача 10.54. Написать программу, которая считывает данные из файла (F:\\file1.dat), созданного в задаче 10.51. Получить два нових файла с именами (F:\\file2.dat), и (F:\\file3.dat), в один из которых записать положительные элементы файла, а в другой – отрицательные. Вычислить количество элементов полученных файлов. Полученные файлы прочитать и вывести на экран.

339

Программный код: using System; using System.IO; namespace C128 { class Program { static void Main(string[] args) { const int n = 15; // количество элементов массива double[] FRES = new double[n]; int i; int n1; // количество элементов файла file2.dat int n2; // количество элементов файла file3.dat // Файл открывается для чтения FileStream fsR = new FileStream("F:\\file1.dat", FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fsR); // Файл открывается для записи FileStream fsW1 = new FileStream("F:\\file2.dat", FileMode.Create, FileAccess.Write); BinaryWriter bw1 = new BinaryWriter(fsW1); // Файл открывается для записи FileStream fsW2 = new FileStream("F:\\file3.dat", FileMode.Create, FileAccess.Write); BinaryWriter bw2 = new BinaryWriter(fsW2); n1 = 0; n2 = 0; Console.WriteLine("Элементы файла file1.dat "); for (i = 0; i <= (n - 1); i++) { // Чтение файла FRES[i] = br.ReadDouble(); // Вывод элементов файла на экран Console.WriteLine(FRES[i].ToString("F3")); if (FRES[i] >= 0) { bw1.Write(FRES[i]); n1 = n1 + 1; }

340

else { bw2.Write(FRES[i]); n2 = n2 + 1; } } br.Close(); fsR.Close(); bw1.Close(); fsW1.Close(); bw2.Close(); fsW2.Close(); Console.WriteLine(); Console.WriteLine("n1={0}; n2={1}", n1, n2); Console.WriteLine(); // Файл открывается для чтения FileStream fsR2 = new FileStream("F:\\file2.dat", FileMode.Open, FileAccess.Read); BinaryReader br2 = new BinaryReader(fsR2); // Файл открывается для чтения FileStream fsR3 = new FileStream("F:\\file3.dat", FileMode.Open, FileAccess.Read); BinaryReader br3 = new BinaryReader(fsR3); double[] F2 = new double[n1]; double[] F3 = new double[n2]; Console.WriteLine("Элементы файла file2.dat "); for (i = 0; i <= (n1 - 1); i++) { // Чтение файла F2[i] = br2.ReadDouble(); // Вывод элементов файла на экран Console.WriteLine(F2[i].ToString("F3")); } Console.WriteLine(); Console.WriteLine("Элементы файла file3.dat \n"); for (i = 0; i <= (n2 - 1); i++) { // Чтение файла F3[i] = br3.ReadDouble(); // Вывод элементов файла на экран

341

Console.WriteLine(F3[i].ToString("F3")); } br2.Close(); fsR2.Close(); br3.Close(); fsR3.Close(); Console.ReadLine(); } } }

Результаты расчета см. рис.10.129

Рисунок 10.129 – Результаты решения задачи 10.54

Задача 10.55. Создать текстовый файл в который будет выведена

таблица значений функции 5 3sin( ) 7y x x в диапазоне от 1 10x с шагом 1. Таблица должна состоять из двух столбцов: значений аргумента и соответствующих им значений функции.

342

Программный код: using System; using System.IO; namespace C123 { class Program { static void Main(string[] args) { // Файл открывается для записи FileStream fsW = new FileStream("F:\\file4.txt", FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fsW); double x, y; // аргумент и значение функции double xn = 1.0; // начальное значение переменной x double xk = 10.0; // конечное значение переменной x double dx = 1.0; // шаг изменения переменной string s; Console.WriteLine("Вычисленные значения функции y "); for (x = xn; x <= xk; x = x + dx) { y = 5 * x + 3 * Math.Sin(x) + 7; // Вычисленные значения y выводятся на экран Console.WriteLine("x={0,6:F2} y={1,6:F3}", x, y); // Вычисленные значения y записываются в файл s = String.Format("x={0,6:F2} y={1,6:F3}", x, y); sw.WriteLine(s); } Console.WriteLine(); sw.Close(); fsW.Close(); // Файл открывается для чтения FileStream fsR = new FileStream("D:\\file4.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fsR); Console.WriteLine("Прочитанные элементы файла"); // Цикл выполняется пока не достигнут конец файла while((s=sr.ReadLine()) !=null) Console.WriteLine(s); sr.Close();

343

fsR.Close(); Console.ReadLine(); } } }

Результаты расчета см. рис.10.130.

Рисунок 10.130 – Результаты решения задачи 10.55

Пояснение: С текстовыми файлами лучше работать с помощью пишущих и читающих

объектов специализированных классов StreamWriter и StreamReader. Здесь используются методы Write() и ReadLine().

Программа за один вызов метода ReadLine() читает по одной физической строке. Условие полной вычитки текстового файла – возврат методом ReadLine() значения null.

Запись строк в текстовый файл лучше осуществлять не методом Write(), а методом WriteLine().

Задача 10.56. Имеется текстовый файл (слова разделены одним

пробелом). Прочитать файл. Определить сколько в тексте гласных и согласных букв.

344

Содержимое текстового файла (F:\\file5.txt ):

Село! В душе моей покой. Село в Украйне дорогой, И, полный сказок и чудес, Кругом села зелёный лес. Цветут сады, белеют хаты, А на горе стоят палаты, И перед крашеным окном В шелковых листьях тополя, А там всё лес, и все поля, И степь, и горы за Днепром. Программный код: using System; using System.IO; namespace C125 { class Program { static void Main(string[] args) { string s1 = "файловое хранение текстовых данных"; char[] c1 = { 'а', 'А', 'у', 'У', 'о', 'О', 'ы', 'Ы', 'и', 'И', 'э', 'Э', 'я', 'Я', 'ю', 'Ю', 'е', 'Е', 'ё', 'Ё' }; char[] c2 = { 'б', 'Б', 'в', 'В', 'г', 'Г', 'д', 'Д', 'ж', 'Ж', 'з', 'З', 'й', 'Й', 'к', 'К', 'л', 'Л', 'м', 'М', 'н', 'Н', 'п', 'П', 'р', 'Р', 'с', 'С', 'т', 'Т', 'ф', 'Ф', 'х', 'Х', 'ц', 'Ц', 'ч', 'Ч', 'ш', 'Ш', 'щ', 'Щ'}; int n1 = 0; // количество гласных букв int n2 = 0; // количество согласных букв string Str; // Файл открывается для чтения FileStream fsR = new FileStream("F:\\file5.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fsR); while ((Str = sr.ReadLine()) != null) { Console.WriteLine(Str); // Вычисление количества гласных букв

345

for (int i = 0; i <= (Str.Length - 1); i++) { char c0 = Str[i]; for (int j = 0; j <= (c1.Length - 1); j++) if (c0 == c1[j]) n1 = n1 + 1; for (int j = 0; j <= (c2.Length - 1); j++) if (c0 == c2[j]) n2 = n2 + 1; } } sr.Close(); fsR.Close(); Console.WriteLine(); Console.WriteLine("Количество гласных символов: " + n1); Console.WriteLine("Количество согласных символов: " + n2); Console.ReadLine(); } } }

Результаты расчета см. рис.10.131

Рисунок 10.131 – Результаты решения задачи 10.56 Пояснение: Задан символьный массив c1, содержащий гласные буквы,

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

Каждый символ во вложенном цикле по очереди сравнивается с элементами массива гласных букв. В случае сравнения значение счетчика n1 увеличивается на единицу. Каждый символ во вложенном цикле по очереди сравнивается также с элементами массива согласных букв. В случае сравнения значение счетчика n2 увеличивается на единицу.

346

Задача 10.57. Записать в файл значения функции ( ) cos( )y x x , 3 3x . Прочитать созданный файл.

Способ 1. Создать консольное приложение

Программный код: using System; using System.IO; namespace C109 { class Program { static void Main(string[] args) { // Файл открывается для записи FileStream fsW = new FileStream("F:\\file6.txt", FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fsW); double x, y; // аргумент и значение функции string s; Console.WriteLine("Вычисленные значения функции y "); // Вывод на экран названий столбцов Console.WriteLine("-----------------"); Console.WriteLine(" x y "); Console.WriteLine("-----------------"); // Запись в файл названиий столбцов sw.WriteLine("-----------------"); sw.WriteLine(" x y "); sw.WriteLine("-----------------"); for (x = -3; x <= 3; x = x + 0.5) { y = 5 * x + 3 * Math.Sin(x) + 7; // Вычисленные значения y выводятся на экран Console.WriteLine("{0,6:F2} {1,7:F3}", x, y); // Вычисленные значения y записываются в файл s = String.Format("{0,6:F2} {1,7:F3}", x, y); sw.WriteLine(s); } Console.WriteLine(); sw.Close();

347

fsW.Close(); // Файл открывется для чтения FileStream fsR = new FileStream("F:\\file6.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fsR); Console.WriteLine("Прочитанные элементы файла"); // Цикл выполняется пока не достигнут конец файла while ((s = sr.ReadLine()) != null) Console.WriteLine(s); sr.Close(); fsR.Close(); Console.ReadLine(); } } }

Результаты расчета см. рис.10.132.

Рисунок 10.132 – Результаты решения задачи 10.57

348

Способ 2. Создать Windows- приложение

ПОРЯДОК ДЕЙСТВИЙ

1. Расположите на форме объекты, как показано на рис. 10.133, 10.134.

На форме расположить: одно поле списка (ListBox); две командных кнопки (Button).

Рисунок 10.133 – Форма к задаче 10.57

2. Установите значения свойств объектов в соответствии с

табл.10.24.

Таблица 10.24 – Значения свойств объектов к задаче 10.57 Объект Имя объекта по

умолчанию (значение свойства Name)

Свойство Значение свойства

Форма Form1 Поле списка ListBox1 Командная кнопка

Button1 Name cmdStart Text Вычислить

Командная кнопка

Button2 Name cmdEnd Text Завершение работы

349

Рисунок 10.134 – Форма к задаче 10.57

3. Программирование. Напишите обработчики событий щелчок мышью по командной

кнопке <Вычислить> и щелчок мышью по командной кнопке <Завершение работы>.

Программный код: using System; using System.IO; using System.Windows.Forms; namespace W18 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void cmdStart_Click(object sender, EventArgs e) { // Файл открывается для записи FileStream fsW = new FileStream("F:\\file7.txt", FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fsW); double x, y; // аргумент и значение функции string s;

350

// Запись в файл названиий столбцов sw.WriteLine("---------------------"); sw.WriteLine(" x y "); sw.WriteLine("---------------------"); for (x = -3; x <= 3; x = x + 0.5) { y = 5 * x + 3 * Math.Sin(x) + 7; // Вычисленные значения y записываются в файл s = String.Format("{0,7:F2} {1,7:F3}", x, y); sw.WriteLine(s); } sw.Close(); fsW.Close(); // Файл открывается для чтения FileStream fsR = new FileStream("F:\\file7.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fsR); // Цикл выполняется пока не достигнут конец файла while ((s = sr.ReadLine()) != null) listBox1.Items.Add(s); sr.Close(); fsR.Close(); } } }

Результаты расчета см. рис.10.135.

Рисунок 10.135 – Результаты решения задачи 10.57

351

Задача 10.58. Создать квадратную матрицу A размером nn. Матрицу заполнить случайными целыми числами. Матрицу построчно вывести на экран. В текстовый файл "F:\\file10.txt"записать сначала n – число

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

Программный код: using System; using System.IO; namespace C112 { class Program { static void Main(string[] args) { int n; // количество строк и столбцов матрицы А Console.Write("Введите n= "); n = Convert.ToInt32(Console.ReadLine()); Console.WriteLine(); int i, j, k; double[,] A = new double[n, n]; string S; Random rnd=new Random(); // Файл открывается для записи FileStream fsW = new FileStream("F:\\file10.txt", FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fsW); // В файл записывается сначала размер матрицы n, // затем сама матрица построчно Console.WriteLine("n={0}", n); sw.WriteLine(n); // Заполнение матрицы А, // вывод матрицы A на экран и запись в файл Console.WriteLine("Элементы матрицы A "); for (i = 0; i <= (n - 1); i++) { for (j = 0; j <= (n - 1); j++) {

352

k = rnd.Next(1, 9); Console.Write(k + " "); sw.Write(k + " "); } Console.WriteLine(); sw.WriteLine(); } Console.WriteLine(); sw.Close(); fsW.Close(); // Файл открывается для чтения FileStream fsR = new FileStream("D:\\file10.txt", FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fsR); S = sr.ReadLine(); // Прочитать строку n = Convert.ToInt32(S); // Получить размер матрицы Console.WriteLine("n= {0}", n); Console.WriteLine("Элементы файла file10.dat "); // Чтение файла и вывод на экран for (i = 0; i <= (n - 1); i++) { // Построчно читать данные S = sr.ReadLine(); // Разобрать данные строки, разделяя числа пробелом // либо знаком табуляции string[] SA = S.Split(new Char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); // Заполнить строку массива числами строки файла for (j = 0; j <= (n - 1); j++) { A[i, j] = Convert.ToInt32(SA[j]); Console.Write( A[i, j] + " " ); } Console.WriteLine(); } Console.WriteLine(); sr.Close(); fsR.Close(); Console.ReadLine(); } } }

353

Результаты расчета см. рис.10.136.

Рисунок 10.136 – Результаты решения задачи 10.58

Пояснение: string[] SA = S.Split(new Char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);

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

В перечислении StringSplitOptions определяются только два значения: None и RemoveEmptyEntries. При значении None пустые строки включаются в конечный результат разделения исходной строки. При значении RemoveEmptyEntries пустые строки исключаются из конечного результата разделения исходной строки.

354

Список литературы

1. Шилдт Герберт. C# 4.0: полное руководство / Г. Шилдт: пер. с

англ. – М: ООО «И.Д. Вильямс», 2011. – 1056 с.

2. Мартынов Н.Н. C# для начинающих / Н.Н. Мартынов. – М.:

Кудиц–пресс, 2007. – 272 с.

3. Культин Н.Б. Microsoft Visual C# в задачах и примерах /

Н.Б. Культин. – СПб.: БХВ – Петербург, 2009. – 320 с.

4. Петцольд Ч. Программирование с использованием Microsoft

Windows Forms. Мастер – класс / Ч. Петцольд: пер. с англ. – М: Русская

редакция; СПб.: Питер, 2006. – 432 с.

5. Фаронов В.В. Программирование на языке С# / В.В. Фаронов. –

СПб.: Питер, 2007. – 240 с.

6. Павловская Т.А. С#. Программирование на языке високого уровня.

Учебник для вузов / Т.А. Павловская. – СПб.: Питер, 2007. – 432 с.

7. Подбельский В.В. Язык Си#. Базовый курс: учеб. Пособие /

В.В. Подбельский. – М.: Финансы и статистика, 2011. – 384 с.

355

Навчальне видання

Соловей Людмила Валентинівна Мірошніченко Наталія Миколаївна

Пономарьова Наталія Георгіївна

ПРОГРАМУВАННЯ НА МОВІ C#

Навчальний посібник для студентів хімічних спеціальностей в тому числі для іноземних студентів

Російською мовою

Роботу до друку рекомендував проф. О.М. Рассоха

В авторській редакції

356

План 2015 р., поз. 36

Підп. до друку 19.06.2015 р. Формат 60х84 1/16. Папір офсетний. Riso-друк. Гарнітура Таймс. Ум. друк. арк. 20,7. Наклад 60 пр.

Зам. № 10 Ціна договірна Видавець і виготовлювач

Видавничий центр НТУ «ХПІ», вул. Фрунзе, 21, м. Харків-2, 61002

Свідоцтво суб’єкта видавничої справи ДК № 3656 від 24.12.2009 р.