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)
- 116 Глава 2
- 2.13. Основы повторения, управляемого счетчиком
- 2.14. Структура повторения for (цикл)
- 120 Глава 2
- 122 Глава 2
- 2.15. Пример использования структуры for
- 124 Глава 2
- 126 Глава 2
- 2.16. Структура множественного выбора switch
- Глава 2
- 130 Глава 2
- 132 Глава 2
- 2.17. Структура повторения do/while
- 134 Глава 2
- 2.18. Операторы break и continue
- Глава 2
- 2.19. Логические операции
- 138 Глава 2
- Глава 2
- 2.21. Заключение по структурному программированию
- IfcrpyKTypa (единственный выбор)
- Глава 2
- Глава 2
- 148 Глава 2
- Глава 2
- Глава 2
- Глава 2
- 156 Глава 2
- 158 Глава 2
- 160 Глава 2
- 2.1. А) следование, выбор и повторение, b) if/else. С) управляемым счет чиком или определенным заранее, d) Метку, сигнал, флаг или лож ный сигнал.
- 162 Глава 2
- 164 Глава 2
- 166 Глава 2
- 168 Глава 2
- 170 Глава 2
- 172 Глава 2
- 174 Глава 2
- 176 Глава 2
- 178 Глава 3
- Глава 3
- 3.3. Математические библиотечные функции
- 3.4. Функции
- Глава 3
- 3.5 Определения функций
- 184 Глава 3
- 186 ГлаваЗ
- 3.6. Прототипы функций
- 188 Глава 3
- 3.7. Заголовочные файлы
- 3.8. Генерация случайных чисел
- Глава 3
- 192 Глава 3
- 194 Глава 3
- 3.9. Пример: азартная игра
- Глава 3
- 198 Глава 3
- 3.10. Классы памяти
- 200 Глава 3
- 3.11. Правила, определяющие область действия
- 202 Глава 3
- 204 Глава 3
- 3.12 Рекурсия
- Глава 3
- 6) Значения, возвращаемые после каждого рекурсивного вызова
- 3.13. Пример использования рекурсии: последовательность чисел Фибоначчи
- Глава 3
- 3.14. Рекурсии или итерации
- 212 Глава 3
- Глава 3
- Глава 4
- Глава 5
- Глава 6
- 3.15. Функции с пустыми списками параметров
- 214 Глава 3
- 3.16. Встраиваемые функции