Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Основы программирования на языке C#. Учебное пособие
.pdf
43
идентификатора должен быть согласован с типом элементов,
хранящихся в контейнере данных. Предполагается также, что
элементы контейнера (массива, коллекции) упорядочены. На каждом
шаге цикла идентификатор, задающий текущий элемент контейнера,
получает значение очередного элемента в соответствии с порядком,
установленным на элементах контейнера. С этим текущим
элементом и выполняется тело цикла – выполняется столько раз,
сколько элементов находится в контейнере. Цикл заканчивается,
когда полностью перебраны все элементы контейнера.
Серьезным недостатком циклов foreach в языке C# является
то, что цикл работает только на чтение, но не на запись элементов.
Так что наполнять контейнер элементами приходится с помощью
других операторов цикла. В приведенном ниже примере показана
работа с трехмерным массивом. Массив создается с
использованием циклов типа for, а при нахождении суммы его
элементов, минимального и максимального значения используется
цикл foreach:
// Демонстрация цикла foreach. Вычисление суммы,
// максимального и минимального элементов
// трехмерного массива, заполненного случайными числами.
public void SumMinMax()
{
int [,,] arr3d = new int[10,10,10];
Random rnd = new Random();
for (int i =0; i<10; i++)
for (int j =0; j<10; j++)
for (int k =0; k<10; k++)
arr3d[i,j,k]= rnd.Next(100);
long sum =0; int min=arr3d[0,0,0], max=arr3d[0,0,0];
foreach(int item in arr3d)
{
sum +=item;
if (item > max) max = item;
else if (item < min) min = item;
}
Console.WriteLine("sum = {0}, min = {1}, max = {2}",
sum, min, max);
}//SumMinMax
41

44
Вопросы для самоконтроля
54x3+x
x
x
sin
5
)+(x+x 3ln
5
0,
1
1
,0,1
2
2
xесли
x
xеслиx
n
)+(x11
1. Как записывается оператор присваивания?
2. Каков синтаксис условного оператора?
3. Опишите оператор выбора языка C#.
4. Как используются операторы перехода?
5. Перечислите операторы циклов, используемые в C#. Каков
синтаксис этих операторов?
6. Какова особенность оператора foreach?
Упражнения
1. Напишите программу, которая по введенному с клавиатуры
числу x выводит на экран значение выражения:
.
2. Напишите программу, которая по введенному с клавиатуры
числу x выводит на экран значение выражения:
.
3. Напишите программу, которая по введенному с клавиатуры
числу x выводит на экран значение выражения:
.
4. Напишите программу, вычисляющую значение функции:
5. Напишите программу, которая по заданному с клавиатуры
числу n выводит на экран сумму:
.
6. Напишите программу, печатающую на экране монитора все
четырехзначные числа, кратные данному числу k.
7. Напечатайте на экране монитора все двузначные четные числа,
располагая числа каждого десятка в отдельном столбце.
8. Напишите программу, которая находит все четырехзначные
числа ABCD, для которых одновременно выполняются два
условия:
а) A, B, C, D – разные цифры;
б) AB – CD = A + B + C + D.
42

45
5. КЛАССЫ В C#
В языке С# все происходит в рамках какого-нибудь класса.
5.1. Основные понятия
Под классом понимается тип данных, определяемый
пользователем. Элементами класса являются данные и функции,
предназначенные для их обработки.
Описание класса содержит ключевое слово class , за которым
следует его имя, а далее в фигурных скобках – тело класса, т.е.
список его элементов. Для класса можно задать также его базовые
классы (предки) и ряд необязательных атрибутов и
спецификаторов, определяющих различные характеристики класса:
[ атрибуты ] [ спецификаторы ] class имякласса [ : предки ]
тело-класса
Имя класса задается программистом по общим правилам С#.
Тело класса – это список описаний его элементов, заключенный в
фигурные скобки. Список может быть пустым, если класс не
содержит ни одного элемента. Пример простейшего класса:
Class HelloClass
{
Public static int Main (string[ ] args)
{
Console.WriteLine (“Привет, Мир!”);
Return 0;
}
}
Спецификаторы определяют свойства класса, а также
доступность класса для других элементов программы. Возможные
значения спецификаторов перечислены в табл. 5.1. Класс можно
описывать непосредственно внутри пространства имен или внутри
другого класса. В последнем случае класс называется вложенным.
В зависимости от места описания класса некоторые из этих
спецификаторов могут быть запрещены.
43

46
Спецификации класса
№ п/п
Спецификатор
Описание
1
new
Используется для вложенных классов.
Задает новое описание класса взамен
унаследованного от предка
2
public
Доступ не ограничен
3
protected
Используется для вложенных классов.
Доступ только из элементов данного и
производных классов
4
internal
Доступ только из данной программы
(сборки)
5
protected internal
Доступ только из данного и
производных классов или из данной
программы (сборки)
6
private
Используется для вложенных классов.
Доступ только из элементов класса,
внутри которого описан данный класс
7
abstract
Абстрактный класс. Применяется в
иерархиях объектов
8
sealed
Бесплодный класс. Применяется в
иерархиях объектов
9
static
Статический класс
Таблица 5.1.
Спецификаторы 2-6 называются спецификаторами доступа.
Они определяют, откуда можно непосредственно обращаться к
данному классу. Спецификаторы доступа могут присутствовать в
описании только в вариантах, приведенных в таблице, а также
могут комбинироваться с остальными спецификаторами.
В этой главе мы будем изучать классы, которые описываются
в пространстве имен непосредственно (т.е. не вложенные классы).
Для таких классов, которые описываются в пространстве имен
непосредственно, допускаются только два спецификатора: public и
internal. По умолчанию, т.е. если ни один спецификатор доступа не
указан, подразумевается спецификатор internal.
Класс является обобщенным понятием, определяющим
характеристики и поведение некоторого множества конкретных
объектов этого класса, называемых экземплярами, или объектами,
класса. Объекты создаются явным или неявным образом, т.е. либо
44

47
программистом, либо системой. Программист создаст экземпляр
класса с помощью операции new, например:
HelloClass Cl = new HelloClass();
Для каждого объекта при его создании в памяти выделяется
отдельная область, в которой хранятся его данные – данные
экземпляра. В классе могут присутствовать элементы, которые
существуют в единственном экземпляре для всех объектов класса.
Последние называют статическими данными.
Для работы с данными класса используются методы класса
(статические методы), для работы с данными экземпляра – методы
экземпляра, или просто методы.
Элементами класса являются:
Константы – хранят неизменяемые значения, связанные с
классом.
Поля – содержат данные класса.
Методы – реализуют вычисления или другие действия,
выполняемые классом или экземпляром.
Свойства – определяют характеристики класса в совокупности
со способами их задания и получения, т.е. методами записи и
чтения.
Конструкторы – реализуют действия по инициализации
экземпляров или класса в целом.
Деструкторы – определяют действия, которые необходимо
выполнить до того, как объект будет уничтожен.
Индексаторы – обеспечивают возможность доступа к
элементам класса по их порядковому номеру.
5.2. Константы и неизменяемые поля
Константы (constants) –это поля, остающиеся постоянными
в течение всего времени жизни приложения. Определяя что-либо
как const, достаточно помнить два правила. Во-первых, константа –
это член, значение которого устанавливается в период компиляции
программистом или компилятором (в последнем случае это
значение по умолчанию). Во-вторых, значение члена-константы
должно быть записано в виде литерала.
45

48
Чтобы определить поле как константу, достаточно поставить
перед определяемым членом ключевое слово const:
clas s Constants
{
static void Main ()
{
const int pi = 3.1415926535897932384626433832795;
const int g = 9.81; //гравитационная постоянная
System.Console.WriteLine{"Число пи: {0}" , pi);
System.Console.WriteLine("Гравитационная постоянная:{0}", g);
}
}
Ваша программа будет лучше читаемой, если вы вместо
записи:
у = х * 3.1415926535897932384626433832795
будете использовать переменную, которая хранит значение pi. В
таком случае используемой переменной должна быть константа:
const double pi = 3.1415926535897932384626433832795 ;
у = х * pi;
Константа обязательно должна быть проинициализирована, и
ее значение не может быть изменено во время выполнения
программы.
5.3. Методы
Процедуры и функции связываются теперь с классом, они
обеспечивают функциональность данных класса и называются
методами класса. И хотя в языке C# нет специальных ключевых
слов – procedure и function, но сами эти понятия присутствуют.
Синтаксис объявления метода позволяет однозначно определить,
чем является метод – процедурой или функцией.
Функция отличается от процедуры двумя особенностями:
всегда вычисляет некоторое значение, возвращаемое в
качестве результата функции;
вызывается в выражениях.
Процедура C# имеет свои особенности:
возвращает формальный результат void, указывающий на
отсутствие результата;
46

49
вызов процедуры является оператором языка;
имеет входные и выходные аргументы, причем выходных
аргументов – ее результатов – может быть достаточно много.
Синтаксически в описании метода различают две части –
описание заголовка и описание тела метода:
заголовок_метода
тело_метода
Рассмотрим синтаксис заголовка метода:
[атрибуты][модификаторы]{void| тип_результата_функции}
имя_метода([список_формальных_аргументов])
Имя метода и список формальных аргументов составляют
сигнатуру метода. Квадратные скобки (метасимволы
синтаксической формулы) показывают, что атрибуты и
модификаторы могут быть опущены при описании метода.
Обязательным при описании заголовка является указание
типа результата, имени метода и круглых скобок, наличие которых
необходимо и в том случае, если сам список формальных
аргументов отсутствует. Формально тип результата метода
указывается всегда, но значение void однозначно определяет, что
метод реализуется процедурой. Тип результата, отличный от void,
указывает на функцию. Вот несколько простейших примеров
описания методов:
void A() {...};
int B(){...);
public void C(){...};
Методы A и B являются закрытыми, а метод С – открыт.
Методы A и С реализованы процедурами, а метод B – функцией,
возвращающей целое значение.
Список формальных аргументов метода может быть пустым
или содержать фиксированное число аргументов, разделяемых
символом запятой. Синтаксис объявления формального аргумента:
[ref|out|params]тип_аргумента имя_аргумента
Обязательным является указание типа и имени аргумента.
Тип может быть любым скалярным типом, массивом, классом,
структурой, интерфейсом, перечислением, функциональным
типом.
47

50
Несмотря на фиксированное число формальных аргументов,
есть возможность при вызове метода передавать ему произвольное
число фактических аргументов. Для реализации этой возможности
в списке формальных аргументов необходимо задать ключевое
слово params. Оно задается один раз и указывается только для
последнего аргумента списка, объявляемого как массив
произвольного типа. При вызове метода этому формальному
аргументу соответствует произвольное число фактических
аргументов.
Содержательно все аргументы метода разделяются на три
группы: входные, выходные и обновляемые. Аргументы первой
группы передают информацию методу, их значения в теле метода
только читаются. Аргументы второй группы представляют собой
результаты метода, они получают значения в ходе работы метода.
Аргументы третьей группы выполняют обе функции. Их значения
используются в ходе вычислений и обновляются в результате
работы метода. Выходные аргументы всегда должны
сопровождаться ключевым словом out, обновляемые – ref. Что же
касается входных аргументов, то, как правило, они задаются без
ключевого слова, хотя иногда их полезно объявлять с параметром
ref, о чем подробнее скажу чуть позже. Заметьте, если аргумент
объявлен как выходной с ключевым словом out, то в теле метода
обязательно должен присутствовать оператор присваивания,
задающий значение этому аргументу. В противном случае возникает
ошибка еще на этапе компиляции. Для иллюстрации приведем
группу методов:
void A(out long p2, int p1)
{
p2 =(long) Math.Pow(p1,3);
Console.WriteLine("Метод A-1");
}
void A(out long p2, params int[] p)
{
p2=0; for(int i=0; i <p.Length; i++) p2 += (long)Math.Pow(p[i],3);
Console.WriteLine("Метод A-2");
}
void A(out double p2, double p1)
{
48

51
p2 = Math.Pow(p1,3);
Console.WriteLine("Метод A-3");
}
void A(out double p2, params double[] p)
{
p2=0; for(int i=0; i <p.Length; i++) p2 += Math.Pow(p[i],3);
Console.WriteLine("Метод A-4");
}
{
return(a++);
}
Тело метода синтаксически является блоком, который
представляет собой последовательность операторов и описаний
переменных, заключенную в фигурные скобки. Если речь идет о теле
функции, то в блоке должен быть хотя бы один оператор перехода,
возвращающий значение функции в форме return (выражение).
Переменные, описанные в блоке, считаются
локализованными в этом блоке. В записи операторов блока
участвуют имена локальных переменных блока, имена полей
класса и имена аргументов метода.
Метод может вызываться в выражениях или быть вызван как
оператор. В качестве оператора может использоваться любой метод
– как процедура, так и функция. Если же попытаться вызвать
процедуру в выражении, то это приведет к ошибке еще на этапе
компиляции. Возвращаемое процедурой значение void
несовместимо с выражениями. Так что в выражениях могут быть
вызваны только функции.
Сам вызов метода, независимо от того, процедура это или
функция, имеет один и тот же синтаксис:
имя_метода([список_фактических_аргументов])
Если это оператор, то вызов завершается точкой с запятой.
Формальный аргумент, задаваемый при описании метода – это
всегда имя аргумента (идентификатор). Фактический аргумент –
это выражение, значительно более сложная синтаксическая
конструкция. Вот точный синтаксис фактического аргумента:
[ref|out]выражение
49

52
Существование в классе методов с одним и тем же именем
называется перегрузкой, а сами одноименные методы называются
перегруженными.
Перегрузка методов полезна, когда требуется решать
подобные задачи с разным набором аргументов. Типичный пример
– это нахождение площади треугольника. Площадь можно
вычислить по трем сторонам, по двум углам и стороне, по двум
сторонам и углу между ними и при многих других наборах
аргументов. Считается удобным во всех случаях иметь для метода
одно имя, например Square, и всегда, когда нужно вычислить
площадь, не задумываясь, вызывать метод Square, передавая ему
известные в данный момент аргументы.
Перегрузка характерна и для знаков операций. В зависимости
от типов аргументов, один и тот же знак может выполнять
фактически разные операции. Классическим примером является
знак операции сложения +, который играет роль операции
сложения не только для арифметических данных разных типов, но
и выполняет конкатенацию строк.
В приведенном выше примере приведены четыре
перегруженных метода с именем A, различающиеся по сигнатуре. Эти
методы отличаются типами аргументов и ключевым словом params.
5.4. Свойства
Свойства позволяют имитировать доступ к внутренним
данным класса. Преимущество свойств перед традиционными
методами доступа заключается в том, что вместо того, чтобы
использовать два отдельных метода, пользователь класса может
использовать единственное свойство, работая с ним так же, как с
открытой переменной-членом данного класса.
Свойство C# состоит из двух блоков – блока доступа (get
block) и блока изменения (set block). Ключевое свойство value
представляет правую часть выражения при присвоении значения
посредством свойства:
50
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
