Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
A.doc
Скачиваний:
36
Добавлен:
09.04.2015
Размер:
5.6 Mб
Скачать

232 Глава 5

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

Как вы можете видеть из вывода перед первым вызовом lowest (), третий элемент массива, array [2], содержит минимальное значение, так что функция возвращает ссылку на него и его значение изменяется на б. 9. Аналогично, после второго вызова array [ 10 ] изменяется на 7 . 9. Это достаточно ясно демонстрирует, что возврат ссыл- ки позволяет использовать функцию в левой части оператора присваивания.

Конечно, при желании вы можете использовать ее и в правой части присваива- ния или в составе любых других подходящих выражений. Если есть два массива — X и Y — с количеством элементов, указанным соответственно в lenx и leny, вы можете присвоить минимальному элементу массива х удвоенное значение удвоенного мини- мального элемента у в следующем операторе:

Этот оператор должен вызвать функцию lowest () дважды — один раз с аргумен- тами у и leny в выражении правой части присваивания и один — с аргументами х и lenx для получения адреса, куда должен быть сохранен результат правого выраже- ния.

Еще одно железное правило: возврат ссылок

То же правило, которое применяется к возврату указателей из функций, также ка- сается возврата ссылок.

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

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

Статические переменные в функциях

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

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

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

Структурная организация программ 233

используется точно такая же форма объявления static переменной, как вы уже ви- дели в главе 2. Например, чтобы объявить переменную count как static, можно вос- пользоваться таким оператором:

Это также инициализирует ее нулем.

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

Следующий простой пример демонстрирует поведение статической переменной в функции.