Область видимости (действия) и время жизни переменных 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Область видимости (действия) и время жизни переменных



Объекты, объявленные вне процедур, называются внешними, объекты, объявленные внутри процедур и блоков, - внутренними.

Областью видимости ( scope ) объекта является та часть программы, в пределах которой использование его имени является корректным.

Область видимости имени (определения или описания) внутреннего объекта – это процедура или блок, в которой(ом) находится это определение или описание.

Области видимости внешнего объекта в языках C и Basic несколько отличаются. В языке C она распространяется от места его определения до конца файла. Напомним, что в этом языке допустимо определение внешнего объекта между определениями функций. В языке Basic эта область охватывает весь модуль (файл).

Если одно и то же имя объявлено на разных уровнях структуры, то это объявление разных объектов и всегда превалирует более "внутреннее" объявление имени, если мы находимся в его области видимости.

Пример. Приводится на языке C, поскольку он имеет больше уровней структуры. Стрелками с номером показаны области видимости соответствующего объекта по имени a.

#define SIZE 100

float a[SIZE]; _______ /* 1-й объект */

.............. |

| ß 1

void main(void){ |

int a,b; _____| /* 2-й объект */

........ | ß 2

{ double a,c; __| /* 3-й объект */

........... | ß 3

} _|_

........ | ß 2

} /* End main */ ___|


int func1(...){ _______

int k,l; |

........ | ß 1

{ char a,e; _____| /* 4-й объект */

......... | ß 4

} __|___

........ | ß 1

} /* End func1 */ |

|

int func2(...){ |

.......... | ß 1

} /* End func2 */ ______|

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

Пример.

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

Второй объект с именем a глобален для блока, содержащего определение третьего объекта с именем a, но локален в функции main.

Третий объект с именем a локален в блоке.

В языке C файл может содержать одни объявления, которые затем могут быть включены в нужные места программы с помощью директивы препроцессора #include.

Рекомендация. Если в программе используются сложные структуры, то их тип разумно описать с помощью инструкции typedef и объединить в один. h файл.

Кроме области видимости объекты программы обладают временем жизни ( lifetime ). Время жизни – это период времени, в течение которого объекту выделяется память. Для внешних объектов память резервируется на все время выполнения приложения. Внутренние объекты в большинстве случаев существуют (имеют выделенную память) только при выполнении процедуры или блока, в которой(ом) они определены. Обычно после завершения работы процедуры или блока отведенная им память освобождается.

И в языке C, и в языке Basic есть средства, которые управляют областью видимости и временем жизни объектов программы. Механизм управления в них, однако, различен, поэтому рассмотрим эти средства по отдельности.

Язык C

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

<объявление>:= [<атрибут класса памяти>] <тип> <список объектов>;

<атрибут класса памяти>:= auto | static | extern | register

Объекты класса памяти auto – это внутренние объекты, память под которые выделяется при входе в функцию или блок и освобождается при выходе. Такой тип памяти называют стек.

Объекты класса памяти static – это также внутренние объекты, но память под них выделяется только один раз и они существуют в течение работы всей программы, причем доступны они только в своей области видимости и при повторном входе в нее сохраняют предыдущие значения. Объекты static имеют одинаковую с объектами auto область видимости, но разное время жизни.


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

void function(...){

static int kol=0;

.................

kol++;

.................

}

Объекты класса памяти extern – это внешние объекты и поэтому потенциально доступны для многих функций. Сами функции всегда внешние, т.к. синтаксис языка C не определяет внутренних функций.

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

Каковы же возможные причины применения этого механизма?

1. Связь между функциями с большим числом объектов обмена.

2. Инициализация объектов (позже).

3. Две или более функций имеют общие данные, но непосредственно не обращаются друг к другу.

Пример.

1. Функция: добавить элемент в таблицу.

2. Функция: найти элемент в таблице.

Общие данные – таблица (или список).

Если класс памяти объекта не указан явно, то он задается по умолчанию положением его определения в тексте. Если определение находится внутри функции или блока, то класс памяти объекта – auto, если вне, то – extern. Время жизни объекта класса памяти extern равно времени выполнения приложения, т.е. оно совпадает с временем жизни объекта класса памяти static. Если внешний объект объявлен с ключевым словом static, то он локализован в файле, т.е. его имя не может быть объявлено в другом файле с ключевым словом extern.

Пример.

/* file1.c */

int i; /* класс extern */

..........

void f1(...){

int i; /* класс auto */

..........

}

Если программа состоит из нескольких файлов, то внешние объекты могут использованы в других файлах. Для этого их необходимо описать в нужных местах с атрибутом класса памяти extern. Ключевое слово extern в данном случае означает описание и говорит о том, что определение такого объекта находится где-то в другом файле.

Пример.

/* file1.c */ /* file2.c */

void f1(...){ int i;

extern int i;...........

............. один и тот же объект

}

void f2(...){

int i; другой объект

.............

}

Замечание. В определениях функций ключевое слово extern записывать не надо, поскольку они по умолчанию внешние, т.е. могут быть вызваны из любого файла. Однако в случае необходимости функцию можно локализовать в файле. Для этого ее определение надо начать с ключевого слова static.

Пример.

static int a(...){ К функции a можно обратиться только из функции b.

.........

}

int b(...){

.........

n=a(...);

.........

}

Выводы.

1. В программе, состоящей из нескольких файлов, может быть только одно определение внешнего объекта (без ключевого слова extern). Объявление имени с атрибутом класса памяти extern означает описание, а не определение.

2. Область видимости внешнего имени – это текст от его определения до конца файла плюс блоки или функции в других файлах, где имеет место описание этого имени с атрибутом класса памяти extern.

3. Внешний объект с атрибутом класса памяти static локализован в файле.

4. Функции могут вызываться до их определения, если их прототипы указаны до места вызова.

5. Статические объекты при выделении памяти всегда инициализируются нулевыми(для строк – "пустыми") значениями, если не указана явная инициализация какими-либо другими значениями. Автоматические объекты при размещении не получают никакого определенного значения. Принято говорить, что после определения они содержат "мусор", если не было их явной инициализации.

Замечание. Правила явной инициализации объектов излагаются ниже.

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

Объекты класса памяти register – это объекты, аналогичные объектам класса памяти auto, которые транслятор стремится разместить в регистрах процессора для обеспечения быстрого доступа. Такое размещение выполняется только при наличии свободных регистров. Атрибут применим также для параметров функции.

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

Язык Basic

Здесь так же, как и в языке C, допустимо объявление внешних объектов, которые сохраняют свои значения в течение всего времени выполнения приложения. Для того, чтобы такое время жизни могли иметь внутренние объекты, также используется ключевое слово static. Однако в отличие от языка C в языке Basic оно определяет самостоятельную инструкцию объявления объектов, используемую вместо инструкции dim.

Пример.

static number as integer, point(1 to 2) as single

Замечание. В отличие от языка C все объекты при их определении инициализируются (не содержат "мусор") следующим образом. Данные числовых типов получают значение "0", строки фиксированной длины заполняются нулями, строки переменной длины получают значение "" (пустая строка). Каждый элемент данных типа, определенного пользователем, инициализируется как отдельная переменная указанного типа.

Ключевое слово static также может быть использовано при определении процедур, однако смысл его употребления в данном случае другой. Инструкция sub или function с ключевым словом static объявляет все свои внутренние объекты как статические, т.е. сохраняющие свои значения в течение всего времени работы приложения.

Пример.

static sub proc(...)

Область видимости объекта определяется ключевыми словами private и public. При объявлении объектов программы они определяют самостоятельные инструкции аналогично инструкции static. Эти инструкции используются при определении внешних объектов. Инструкция private локализует такие данные в файле, инструкция public делает объект доступным во всех файлах приложения.

Замечание. Отметим отличие инструкции public от атрибута класса памяти extern языка C. Атрибут extern делает внешний объект доступным только в тех блоках или функциях других файлов, где имеет место его объявление. Инструкция public не требует никакого дополнительного объявления в других файлах для возможности обращения к такому объекту, но делает его доступным по всей программе, что не всегда требуется. Механизм использования extern является более гибким и предпочтительным с точки зрения надежности программы.

Использование инструкции private внутри процедуры равносильно применению инструкции dim и поэтому не имеет смысла. Использование инструкции public внутри процедуры вызовет ошибку трансляции.

Пример.

private number as integer

public point(1 to 2) as single

Действие этих ключевых слов в инструкциях sub и function аналогично изложенному выше, т.е. ключевое слово private делает процедуру доступной только для процедур данного файла, а слово public – для процедур всех файлов приложения. По умолчанию, т.е. при отсутствии в инструкции sub или function этих слов, процедура рассматривается как public.

Пример.

public sub Matrix(p(9,9) as double, q(9) as double, s(9) as double, l as integer, _

k as integer)

private function Max(ByVal a as double, ByVal b as double) as double

Проект программы

В современных средах разработки программ существуют специальные средства, позволяющие управлять процессом трансляции отдельных модулей, собирать (компоновать) полученные после трансляции объектные файлы (расширение .obj) в единый загрузочный модуль (расширение .exe). Загрузочный модуль затем размещается в память компьютера (загружается) и выполняется. Эти средства создают и корректируют файл описания проекта программы. Проект – это набор файлов, используемых при построении приложения. Средства работы с проектами выполняют также и некоторые дополнительные функции, облегчающие разработку.



Поделиться:


Последнее изменение этой страницы: 2017-02-08; просмотров: 398; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.131.13.194 (0.043 с.)