Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Books / 3_C#_2005_для_чайников_(Дэвис-2008)

.pdf
Скачиваний:
86
Добавлен:
24.03.2015
Размер:
15.46 Mб
Скачать

// Можно присваивать значения непосредственно Console . Write("Производител ь = " ) ;

myCar . sManufacturer = C o n s o l e . R e a d L i n e О ;

//Остальные данные имеют тип i n t

Console . Write("Количеств о дверей =

" ) ;

s = C o n s o l e . R e a d L i n e ( ) ;

 

myCar.nNumOfDoors

=

C o n v e r t . T o I n t 3 2 ( s ) , -

Console . Write("Количеств о колес =

" ) ;

s = C o n s o l e . R e a d L i n e ( ) ;

 

myCar.nNumOfWheels

=

C o n v e r t . T o I n t 3 2 ( s ) ;

// Вывод полученной

информации

 

Console . WriteLine("\пВаш а машина:

" ) ;

Console . WriteLine(myCar . sManufacture r + " " +

 

myCar . sModel) ;

 

C o n s o l e . W r i t e L i n e ( " c

" + myCar.nNumOfDoors +

 

"

дверями, "

 

+"на " + myCar.nNumOfWheels

+" колесах" ) ;

//Ожидаем подтверждения пользователя

Console . WriteLine("Нажмите <Enter> для " + "завершения программы.. . ") ;

C o n s o l e . R e a d ( ) ;

Листинг программы начинается с определения класса V e h i c l e .

Определение класса может находиться как до, так и после класса Program — это не имеет значения. Однако вам нужно принять какой-то один стиль и сле­ довать ему.

Программа создает объект myCar класса V e h i c l e , а затем заполняет все его поля информацией, вводимой пользователем с клавиатуры. Проверка корректности входных данных не производится. Затем программа выводит введенные данные на экран в немно­ го ином формате.

Вывод этой программы выглядит следующим образом:

Введите информацию о машине

Модель

 

=

M e t r o p o l i t a n

Производитель

=

Nash

Количество

дверей

=

2

Количество

колес

 

=

4

Ваша м а ш и н а :

 

 

 

 

Nash Metropolita n

 

 

с 2 дверями,

на

4

колесах

Нажмите <Enter>

для

завершения программы...

Глава В, Объединение данных - классы и массивы

119

Вызов Read ( ) , в отличие от ReadLine ( ) , оставляет курсор сразу за введен! ной строкой. Это приводит к тому, что ввод пользователя находится на той nil строке, что и приглашение. Кроме того, добавление символа новой стромГ

'\ п ' создает пустую строку без необходимости вызывать WriteLin e ( ) .

От л и ч ие между объектами

Заводы в Детройте в состоянии выпускать множество автомобилей и отслеживать кажду»| выпущенную машину и при этом не путать их. Аналогично, программа может создать не­ сколько объектов одного и того же класса, как показано в следующем фрагменте:

V e h i c l e c a r l

= new

V e h i c l e О ;

c a r l . s M a n u f a c t u r e r

= "Studebaker" ;

c a r l . s M o d e l

= "Avanti" ;

// Следующий

код никак не влияет на c a r l

V e h i c l e c a r 2

= new

V e h i c l e ( ) ;

c a r 2 . s M a n u f a c t u r e r

= "Hudson";

c a r 2 . s M o d e l = " H o r n e t " ;

Создание объекта c a r 2 и присваивание ему имени и производителя никак не влияй] на объект c a r l .

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

С с ы л к и

Оператор "точка" и оператор присваивания — единственные два оператора, опреде­ ленные для ссылочных типов. Рассмотрим следующий фрагмент исходного текста:

//Создание нулевой ссылки

V e h i c l e yourCar;

//Присваивание значения ссылке

yourCar = new V e h i c l e ( ) ;

// Использование точки для обращения к члену yourCar . sManufacture r = "Rambler";

// Создание новой ссылки,

которая указывает на тот же объект

V e h i c l e yourSpousalCa r =

yourCar;

В первой строке создается объект yourCar, причем без присваивания ему значения, Такая неинициализированная ссылка называется нулевым объектом (null object). Любые попытки использовать неинициализированную ссылку приводят к немедленной генера­ ции ошибки, которая прекращает выполнение программы.

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

Второе выражение создает новый объект V e h i c l e и присваивает его ссылочной пе-1 ременной y o u r C a r . И последняя строка кода присваивает ссылке y o u r S p o u s a l C a r l

120

Часть III. Объектно-основанное программирование

ссылку yourCar. Как показано на рис. 6.1, это приводит к тому, что yourSpousalCa r

ссылается на тот же объект, что и yourCar.

Рис. 6.1. Взаимоотношения между дву­ мя ссылками на один и тот же объект

Эффект от следующих двух вызовов одинаков:

// Создание вашей

машины

Vehicle yourCar

=

new V e h i c l e () ;

yourCar. sModel

=

" K a i s e r " ;

//Эта машина принадлежит и вашей жене Vehicle yourSpousalCa r = yourCar;

//Изменяя одну машину, вы изменяете и другую

yourSpousalCar. sModel = "Henry J " ;

Console.WriteLine("Ваша машина - " + y o u r C a r . s M o d e l ) ;

Выполнение данной программы приводит к выводу на экран названия модели Henry J, а не Kaiser . Обратите внимание, что yourSpousalCa r не указывает на yourCar— вместо этого просто и yourSpousalCar , и yourCar указывают,на один и тот же объект.

Кроме того, ссылка y o u r S p o u s a l C a r будет корректна, даже если окажется "потерянной" (например, при выходе за пределы области видимости), как показано

вследующем фрагменте:

//Создание вашей машины

Vehicle yourCar

=

new V e h i c l e () ;

yourCar. sModel

=

" K a i s e r " ;

//Эта машина принадлежит и вашей жене Vehicle yourSpousalCa r = yourCar;

//Когда она забирае т с е б е вашу машину...

yourCar = n u l l ; // yourCar теперь ссылается на "нулевой

//объект"

//. . . yourSpousalCar ссылается на все ту же машину

Console.WriteLine("Ваша машина - " + y o u r S p o u s a l C a r . s M o d e l ) ;

Выполнение этого фрагмента исходного текста выводит на экран сообщение "Ваша машина - K a i s e r " несмотря на то, что ссылка yourCa r стала недейст­ вительной.

Объект перестал быть достижимым по ссылке yourCar. Но он не будет пол­ ностью недостижимым, пока не будут "потеряны" или обнулены обе ссылки — и yourCar, и yourSpousalCar .

После этого — вернее будет сказать, в некоторый непредсказуемый момент после этого — сборщик мусора (garbage collector) С# вернет память, использованную ранее под

Глава 6. Объединение данных - классы и массивы

121

объект, все ссылки на который утрачены. Дополнительные сведения о сборке мусора бу-1 дут приведены в конце главы 12, "Наследование".

К л а с с ы , с о д е р ж а щ и е к л а с с ы

Члены класса могут, в свою очередь, быть ссылками на другие классы. Например! транспортное средство имеет двигатель, свойствами которого являются, в частности! мощность и рабочий объем. Можно поместить эти параметры непосредственно в клася V e h i c l e следующим образом:

p u b l i c c l a s s V e h i c l e

{

 

 

p u b l i c

s t r i n g sModel;

p u b l i c

s t r i n g sManufacturer ;

p u b l i c

i n t

nNumOfDoors;

p u b l i c

i n t

nNumOfWheels;

p u b l i c

i n t

nPower;

p u b l i c

doubl e d i s p l a c e m e n t ;

}

//Модель

//Производитель

//Количество дверей

//Количество колес

//Мощность двигателя

//Рабочий объем

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

Двигатель является самодостаточной концепцией и может быть описан отдельным! классом:

p u b l i c c l a s s Motor

 

 

{

 

 

 

p u b l i c

i n t nPower;

//

Мощность

p u b l i c

doubl e d i s p l a c e m e n t ;

//

Рабочий объем

}

Вы можете внести этот класс в класс V e h i c l e следующим образом: p u b l i c c l a s s V e h i c l e

{

p u b l i c

s t r i n g sModel;

 

 

p u b l i c

s t r i n g sManufacturer ;

 

p u b l i c

i n t

nNumOfDoors;

 

p u b l i c

i n t

nNumOfWheels;

 

p u b l i c

Motor motor ;

}

/ / Модель / / Производитель

/ / Количество дверей / / Количество колес

Соответственно, создание s o n s C a r теперь выглядит так:

//Сначала создае м двигатель

Motor l a r g e r M o t o r

=

new M o t o r ( ) ;

largerMotor . nPowe r =

23 0;

l a r g e r M o t o r . d i s p l a c e m e n t = 4 . 0 ;

// Теперь создае м

автомобиль

V e h i c l e sonsCa r =

new V e h i c l e ( ) ;

sonsCar . sMode l =

"Cherokee S p o r t " ;

s o n s C a r . s M a n f a c t u r e r = " J e e p " ;

sonsCar.nNumOfDoors = 2;

sonsCar.nNumOfWheels

= 4;

//Присоединяем двигатель к автомобилю

sonsCar . moto r = l a r g e r M o t o r ;

122

Насть III. Объектно-основанное программирование

Доступ к рабочему объему двигателя из V e h i c l e можно получить в два этапа, как показано в приведенном фрагменте:

Motor m = sonsCar . motor ;

Console.WriteLine("Рабочий объем равен " + m . d i s p l a c e m e n t ) ; Однако можно получить эту величину и непосредственно:

Console.Writeline ("Рабочий объем равен " +

s o n s C a r . m o t o r . d i s p l a c e m e n t ) ;

Влюбом случае доступ к значению d i s p l a c e m e n t осуществляется через класс Motor.

Этот фрагмент взят из исходного текста программы VehicleAndMotor, которую можно найти на прилагаемом компакт-диске.

Статические ч л е н ы к л а с с а

Большинство членов-данных описывают отдельные объекты. Рассмотрим следующий

класс Саг:

 

 

public c l a s s Car

 

(

 

 

public

s t r i n g s L i c e n s e P l a t e ; // Номерной знак

автомобиля

I

 

 

Номерной

знак является свойством объекта, описывающим

каждый автомобиль

и уникальным для каждого автомобиля. Присваивание номерного знака одному автомо­

билю не меняет номерной знак другого:

Car cousinsCar = new Car () ;

cousinsCar. s L i c e n s e P l a t e

= "XYZ123";

Car yourCar = new Car () ;

 

yourCar. s L i c e n s e P l a t e =

"ABC789";

Однако имеются и такие свойства, которые присущи всем автомобилям. Например, количество выпущенных автомобилей является свойством класса Саг, но не отдельного объекта. Свойство класса помечается специальным ключевым словом s t a t i c , как пока­

зано в следующем фрагменте исходного текста:

 

public class Car

 

{

 

 

public

s t a t i c

 

int

nNumberOfCars; // Количество выпущенных

автомобилей

public

s t r i n g s L i c e n s e P l a t e ; // Номерной знак

автомобиля

}

Обращение к статическим членам выполняется не посредством объекта, а через сам класс, как показано в следующем фрагменте исходного текста:

// Создание нового объекта класса Саг

Car newCar = new Car () ; newCar.sLicensePlate = "ABC123";

// Увеличиваем количество автомобилей на 1

Car.nNumberOf Cars++ ;

(пава 6. Объединение данных - классы и массивы

123

О б р а щ е н ие к члену объекта

n e w C a r . s L i c e n s e P l a t e выполняется посред

ством объекта n e w C a r , в то

время как обращение к (статическому) члену

C a r . n N u m b e r O f C a r s осуществляется с п о м о щ ь ю имени класса. Все объект типа С а г совместно используют один и тот же член n N u m b e r O f C a r s .

Определение константных членов-данных

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

c l a s s P r o g r a m

{

/ / Ч и с л о д н е й в г о д у ( в к л ю ч а я в и с о к о с н ы й г о д )

p u b l i c

const i n t n D a y s I n Y e a r = 3 6 6 ;

p u b l i c

s t a t i c v o i d M a i n ( s t r i n g [ ] a r g s )

{

/ / Э т о м а с с и в — о н и х б у д е т р а с с к а з а н о н е м н о г о п о з ж е i n t [ ] n M a x T e m p e r a t u r e s = n e w i n t [ n D a y s I n Y e a r ] ;

f o r ( i n t i n d e x = 0 ; i n d e x < n D a y s I n Y e a r ; i n d e x + + )

{

/ / В ы ч и с л е н и е с р е д н е й т е м п е р а т у р ы д л я к а ж д о г о д н я г о д а

Константу n D a y s I n Y e a r можно использовать везде в вашей программе вместо ла 366. Константные переменные очень полезны, так как позволяют заме "магические числа" (в данном случае— 366) описательным именем n D a y s I n Y e a r , * повышает удобочитаемость программы и облегчает ее сопровождение.

С# имеет еще один способ объявления констант. Возможно, вам больше поим вится использовать не модификатор c o n s t , а модификатор r e a d o n l y :

p u b l i c readonly i n t n D a y s I n Y e a r = 3 6 6 ;

Как и при применении модификатора c o n s t , после того как вы присвоите конст инициализирующее значение, оно не может быть изменено нигде в программе. Xотя причины этого совета носят слишком технический характер, чтобы описывать их в стоящей книге, при объявлении констант предпочтительно использовать модификат r e a d o n l y .

Для констант имеется собственное соглашение по именованию. Вместо именован их так же, как и переменных (как в примере с n D a y s I n Y e a r ) многие программы предпочитают использовать прописные буквы с разделением слов подчеркиваниями DAYS_IN_YEAR. Такое соглашение ясно отделяет константы от обычных переменных.

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

124

Часть III. Объектно-основанное программирова

одна конструкция для хранения множества объектов, например, коллекции старинных автомобилей Билла Гейтса. Встроенный класс A r r a y представляет собой структуру, ко­ торая может содержать последовательности однотипных элементов (чисел типа i n t , double, объекты V e h i c l e и т.п.).

Зачем нужны массивы

Рассмотрим задачу определения среднего из десяти чисел с плавающей точкой. Каж­ дое из 10 чисел требует собственной переменной для хранения значения типа d o u b l e (усреднение целых чисел может привести к ошибке округления, описанной в главе 3, "Объявление переменных-значений"):

double dO = 5; double dl = 2 ; double d2 = 7; double d3 = 3 . 5 ; double d4 = 6 . 5 ; double d5 = 8; double d6 = 1; double d7 = 9; double d8 = 1; double d9 = 3;

Теперь нужно просуммировать все эти значения и разделить полученную сумму на 10:

double dSum = dO

+ dl

+ d2 + d3 + d4 +

d5 + d6

+ d7 + d8 + d9;

double dAverage =

dSum / 10;

Перечислять все элементы — очень утомительно, даже если их всего 10. А теперь

представьте, что вам надо усреднить 10000 чисел...

Массив фиксированного размера

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

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

double[] dArray = {5, 2, 7, 3 . 5 , 6 . 5 , 8, 1, 9, 1, 3} ;

Класс Array использует специальный синтаксис, который делает его более удобным в применении. Двойные квадратные скобки [] указывают на способ доступа к отдельным элементам массива:

dArray[0] соответствует dO dArray[1] соответствует dl

Нулевой элемент массива соответствует do, первый — dl и так далее.

Номера элементов массива — 0, 1, 2, ... — известны как их индексы.

(пава 6. Объединение данных

125

- классы и массивы

 

В С# индексы массивов начинаются с 0, а не с 1. Таким образом, элемент с индексом 1 не является первым элементом массива. Не забывайте об этом!

Использование d A r r a y было бы слабым улучшением, если бы в качестве индекса массива нельзя было использовать переменную. Применять цикл f o r существенно проще, чем записывать каждый элемент вручную, что и демонстрирует программа F i x e d A r r a y A v e r a g e .

11

' F i x e d A r r a y A v e r a g e

 

 

 

//

Усреднение

массива

чисел

фиксированного

р а з м е р а

с

/ / и с п о л ь з о в а н и е м ц и к л а

 

 

 

n a m e s p a c e

F i x e d A r r a y A v e r a g e

 

 

 

 

u s i n g

S y s t e m ;

 

 

 

 

 

p u b l i c

c l a s s

P r o g r a m

 

 

 

 

{

 

 

 

 

 

 

 

p u b l i c s t a t i c

v o i d M a i n ( s t r i n g [ ]

a r g s )

 

 

d o u b l e [ ]

d A r r a y =

 

 

 

{ 5 , 2 , 7 , 3 . 5 , 6 . 5 , 8 , 1 , 9 , 1 , 3 } ;

/ / Н а к о п л е н и е с у м м ы э л е м е н т о в / / м а с с и в а в п е р е м е н н о й d S u m d o u b l e d S u m = 0 ,-

f o r ( i n t i = 0 ; i < 1 0 ; i + + \

I

d S u m = d S u m + d A r r a y [ i ] ;

/ / В ы ч и с л е н и е с р е д н е г о з н а ч е н и я d o u b l e d A v e r a g e = d S u m / 1 0 ;

C o n s o l e . W r i t e L i n e ( d A v e r a g e ) ;

/ / О ж и д а е м п о д т в е р ж д е н и я п о л ь з о в а т е л я

C o n s o l e . W r i t e L i n e ( " Н а ж м и т е < E n t e r > д л я " +

" з а в е р ш е н и я п р о г р а м м ы . . . " ) ;

C o n s o l e . R e a d ( ) ;

Программа начинает работу с инициализации переменной d S u m значением 0. Затем программа циклически проходит по всем элементам массива d A r r a y и прибавляет га к dSum . По окончании цикла сумма всех элементов массива хранится в dSum . Раздели! ее на количество элементов массива, получаем искомое среднее значение.

Проверка границ массива

Программа F i x e d A r r a y A v e r a g e должна циклически проходить по массиву из 10 элементов. К счастью, цикл разработан так, что проходит ровно по 10 элементам мас­ сива. Ну а если была бы допущена ошибка и проход был бы сделан не по 10 элементам, а по иному их количеству? Следует рассмотреть два основных случая.

126

Часть III. Объектно-основанное программирование

Что произойдет при выполнении 9 итераций? С# не трактует такую ситуацию как ошибочную. Если вы хотите рассмотреть только 9 из 10 элементов, то как С# может указывать вам, что именно вам нужно делать? Конечно, среднее значение при этом будет неверным, но программе это неизвестно.

Что произойдет при выполнении 11 (или большего количества) итераций?

В этом случае С# примет свои меры и не позволит индексу выйти за дозволенные пре­ делы, чтобы вы не смогли случайно переписать какие-нибудь важные данные впамяти. Чтобы убедиться в этом, измените сравнение в цикле f o r , заменив 10 на 11: for (in t i = 0 ; i < 1 1 ; i + +)

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

ем об ошибке:

 

I n d e x O u t O f R a n g e E x c e p t i o n w a s

u n h a n d l e d

Index was o u t s i d e t h e b o u n d s

o f t h e a r r a y .

Здесь C# сообщает о происшедшей неприятности— исключении I n d e x O u t O f ­ RangeException, из названия которого и из поясняющего текста становится понят­ на причина ошибки, — выход индекса за пределы допустимого диапазона. (Кроме этого, выводится детальная информация о том, где именно и что произошло, но пока то вы не настолько знаете С#, чтобы разобраться в этом.)

Массив переменного размера

Массив, используемый в программе F i x e d A r r a y A v e r a g e , сталкивается с двумя серьезными проблемами:

его размер фиксирован и равен 10 элементам;

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

Значительно более гибкой была бы программа, которая могла бы считывать переменной количество значений, вводимое пользователем, ведь она могла бы работать не только с определенными в программе F i x e d A r r a y A v e r a g e значениями, но и с другими мно­ жествами значений.

Формат объявления массива переменного размера немного отличается от объявления «ива фиксированного размера:

doublet] d A r r a y = n e w d o u b l e [ N ] ;

Здесь N — количество элементов в выделяемом массиве.

Модифицированная версия программы V a r i a b l e A r r a y A v e r a g e позво­ ляет пользователю указать количество вводимых значений. Поскольку про­ грамма сохраняет введенные значения, она может не только вычислить среднее значение, но и вывести результат в удобном виде.

;// V a r i a b l e A r r a y A v e r a g e

 

 

 

 

 

//Вычисление

с р е д н е г о

з н а ч е н и я

м а с с и в а ,

р а з м е р к о т о р о г о

//указывается

п о л ь з о в а т е л е м

в о

в р е м я

р а б о т ы п р о г р а м м ы .

[// Накопление

в в е д е н н ы х

д а н н ы х

в м а с с и в е

п о з в о л я е т

[//обращаться

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

[//привлекательно в ы г л я д я щ е г о

в ы в о д а

н а

э к р а н .

Гюва 6, Объединение данных - классы и массивы

127

n a m e s p a c e V a r i a b l e A r r a y A v e r a g e

{

u s i n g S y s t e m ;

 

p u b l i c c l a s s P r o g r a m

 

{

 

p u b l i c s t a t i c v o i d M a i n ( s t r i n g [ ]

a r g s )

{

/ / С н а ч а л а с ч и т ы в а е т с я к о л и ч е с т в о ч и с е л т и п а d o u b l e , / / к о т о р о е п о л ь з о в а т е л ь н а м е р е н в в е с т и д л я у с р е д н е н и я

C o n s o l e . W r i t e ( " В в е д и т е к о л и ч е с т в о у с р е д н я е м ы х ч и с е л : " ) ; s t r i n g s N u m E l e m e n t s = C o n s o l e . R e a d L i n e О ;

i n t n u m E l e m e n t s = C o n v e r t . T o I n t 3 2 ( s N u m E l e m e n t s ) ; C o n s o l e . W r i t e L i n e ( ) ;

/ / О б ъ я в л я е м м а с с и в н е о б х о д и м о г о р а з м е р а

d o u b l e [ ] d A r r a y = n e w d o u b l e [ n u m E l e m e n t s ] ;

/ / Н а к а п л и в а е м з н а ч е н и я в м а с с и в е

f o r ( i n t i = 0 ; i < n u m E l e m e n t s ; i + + )

{

/ / П р и г л а ш е н и е п о л ь з о в а т е л ю д л я в в о д а ч и с е л

C o n s o l e . W r i t e ( " В в е д и т е ч и с л о т и п а d o u b l e № " + ( i + 1) + " : " ) ;

s t r i n g s V a l = C o n s o l e . R e a d L i n e ( ) ;

d o u b l e d V a l u e = C o n v e r t . T o D o u b l e ( s V a l ) ;

/ / В н о с и м ч и с л о в м а с с и в

d A r r a y [ i ] = d V a l u e ;

}

/ / С у м м и р у е м ' n u m E l e m e n t s ' з н а ч е н и й и з м а с с и в а в / / п е р е м е н н о й d S u m

d o u b l e d S u m = 0 ;

f o r ( i n t i = 0; i < n u m E l e m e n t s , - i + + )

{

d S u m = d S u m + d A r r a y [ i ] ;

}

/ / В ы ч и с л я е м с р е д н е е

d o u b l e d A v e r a g e = d S u m / n u m E l e m e n t s ;

/ / В ы в о д и м р е з у л ь т а т н а э к р а н C o n s o l e . W r i t e L i n e ( ) ;

C o n s o l e . W r i t e ( d A v e r a g e

+ " я в л я е т с я с р е д н и м и з ( " + d A r r a y [0 ] ) ,-

f o r ( i n t i = 1; i < n u m E l e m e n t s , - i + + )

{

C o n s o l e . W r i t e ( " + " + d A r r a y [ i ] ) ;

}

C o n s o l e . W r i t e L i n e ( " ) / " + n u m E l e m e n t s ) ;

128

Часть III. Объектно-основанное программирован