logo
Харви Дейтел, Пол Дейтел Как программировать на С++ / 02-Deitel-Стр-115-214

202 Глава 3

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

Идентификаторы, объявленные внутри блока (на внутреннем уровне), имеют областью действия блок. Область действия блок начинается объяв­лением идентификатора и заканчивается конечной правой фигурной скобкой блока. Локальные переменные, объявленные в начале функции, имеют об­ластью действия блок так же, как и параметры функции, являющиеся ло­кальными переменными. Любой блок может содержать объявления перемен­ных. Если блоки вложены и идентификатор во внешнем блоке имеет такое же имя, как идентификатор во внутреннем блоке, идентификатор внешнего блока «невидим» (скрыт) до момента завершения работы внутреннего блока. Это означает, что пока выполняется внутренний блок, он видит значение своих собственных локальных идентификаторов, а не значения идентифика­торов с идентичными именами в охватывающем блоке. Локальные перемен­ные, объявленные как static, имеют областью действия блок, несмотря на то, что они существуют с самого начала выполнения программы.

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

Типичная ошибка программирования 3.16

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

Хороший стиль программирования 3.12

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

Программа на рис. 3.12 демонстрирует области действия глобальных переменных, автоматических локальных переменных, и локальных перемен­ных типа static.

Объявленной глобальной переменной x присвоено начальное значение 1. Эта глобальная переменная невидима в любом блоке (функции), в котором объявляется переменная с именем x. В main объявляется локальная пере­менная x, которой присваивается начальное значение 5. Переменная печа­тается, чтобы показать, что в main невидима глобальная x. Далее, в main определяется новый блок, с другой локальной переменной x, которой при­сваивается начальное значение 7. Эта переменная печатается, чтобы показать, чтобы показать, что она делает невидимой x внешнего блока main. Пере­менная x со значением 7 автоматически разрушается при выходе из блока, после чего печатается локальная переменная x внешнего блока функции main, чтобы показать, что она теперь не скрыта. Программа определяет три функции — каждая из них не требует аргументов и ничего не возвращает. Функция а определяет автоматическую переменную x и присваивает ей на-

Функции

203

чальное значение 25. При вызове а переменная печатается, получает прира­щение и печатается снова перед выходом из функции. Автоматическая пере­менная x создается заново и ей присваивается начальное значение 25 при каждом вызове этой функции. Функция b объявляет переменную x как static и присваивает ей начальное значение 50. Локальные переменные, объявлен­ные как static, сохраняют свои значения, даже когда они находятся за пре­делами области действия. При вызове b переменная x печатается, получает приращение и печатается снова перед выходом из функции. При следующем вызове этой функции локальная переменная x типа static будет содержать значение 51. Функция с не объявляет никаких переменных. Поэтому, когда она ссылается на переменную x, то использует глобальную переменную x. При вызове с глобальная переменная x печатается, умножается на 10 и пе­чатается снова перед выходом из функции. При следующем вызове этой функ­ции глобальная переменная x будет содержать это модифицированное зна­чение 10. Окончательно, программа снова печатает локальную переменную x в main, чтобы показать, что ни одна из функций не вызывает изменения значения x, так как все функции ссылаются на переменные в другой области действия.

// Пример областей действия #include <iostream.h>

void а(void); void b(void); void с(void);

int x = 1;

main ( ) {

int x = 5;

// прототип функции

// прототип функции

// прототип функции

// глобальная переменная

// локальная переменная main

cout « "локальная x во внешней области действия main = "

« x « endl;

( // начало новой области действия

int x = V;

cout «"локальная x во внутренней области действия main = "

« x « endl; } // конец новой области действия

cout « "локальная x во внешней области действия main = " « x « endl;

a() b() c() a() b()

c()

// а имеет автоматическую локальную переменную x

// b имеет статическую локальную переменную x

// с использует глобальную переменную x

// а заново дает начальное значение x

//статическая локальная x сохраняет предыдущее

// значение

//глобальная x также сохраняет свое значение

cout « "локальная x в main return 0;

" « x « endl;

Рис. 3.12. Пример областей действия (часть 1 из 2)