Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Классы хранения и видимость переменныхСодержание книги
Поиск на нашем сайте
Общие положения
Для каждого идентификатора существует как минимум два атрибута: тип и класс хранения. Тип определяет размер памяти, выделяемой компилятором для объекта и способ интерпретации выделенной памяти (например, как адрес памяти для указателей или массив однотипных элементов). Класс хранения определяет место, где объект располагается (внутренние регистры процессора, сегмент данных, сегмент стека), и одновременно время жизни объекта (например, все время выполнения программы или только время выполнения конкретной части кода программы). Класс хранения либо задается явно, либо компилятор «сам» определяет это по местоположению описания в тексте программы. Время жизни и класс хранения тесно связаны друг с другом. С точки зрения времени жизни различают три типа объектов: статические, локальные, динамические. Тесно связанным с понятием «класс хранения» является и понятие видимости, или области определения идентификатора. Область определения - это та часть программы, в пределах которой идентификатор может использоваться для доступа. Есть несколько типов области определения: в пределах блока (локальная видимость); в пределах функции; в пределах файла текста программы.
7.2. Область определения и видимость идентификатора.
Внешние переменные
Текст программы на С++ может быть размещен целиком в одном текстовом файле, в котором будут помещены функция main() и все другие функции, если они есть. Однако это не всегда удобно (а иногда и просто невозможно). В таком случае текст программы размещается в нескольких текстовых файлах, каждый из которых содержит целиком одну или несколько функций. Для объединения в одну программу эти текстовые файлы компилируются совместно. Информация (имя текстового файла, директорий) обо всех объединяемых в одну программу файлах, может быть помещена в так называемый файл проекта. Компилятор порождает для каждого исходного текстового файла отдельный объектный файл. Затем эти файлы объединяются компоновщиком в загрузочный модуль (.EXE-файл). Объектный файл - это неготовый к исполнению программный код. Образно говоря, объектный файл - это отдельный модуль дорогого музыкального центра, состоящего из отдельных блоков: усилителя, радиоприемника, магнитофона, проигрывателя. Для того, чтобы «заиграла» музыка, необходимо эти блоки соединить проводами друг с другом. Чтобы не ошибиться, разъемы на разных сторонах проводов часто делают неодинаковыми. Разъемы в объектных файлах порождает компилятор. Один вид разъемов соответствует известному в языке ассемблера понятию PUBLIC, другой - понятию EXTERN. Процесс объединения блоков с помощью проводов похож на работу компоновщика. В роли разъемов, объединяемых в объектных файлах проводами, выступают так называемые внешние ссылки. Это либо имена функций, либо переменные. Встретив разъем EXTERN, компоновщик ищет подходящий ему разъем PUBLIC сначала в данном объектном файле, затем в других объектных файлах из числа компилируемых совместно. Потом он просматривает библиотеки. Если подходящий разъем не найден, компоновка завершается с сообщением об ошибке типа «Неразрешенная внешняя ссылка» или «неизвестное имя...» (Unresolved external …). Если разъем EXTERN соответствует имени библиотечной функции, то она помещается в загрузочный модуль. Другими словами, разъем EXTERN - это указание компоновщику искать соответствующий ему по имени разъем типа PUBLIC. Область определения идентификатора нужна компилятору для того, чтобы сгенерировать корректный машинный код. Если идентификатор описан внутри блока {}, он имеет локальную область определения, ограниченную размерами блока. Отсюда следует, что все переменные, описанные внутри функции, в том числе и формальные параметры, имеют локальную область определения. Для локальных переменных компилятор не создает никаких разъемов – ни PUBLIC, ни EXTERN. Если идентификатор описан вне каких-либо блоков, он является глобальным и имеет область определения, начинающуюся с точки описания и продолжающуюся до конца файла. Для всех глобальных переменных компилятор создает разъем PUBLIC. Глобальный идентификатор будет видимым из всех функций ниже точки описания переменной. Чтобы идентификатор стал видимым в функциях выше точки описания переменной или в функциях, определения которых расположены в других файлах, используется объявление с атрибутом EXTERN. Обратите внимание на то, что воздействие на видимость объекта не связано с резервированием памяти компилятором. Поэтому, например, строка программы extern int var1; является не описанием переменной, а объявлением ее как внешней ссылки. Обрабатывая такое предложение, компилятор создает разъем EXTERN для переменной var1. Отсюда вытекают два очевидных следствия: при объявлении переменной как EXTERN просто невозможно выполнить ее инициализацию. Например, выражение extern int var1 = 20; является ошибкой; для того чтобы какой-либо объект данных, в том числе и объявленный как EXTERN, был видим из всех функций файла, необходимо поместить описание или объявление объекта в самом начале файла, перед первой функцией. Сначала компоновщик просматривает глобальные переменные текущего файла (т.е. все разъемы PUBLIC в том файле, в котором встретилось объявление EXTERN). Если не найден подходящий глобальный идентификатор в текущем файле, компоновщик просматривает все идентификаторы, помеченные как PUBLIC, в других объектных файлах, образующих один проект. Если и там не будет найден соответствующий идентификатор, поиск продолжается в библиотеках. Внешние переменные – один из способов «передачи» функциям аргументов и «возврата» из функций необходимых значений. Просто взаимодействующие функции используют общие области памяти. Имена функций в языке С++ – это всегда глобальные имена, видимые по умолчанию из всех файлов одного проекта. Однако прототип функции действует только в пределах одного файла. Из-за этого, в частности, приходится помещать во все совместно компилируемые файлы директивы препроцессора, связанные с подключением.h-файлов, содержащих прототипы библиотечных функций. Приведем пример программы, текст которой размещен в двух файлах (для связи функций программы используется внешняя переменная i): // Prim7_1.cpp #include <stdio.h> extern int i; void main(void) { void next(void); /* прототип */ int i = 3; i++; printf("В main i = %d\n", i); next(); } void next(void) { void other(void); /* прототип */ i++; printf("B next i = %d\n", i); other(); }
// Prim7_2.cpp #include <stdio.h> extern int i; void other(void) { i++; printf("B other i = %d\n", i); } В результате выполнения программы получены следующие результаты: B main i = 4 B next i = 5 B other i = 6
|
||
|
Последнее изменение этой страницы: 2017-02-05; просмотров: 357; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.217.128 (0.008 с.) |