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

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

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

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

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

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

139

Глава 7

Функции функций

>Определение функции

>Передача аргументов в функцию

>Получение результата из функции

>Передача аргументов программе

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

с единым целым может справиться один человек.

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

Рассмотрим следующий пример:

class

E x a m p l e

 

 

 

 

 

 

 

p u b l i c i n t n l n t ;

 

 

/ / H e

с т а т и ч е с к и й

ч л е н

p u b l i c

s t a t i c

i n t

n S t a t i c I n t

/ /

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

p u b l i c v o i d M e m b e r F u n c t i o n ( )

/ / H e

с т а т и ч е с к а я

ф у н к ц и я

{

 

 

 

 

 

 

 

 

 

C o n s o l e . W r i t e L i n e ( " Э т о

ф у н к ц и я - ч л е н " ) ;

 

}

 

 

 

 

 

 

 

^

 

p u b l i c

s t a t i c

v o i d

C l a s s F u n c t i o n ( )

/ / С т а т и ч е с к а я ф у н к ц и я

{

 

 

 

 

 

 

 

 

 

C o n s o l e . W r i t e L i n e ( " Э т о

ф у н к ц и я

к л а с с а " ) ;

 

}

Элемент n l n t является членом-данными, с которыми вы познакомились в главе 6, "Объединение данных— классы и массивы". Однако элемент M e m b e r F u n c t i o n () для вас нов. Он известен как функция-член, представляющая собой набор кода С#, который может быть выполнен с помощью ссылки на имя этой функции. Честно говоря, такое определение смущает даже меня самого, так что лучше рассмотреть, что такое функция, на примерах.

Примечание: отличие между статическими и нестатическими функциями крайне важно. Частично эта тема будет раскрыта в данной главе, но более подробно об этом

речь пойдет в главе 8, "Методы класса", где будет введен термин метод, очень распрестраненный в объектно-ориентированных языках программирования наподобие С# л обозначения нестатических функций классов.

В следующем фрагменте присваиваются значения члену объекта n l n t и члену класш (статическому члену) n S t a t i c I n t :

E x a m p l e

e x a m p l e

n e w E x a m p l e ( ) ; / / С о з д а н и е о б ъ е к т а

e x a m p l e . n l n t

1 ;

/ / И н и ц и а л и з а ц и я

ч л е н а с

 

 

 

/ /

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

о б ъ е к т а

E x a m p l e . n S t a t i c I n t

=2 ;

/ / И н и ц и а л и з а ц и я

ч л е н а с

 

 

 

/ /

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

к л а с с а

Практически аналогично в приведенном далее фрагменте происходит обращение (путем вызова) к функциям M e m b e r F u n c t i o n () и C l a s s F u n c t i o n ( ) :

E x a m p l e e x a m p l e = n e w E x a m p l e ( ) ;

/ / С о з д а н и е о б ъ е к т а

e x a m p l e . M e m b e r F u n c t i o n ( ) ;

/ / В ы з о в ф у н к ц и и - ч л е н а

/ /

с у к а з а н и е м о б ъ е к т а

E x a m p l e . C l a s s F u n c t i o n ( ) ;

/ / В ы з о в ф у н к ц и и к л а с с а с

/ / у к а з а н и е м к л а с с а

/ / П р и в е д е н н ы е д а л е е с т р о к и н е к о м п и л и р у ю т с я

e x a m p l e . C l a s s F u n c t i o n ( ) ;

/ / Н е л ь з я о б р а щ а т ь с я к ф у н к ц и и

/ /

к л а с с а

с у к а з а н и е м о б ъ е к т а

E x a m p l e . M e m b e r F u n c t i o n ( ) ;

/ / Н е л ь з я о б р а щ а т ь с я к ф у н к ц и и -

/ / ч л е н у с у к а з а н и е м к л а с с а

Отличие между функциями класса (статическими) и функциями-членами (нестатическими), или методами, отражает различие между переменными клас­ са (статическими) и переменными-членами (нестатическими), описанное ранее! в главе 6, "Объединение данных — классы и массивы".

Выражение e x a m p l e . M e m b e r F u n c t i o n () передает управление коду, содержаще муся внутри функции. Процесс вызова E x a m p l e . C l a s s F u n c t i o n () практически та кой же. В результате выполнения приведенного выше фрагмента кода получается сл дующий вывод на экран:

Э т о ф у н к ц и я - ч л е н Э т о ф у н к ц и я к л а с с а

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

Я включаю круглые скобки при указании функций в тексте — наприме M a i n () — чтобы функции было легче распознать. Без этого упоминания их

втексте можно легко спутать с переменными или классами.

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

142

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

В этом разделе в качестве демонстрации того, как разумное определение функций может помочь сделать программу проще для написания и понимания, будет взята моно­ литная программа C a l c u l a t e l n t e r e s t T a b l e из главы 5, "Управление потоком вы­ полнения", и разделена на несколько функций. Такой процесс переделки рабочего кода при сохранении его функциональности называется рефакторингом, и Visual Studio 2005 обеспечивает удобное меню Refactor, которое автоматизирует большинство распростра­ ненных задач рефакторинга.

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

Чтение комментариев при опущенном программном коде должно способство­ вать пониманию намерений программиста. Если это не так — значит, вы плохо комментируете ваши программы. (И наоборот, если вы не можете, опустив большинство комментариев, понять, что делает программа на основании имен функций, значит, вы недостаточно ясно именуете функции и/или делаете их слишком большими).

"Скелет" программы C a l c u l a t e l n t e r e s t T a b l e выглядит следующим образом: 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 )

{

/ / П р и г л а ш е н и е в в е с т и н а ч а л ь н ы й в к л а д .

/ /

Е с л и в к л а д о т р и ц а т е л е н , г е н е р и р у е т с я с о о б щ е н и е о б

/ /

о ш и б к е .

/ / П р и г л а ш е н и е д л я в в о д а п р о ц е н т н о й с т а в к и .

/ / Е с л и п р о ц е н т н а я с т а в к а о т р и ц а т е л ь н а , г е н е р и р у е т с я / / с о о б щ е н и е о б о ш и б к е .

/ / П р и г л а ш е н и е для, в в о д а к о л и ч е с т в а л е т . / / В ы в о д в в е д е н н ы х д а н н ы х .

/ / Ц и к л п о в в е д е н н о м у к о л и ч е с т в у л е т . w h i l e ( n Y e a r < = n D u r a t i o n )

{

// В ы ч и с л е н и е з н а ч е н и я в к л а д а с н а ч и с л е н н ы м и

•*.

II

п р о ц е н т а м и .

 

/ / В ы в о д р е з у л ь т а т а в ы ч и с л е н и й .

}

}

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

I / часть начального ввода данных, в которой пользователи вводят вклад, процент­ ную ставку и срок;

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

I J последняя часть кода, создающая и выводящая таблицу на экран.

Глава 7, Функции функций

143

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

вклада,

процентной ставки и

срока практически один и тот же. Это наблюдение дает еще одну точку для рефакторинга.

Все перечисленное позволяет выполнить рефакторинг программы Calcl l a t e l n t e r e s t T a b l e и создать программу C a l c u l a t e l n t e r e s t T a b l e W i t h F u n c t i o n s .

/ / C a l c u l a t e I n t e r e s t T a b l e W i t h F u n c t i o n s

// Генерация таблицы роста вклада по тому же алгоритму, что

//и ранее рассматривавшихся программах, однако в этой

//программе работа распределена между несколькими

//функциями.

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

n a m e s p a c e

C a l c u l a t e I n t e r e s t T a b l e W i t h F u n c t i o n s

{

 

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 )

{

//Раздел 1 - ввод данных, необходимых для создания

//таблицы

d e c i m a l m P r i n c i p a l = 0 ; d e c i m a l m l n t e r e s t = 0,- d e c i m a l m D u r a t i o n = 0 ;

I n p u t l n t e r e s t D a t a ( r e f m P r i n c i p a l , r e f m l n t e r e s t , r e f m D u r a t i o n ) ;

//Раздел 2 - проверка введенных данных путем вывода

//их пользователю на экран

C o n s o l e . W r i t e L i n e ( ) ;

/ / s k i p a . l i n e

 

C o n s o l e . W r i t e L i n e ( " В к л а д

= " +

m P r i n c i p a l ) ;

 

C o n s o l e . W r i t e L i n e ( " П р о ц е н т н а я ставка = " +

m l n t e r e s t +

" % " ) ;

C o n s o l e . W r i t e L i n e ( " С р о к

= " +

m D u r a t i o n + . " лет");

C o n s o l e . W r i t e L i n e ( ) ;

//Раздел 3 - и, наконец, вывод таблицы вкладов по

//годам

O u t p u t l n t e r e s t T a b l e ( m P r i n c i p a l , m l n t e r e s t , m D u r a t i o n ) ;

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

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

C o n s o l e . W r i t e L i n e ( " Н а ж м и т е

< E n t e r > для " +

744

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

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

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

}

/ / I n p u t l n t e r e s t D a t a - к л а в и а т у р н ы й в в о д в к л а д а , / / п р о ц е н т н о й с т а в к и и с р о к а д л я р а с ч е т а т а б л и ц ы

//Эта функция реализует раздел 1, разбивая его на три

//компонента

p u b l i c

s t a t i c

v o i d

I n p u t l n t e r e s t D a t a ( r e f

 

r e f

 

r e f

d e c i m a l d e c i m a l d e c i m a l

m P r i n c i p a l , m l n t e r e s t , m D u r a t i o n )

{

/ / l a П о л у ч е н и е в к л а д а

m P r i n c i p a l

= I n p u t P o s i t i v e D e c i m a l ( " в к л а д " ) ;

/ / 1 6 П о л у ч е н и е п р о ц е н т н о й с т а в к и

m l n t e r e s t =

I n p u t P o s i t i v e D e c i m a l ( " п р о ц е н т н а я с т а в к а " ) ;

// 1в П о л у ч е н и е с р о к а

m D u r a t i o n = I n p u t P o s i t i v e D e c i m a l ( " с р о к " ) ;

}

/ / I n p u t P o s i t i v e D e c i m a l - в о з в р а щ а е т п о л о ж и т е л ь н о е ч и с л о / / т и п а d e c i m a l с к л а в и а т у р ы .

/ / В ы п о л н я е т с я т о л ь к о о д н а п р о в е р к а - н а / / н е о т р и ц а т е л ь н о с т ь в в е д е н н о г о з н а ч е н и я . p u b l i c s t a t i c

d e c i m a l I n p u t P o s i t i v e D e c i m a l ( s t r i n g s P r o m p t )

{

/ / Ц и к л в ы п о л н я е т с я , п о к а н е б у д е т в в е д е н о в е р н о е / / з н а ч е н и е

w h i l e ( t r u e )

{

/ / П р и г л а ш е н и е д л я в в о д а

C o n s o l e . W r i t e ( " В в е д и т е " + s P r o m p t + " : " ) ;

/ / П о л у ч е н и е з н а ч е н и я т и п а d e c i m a l с к л а в и а т у р ы s t r i n g s l n p u t = C o n s o l e . R e a d L i n e ( ) ;

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

/ / В ы х о д и з ц и к л а п р и в в о д е к о р р е к т н о г о з н а ч е н и я i f ( m V a l u e > = 0 )

{

/ / В о з в р а т в в е д е н н о г о з н а ч е н и я r e t u r n m V a l u e ;

}

/ / В п р о т и в н о м с л у ч а е г е н е р и р у е т с я и в ы в о д и т с я / / с о о б щ е н и е о б о ш и б к е

C o n s o l e . W r i t e L i n e ( s P r o m p t +

Глава 7. Функции функций

145

" н е м о ж е т и м е т ь о т р и ц а т е л ь н о е з н а ч е н и е " ) ; 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 L i n e ( ) ;

}

}

/ / O u t p u t l n t e r e s t T a b l e / / п р о ц е н т н о й с т а в к и и / / э к р а н т а б л и ц у р о с т а

- д л я з а д а н н ы х з н а ч е н и й в к л а д а , с р о к а г е н е р и р у е т и в ы в о д и т н а в к л а д а

// Реализация раздела 3 основной программы

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

v o i d O u t p u t l n t e r e s t T a b l e ( d e c i m a l d e c i m a l d e c i m a l

m P r i n c i p a l , m l n t e r e s t , m D u r a t i o n )

{

f o r ( i n t n Y e a r = 1 ; n Y e a r < = m D u r a t i o n ; n Y e a r + + )

{

/ / В ы ч и с л е н и е н а ч и с л е н н ы х п р о ц е н т о в d e c i m a l m l n t e r e s t P a i d ;

m l n t e r e s t P a i d = m P r i n c i p a l * ( m l n t e r e s t / 1 0 0 ) ;

/ / В ы ч и с л е н и е з н а ч е н и я н о в о г о в к л а д а п у т е м / / д о б а в л е н и я н а ч и с л е н н ы х п р о ц е н т о в к о с н о в н о м у / / в к л а д у

m P r i n c i p a l = m P r i n c i p a l + m l n t e r e s t P a i d ;

/ / О к р у г л е н и е в к л а д а д о к о п е е к

m P r i n c i p a l = d e c i m a l . R o u n d ( m P r i n c i p a l , 2 ) ;

/ / В ы в о д р е з у л ь т а т а

C o n s o l e . W r i t e L i n e ( n Y e a r + " - " + m P r i n c i p a l ) ;

}

}

}

}

Раздел M a i n () разделен на три очевидные части, каждая из которых выделена и ментарием с полужирным шрифтом. Кроме того, первая часть, в свою очередь, подела на три подраздела — 1а, 1би 1в.

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

В первой части для ввода значений трех переменных, необходимых для работы про граммы ( m P r i n c i p a l , m l n t e r e s t и м m D u r a t i o n ) , вызывается функция I n p u t l n t e r e s t D a t a ( ) . Во второй части полученные значения выводятся на экран так же, и и в предыдущих версиях программы. Последняя часть строит и выводит на экран таблица цу вкладов с помощью функции O u t p u t l n t e r e s t T a b l e ( ) .

Начнем с конца, с функции O u t p u t l n t e r e s t T a b l e ( ) . В ней содержится цш в котором выполняется вычисление начисленных процентов — в точности так же, ю

146

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

это делалось в программе C a l c u l a t e l n t e r e s t T a b l e в главе 5, "Управление потоком выполнения". Преимущество данной версии заключается в том, что при разработке этой части кода не нужно сосредотачиваться на деталях ввода и верификации данных. При написании этой функции следует просто думать о том, как вычислить и вывести таблицу для уже полученных значений. После выполнения функции управление вернется в стро­ ку, следующую за вызовом функции O u t p u t l n t e r e s t T a b l e ( ) .

O u t p u t l n t e r e s t T a b l e ! ) — хороший повод для того, чтобы воспользо­ ваться новым меню Refactoring в Visual Studio 2005. Для этого надо выполнить следующие действия.

1.Воспользоваться в качестве стартовой точки примером CalculatelnterestTableMoreForgiving из главы 5, "Управление потоком выполнения", вы­ брав исходный текст от объявления переменной nYear до конца цикла while:

i n t n Y e a r =

0 ;

/ / П е р е м е н н а я ц и к л а

w h i l e ( n Y e a r

< = n D u r a t i o n )

/ / и в е с ь ц и к л w h i l e

{

 

 

//...

}

2.Выбрать команду меню Refactor^Extract Method.

3.В диалоговом окне Extract Method ввести O u t p u t l n t e r e s t T a b l e , затем

просмотреть поле Preview Method Signature и щелкнуть на кнопке ОК.

Обратите внимание, что предложенная "сигнатура" нового "метода" начинается с ключевых слов p r i v a t e s t a t i c и включает m P r i n c i p a l , m l n t e r e s t и n D u r a t i o n в круглых скобках. О ключевом слове p r i v a t e , как альтернативе p u b l i c , будет рассказано в главе 11, "Классы". Пока же вы можете при желании сделать эту функцию p u b l i c .

Результат такого рефакторинга заключается в следующем.

/ Ниже функции M a i n ( ) p u t l n t e r e s t T a b l e

добавляется новая p r i v a t e s t a t i c функция O u t ­ ( ) .

/Там, где в функции M a i n () находился выбранный код, появляется следующая строка:

m P r i n c i p a l = O u t p u t l n t e r e s t T a b l e ( m P r i n c i p a l ,

m l n t e r e s t , n D u r a t i o n ) ;

Точно такой же подход "разделяй и властвуй" применим и для функции I n p u t l n ­ t e r e s t D a t a ( ) . Однако в этом случае требуется более сложный рефакторинг, так что я выполнил его вручную и все его этапы здесь не показаны. Все же искусство рефакто­ ринга выходит за рамки настоящей книги.

В функции I n p u t l n t e r e s t D a t a () вы сосредотачиваетесь только на вводе трех зна­ чений типа d e c i m a l . В данном случае, несмотря на три различные переменные, действия по их вводу оказываются идентичны и могут быть размещены в функции I n p u t P o s i ­ tiveDecimal ( ) , которая одинаково применима как для ввода вклада, так и для ввода процентной ставки и срока, для которого выполняется расчет. Заметьте, как три цикла while в исходной программе превратились в один в теле функции I n p u t P o s i ­ t i v e D e c i m a l ( ) . Тем самым устранено дублирование кода, которое всегда нежелательно.

[пава 7. Функции функций

147

Внесение в программу модификаций, делающих ее понятнее и проще, не га няя при этом ее функциональность и внешнее поведение, называется рефак рингом. Большое количество информации о нем можно найти на Web-ca w w w . r e f a c t o r i n g . c o m .

Функция I n p u t P o s i t i v e D e c i m a l () выводит приглашение и ожидает ввода по] зователя. Если введенное пользователем значение неотрицательно, она возвращает вызвавшей ее функции. Если же введенное значение отрицательно, функция выводит! общение об ошибке и повторяет цикл ввода.

С точки зрения пользователя получается та же программа, что и раньше (в глав "Управление потоком выполнения"), поскольку работает она в точности так же:

В в е д и т е

в к л а д : 1 0 0

В в е д и т е

п р о ц е н т н у ю с т а в к у : - 1 0

П р о ц е н т н а я с т а в к а н е м о ж е т б ы т ь о т р и ц а т е л ь н а

П о п р о б у й т е е щ е р а з

В в е д и т е

п р о ц е н т н у ю с т а в к у : 1 0

В в е д и т е

с р о к : 1 0

В к л а д

=

10 0

П р о ц е н т н а я

с т а в к а =

10%

С р о к

=

1 0 л е т

1 - 1 1 0 . 0

2 - 1 2 1 . 0 0

3 - 1 3 3 . 1 0

4 - 1 4 6 . 4 1

5 - 1 6 1 . 0 5

6 - 1 7 7 . 1 6

7 - 1 9 4 . 88

8 - 2 1 4 . 3 7

9 - 2 3 5 . 8 1

1 0 - 2 5 9 . 3 9

Н а ж м и т е < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы . . .

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

Зачем беспокоиться о функциях?

Когда концепция функции появилась в 1950-е годы в Фортране, ее единственной целы! было избежать дублирования кода. Предположим, вы пишете программу, которая доли вычислять и выводить на экран некоторое отношение во многих местах. В этом случае программа может просто вызывать в этих местах функцию D i s p l a y R a t i o ( ) , позво­ ляющую избежать дублирования кода. Такая экономия может показаться не слишком большой, если функция состоит всего из пары строк, но функции бывают разные; они мо­ гут быть очень сложными и большими. Кроме того, распространенные функции, наподо­ бие W r i t e L i n e ( ) , MOiyr использоваться в сотнях различных мест.

Второе преимущество применения функций также очевидно: проще корректно напи сать и отладить одну функцию, чем десяток фрагментов кода, и вдвойне проще еле лать это, если функция невелика. Функция D i s p l a y R a t i o () включает проверку то-

148

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

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

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

Функция наподобие c a l c u l a t e S i n () служит идеальным примером. Программист, реализуя сложные вычисления, совершенно не должен беспокоиться, как именно бу­ дут применены их результаты. Прикладной программист может использовать функ­ цию c a l c u l a t e S i n ( ) , не интересуясь, как именно она устроена и работает. Этот подход существенно снижает количество вещей, о которых должен думать и пережи­ вать прикладной программист. Большую работу гораздо проще сделать, если разде­ лить ее на несколько частей.

Большие программы, как, например, текстовый редактор, строятся из множества функций разного уровня абстракции. Например, функция R e d i s p l a y D o c u m e n t () должна вызы­ вать функцию R e p a r a g r a p h () для вывода абзацев документа. Эта функция, в свою оче­ редь, должна вызывать функцию C a l c u l a t e W o r d W r a p () для вычисления длин отдель­ ных строк абзаца. Функция C a l c u l a t e W o r d W r a p () может вызывать функцию L o o k - UpWordBreak ( ) , определяющую, как должно быть разбито для переноса слово, стоящее в конце строки. Каждая из перечисленных функций решает одну задачу, кото­ рую можно сформулировать простым предложением (кстати, обратите внимание и на информативность названий функций).

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

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

public s t a t i c v o i d O u t p u t

( )

(

 

C o n s o l e . W r i t e L i n e ( " Э т о

ф у н к ц и я " ) ;

}

Сравним этот пример с реальными функциями. Например, функция вычисления синуса требует определенных входных данных — в конце концов, вы ведь вычисляете синус чегото? Аналогично, при конкатенации двух строк нужно передать функции две строки — не так ли? И получить от функции результаты ее работы? Следовательно, возникает край­ няя необходимость в механизме обмена информацией с функцией.

Шва 7. Функции функций

149