Главная Случайная страница


Полезное:

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


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Определение и описание переменных





В зависимости от способа определения переменной и его места размещения в программе явно, либо по умолчанию всегда определяются следующие её свойства:

· тип переменной;

· класс памяти (задаёт размещение переменной);

· продолжительность существования переменной;

· сфера действия имени переменной;

· видимость переменной;

· тип компоновки.

О типах и их свойствах, задаваемых при определении переменных, уже говорилось ранее. В общем виде определение переменных имеет следующий формат:

[s] [m] тип имя1 [иниц.1], имя2 [иниц.2], …;

где s - спецификатор класса памяти (auto, static, extern, register); m – модификатор const или volatile; тип – один из типов данных (основной или определенный программистом); имя – идентификатор; иниц. – необязательный инициализатор, определяющий начальное значение соответствующего объекта. В квадратных скобках указаны параметры, которые можно опустить при определении, задав тем самым их значения по умолчанию.

Синтаксис инициализатора (иниц.) переменной:

= инициализирующее выражение

либо

(инициализирующее выражение)

Пример:

const double pi = 3.1415; /*Определяется и инициализируется именованная статическая константа pi */

extern const double pi; // Описание константы pi

Наиболее часто в качестве инициализирующего выражения используется константа. Вторая «скобочная» форма инициализации разрешена только внутри функции, т.е. для локальных объектов. Инициализация в отличии от присваивания выполняется только один раз во время определения объекта.

Модификаторы:

volatile (переменный) – ключевое слово (модификатор), которое сообщает, что значение переменной может быть изменено во время выполнения программы. Модификатор volatile практически никогда не употребляется в тексте программ, так как по умолчанию все переменные являются volatile.

const (постоянный) – ключевое слово (модификатор), которое сообщает, что значение переменной не может быть изменено во время выполнения программы. Модификатор const позволяет переопределить заданный по умолчанию при определении переменных модификатор volatile. Используется для создания именованных констант, например: const double PI = 3.14159; //определяется именованная константа PI.

Классы памяти:

auto – автоматически выделяемая, локальная память. Спецификатор auto может быть задан только при определении объектов блока, например, в теле функции. Этим объектам память выделяется при входе в блок и освобождается при выходе из него. Вне блока объекта класса auto не существует. Необходимость явно использовать спецификатор класса памяти auto в тексте программы практически всегда отсутствует, так как все переменные, определенные внутри блока по умолчанию, являются локальными, т.е. по умолчанию имеют спецификатор auto;

register – автоматически выделяемая, по возможности регистровая память. Спецификатор register аналогичен auto, но для размещения значений объектов используются регистры, а не участки основной памяти. Такая возможность имеется не всегда, и в случае отсутствия регистровой памяти (если регистры заняты другими данными) объект класса register компилятор обрабатывает как объект auto. Спецификатор register также практически не используется в тексте программ, так как компилятор очень часто сам оптимизирует код или по скорости выполнения, или по его размеру, тем самым самостоятельно решая какие переменные сделать register, а какие нет.

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

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

Переменные со статической продолжительностью существования существуют с момента запуска программы и до момента окончания её работы. Фактически, память под такие переменные отводится в сегменте данных программы, т.е. в исполняемом файле программы (*.exe) есть соответствующее типу переменной количество байт, в которых хранится значение статической переменной.


По определению статическими переменными являются переменные, определенные вне любого блока ({}), либо переменные, определенные в блоке со спецификатором static. Переменная, определенная вне любого блока ({}), называется также глобальной и по умолчанию имеет класс памяти extern. Сфера действия имени глобальной переменной, другими словами, фрагмент программы, где можно с помощью имени обратится к переменной, у глобальной переменной совпадает с областью существования, т.е. является вся программа.

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

По определению любая переменная, определенная внутри блока ({}) без спецификатора static, является локальной автоматической, а со спецификатором static – локальной статической. Область существования локальной автоматической переменной ограничена, начиная с места определения её в программе и заканчивая концом блока, в котором эта локальная переменная определена, а областью существования локальной статической переменной является вся программа. Сфера действия имени у локальной статической и автоматической переменных совпадает. Она начинается с места их определения в программе и заканчивается концом блока, в котором эти локальные переменные определены. Помимо этого, формальные параметры в определении функции также являются локальными автоматическими переменными, область существования которых ограничена телом функции. Формальные параметры в описании функции – это тоже локальные автоматические переменные, область существования которых ограничена строкой программы, содержащей описание этой функции. Пример:

//Программа 3.1

#include "stdafx.h"

#include <iostream> //1

int pr = 7; /*2. Определение глобальной статической переменной pr. Область существования этой переменной pr  вся программа. */

int sum(int pa, int pr); /*3. Описание функции sum(), в которой два формальных параметра: pa и pr. Область существования pa и pr  только эта строка программы. */

void main(){ //4.

int pr = 8; /*5. Определение локальной переменной pr. Область существования pr c момента определения до конца тела функции main(), т.е. с 5 по 13 строки программы. */

std::cout<<"\n 1. sum(pr, 3) = "<<sum(pr, 3); /*6. Вызов функции sum()*/

{ //7. Начало нового блока

int pr = 9; /*8. Определение локальной переменной pr. Область существования pr c момента определения до конца блока, т.е. с 8 по 11 строки программы. */


std::cout<<"\n 2. sum(pr, 3) = "<<sum(pr, 3); /*9. Вызов функции sum()*/

std::cout<<"\n 3. sum(::pr, 3) = "<<sum(::pr, 3); /*10. Вызов функции sum()*/

} //11. Конец блока

std::cout<<"\n 4. sum(::pr, 3) = "<<sum(::pr, 3);/*12. Вызов функции sum()*/

getchar();

} //13. Конец тела функции main()

int sum(int z, int pr){ /*14. Определены две локальные переменные z и pr. Область существования – тело функции sum(), т.е. 14 – 18 строки программы. */

static int count = 0; /*15. Определение локальной статической переменной count. Область существования  вся программа. */

count ++; //16.

return z+pr; //17.

}

В этой программе в строках 1, 2, 4, 7, 13 определены переменные pr. Все эти переменные абсолютно разные, они хранят свои значения в разных фрагментах памяти, область существования у них тоже разная, единственное, что их объединяет - это имя.

Когда определено несколько переменных с одним именем и области их существования частично или полностью совпадают, например, как в случае с переменной pr, то для того чтобы определить, к какой конкретно переменной происходит обращение, необходимо учитывать видимость этой переменной в программе. Поясним на примере переменной pr понятие видимости переменной в каждой точке программы (рис. 3.1)

Рис. 3.1. Видимость объектов, связанных с одним идентификатором (именем) в однофайловой программе

 

На рис. 3.1 прямоугольниками показаны области существования переменных pr. Стрелками обозначено, к какой конкретно переменной происходит обращение при использовании имени pr в программе. Таким образом, определение локальной переменной с таким же именем, как и у глобальной, делает невидимой глобальную переменную, но к ней можно получить доступ, если применить операцию указания области видимости (::), что и продемонстрировано в 10 и 12 строках. Интересен тот факт, что доступ к локальной переменной pr, определенной в 5 строке из строк с 7 по 11, невозможен никаким способом. Отметим также, что глобальные переменные видны во всей программе и поэтому их можно использовать в теле функций, передавая через них данные.

Переменная count – это статическая переменная, поэтому область её существования - вся программа, но так как она локальная, то сфера действия имени этой переменной заключена в пределах, начиная с её определения и до конца тела функции sum(), т.е. строки с 15 по 18. К этой переменной нельзя обратиться за пределами указанного диапазона.

Особенность использования локальных статических переменных заключена в том, что они не уничтожаются при выходе из функции, как локальные автоматические. Это значит, что в них функции могут хранить какие-то данные в промежутках между своими вызовами. Строка 15 фактически ни разу не выполняется в программе при вызове функции sum(), т.е. во время выполнения в строке 15 не создаётся и не инициализируется нулевым значением новая переменная. Она уже была создана и инициализирована нулевым значением на этапе компиляции. Поэтому при вызове функции sum() значение count не обнуляется в строке 15; в строке 16 оно увеличивается на единицу и хранится до следующего вызова sum(). Таким образом, с помощью локальной статической переменой count подсчитывается количество вызовов функции sum().


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

Если программа состоит более чем из одного файла (модуля), то глобальная переменная, определенная в одном файле, может быть доступна в другом файле программы, а может быть и нет. Доступность глобальной переменной определяется типом компоновки. Внешний тип компоновки означает, что одна и та же глобальная переменная может быть видна в нескольких файлах программы; внутренний тип компоновки означает, что глобальная переменная видна только в том файле, в котором она определена. Пример:







Date: 2015-05-22; view: 1011; Нарушение авторских прав



mydocx.ru - 2015-2024 year. (0.009 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию