ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.12.2025

Просмотров: 3192

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Что произойдет при выполнении 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. Объектно-основанное программирован


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

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

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 ( ) ;

 

Вот как выглядит вычисление среднего для чисел от 1 до 5:

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

ч и с е л : 5

Введите

ч и с л о

Введите

ч и с л о

Введите

ч и с л о

Введите

ч и с л о

Введите

ч и с л о

ти п а

ти п а

ти п а

ти п а

ти п а

d o u b l e

№ 1 :

1

d o u b l e

№ 2 :

2

d o u b l e

№ 3 :

3

d o u b l e

№4:

4

d o u b l e

№ 5 :

5

3 я в л я е т с я с р е д н и м и з ( 1 + 2 + 3 + 4 + 5 ) / 5 Нажмите < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы . . .

Программа V a r i a b l e A r r a y A v e r a g e начинается с вывода приглашения пользова­ телю указать количество значений, которые будут введены далее и которые требуется усреднить. Введенное значение сохраняется в переменной n u m E l e m e n t s типа i n t . В представленном примере здесь оказывается введено число 5.

Затем программа выделяет память для нового массива d A r r a y с указанным количе­ ством элементов. В данном случае программа это делает для массива, состоящего из пя­ ти элементов типа d o u b l e . Программа выполняет n u m E l e m e n t s итераций цикла, счи­ тывая вводимые пользователем значения и заполняя ими массив.

После того как пользователь введет указанное им ранее число данных, программа ис­ пользует тот же алгоритм, что и в программе F i x e d 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 , возможно, не удовлетворяет вашим пред­ ставлениям о гибкости. Может статься, что вам бы хотелось позволить пользовате­ лю вводить числа, а после ввода какого-то очередного числа дать команду вычис­ лить среднее значение введенных чисел. Кроме массивов, С# предоставляет про­ граммисту и другие типы коллекций; некоторые из них могут при необходимости увеличивать или уменьшать свой размер. В главе 15, "Обобщенное програм­ мирование", вы познакомитесь с такими альтернативами массивам.

Свойство Length

В программе V a r i a b l e A r r a y A v e r a g e для заполнения массива использован цикл for:

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

129


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

d o u b l e t ] 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 ;

 

}

 

 

Массив d A r r a y объявлен как

и м е ю щ и й длину n u m E l e m e n t s . Таким образом, по­

нятно, почему цикл выполняет именно n u m E l e m e n t s итераций для прохода по массиву. Вообще говоря, не слишком-то и удобно таскать повсюду вместе с массивом пер(

менную, в которой хранится его

длина. Но, к счастью, это не является неизбежными

у массива есть свойство L e n g t h ,

которое содержит его длину, так что d A r r a y . Lengtkl

в данном случае содержит то же значение, что и n u m E l e m e n t s .

Таким образом, предпочтительнее использовать такой вид цикла f o r :

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

f o r ( i n t i = 0 ; i < d A r r a y . L e n g t h ; i + + )

О т л и ч ие массивов фиксированной и переменной д л и н ы

С первого взгляда бросается в глаза, насколько отличается синтаксис массивов фик|

сированной и переменной длины:

 

d o u b l e [ ]

d F i x e d L e n g t h A r r a y =

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

d o u b l e t ]

d V a r i a b l e L e n g t h A r r a y

= n e w d o u b l e [ 1 0 ] ;

Однако C# пытается сэкономить ваши усилия, а потому позволяет Использовать ита| кой код для выделения памяти для массива с его одновременной инициализацией:

d o u b l e t ] d F i x e d L e n g t h A r r a y =

n e w d o u b l e [ 1 0 ] { 5 , 2 , 7 , 3 . 5 , 6 . 5 , 8 , 1 , 9 , 1 , 3 } ;

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

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

p u b l i c c l a s s S t u d e n t

{

p u b l i c

s t r i n g

p u b l i c

d o u b l e

s N a m e ;

d G P A ; / / С р е д н и й б а л л

}

130

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


Этот простейший класс содержит только имя студента и его успеваемость. В следующем фрагменте объявляется массив из n u m ссылок на объекты типа S t u d e n t :

Student [ ] s t u d e n t s

= n e w S t u d e n t [ n u m ] ;

Выражение n e w

S t u d e n t [num] объявляет не массив объектов S t u d e n t ,

а массив ссылок на объекты S t u d e n t .

Итак, каждый элемент s t u d e n t s [ i ] представляет собой ссылку на нулевой объект, так как С# инициализирует новые, неопределенные объекты значением n u l l . Можно сформулировать это и иначе, сказав, что ни один из элементов s t u d e n t s [ i ] после вы­ полнения рассматриваемого оператора n e w не ссылается на объект типа S t u d e n t . Так что сначала вы должны заполнить массив следующим образом:

for ( i n t i = 0;

i < s t u d e n t s . L e n g t h ; i + +)

{

 

s t u d e n t s [ i ]

= n e w S t u d e n t ( ) ;

}

Теперь в программе можно вводить свойства отдельных студентов таким образом:

s t u d e n t s [ i ]

= n e w S t u d e n t ( ) ;

s t u d e n t s

[ i ]

. s N a m e

=

"My N a m e " ;

s t u d e n t s

[ i ]

. dGPA

=

dMyGPA;

Все это можно увидеть в программе A v e r a g e S t u d e n t G P A , которая полу­ чает информацию о студентах и вычисляет их среднюю успеваемость.

//A v e r a g e S t u d e n t G P A

/ / В ы ч и с л я е т с р е д н ю ю у с п е в а е м о с т ь м н о ж е с т в а с т у д е н т о в . using S y s t e m ;

namespace

A v e r a g e S t u d e n t G P A .

f

 

p u b l i c

c l a s s S t u d e n t

{

 

p u b l i c

s t r i n g

p u b l i c

d o u b l e

s N a m e ; d G P A ;

/ / С р е д н и й б а л л

}

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 )

{

/ / О п р е д е л я е м к о л и ч е с т в о с т у д е н т о в

C o n s o l e . W r i t e L i n e ( " В в е д и т е к о л и ч е с т в о с т у д е н т о в " ) ; s t r i n g s = C o n s o l e . R e a d L i n e ( ) ;

i n t n N u m b e r O f S t u d e n t s = C o n v e r t . T o I n t 3 2 ( s ) ; / / В ы д е л я е м м а с с и в о б ъ е к т о в S t u d e n t

S t u d e n t [ ] s t u d e n t s = n e w S t u d e n t [ n N u m b e r O f S t u d e n t s ] ;

/ / З а п о л н я е м f o r ( i n t i =

м а с с и в

0; i < s t u d e n t s . L e n g t h ; i + + )

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

131