Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
пиппец 2.doc
Скачиваний:
107
Добавлен:
07.06.2015
Размер:
3.16 Mб
Скачать

57. Переменные величины в яп, их атрибуты, время жизни, область видимости

Переменная величина – именованная область памяти. Величины бывают постоянные – не меняются в процессе работы программы, переменные – могут изменяться. Величина имеет три хар-ки: имя, зн-е, тип.

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

Тип данных определяется 1) мн-во зн-ий, кот могут принимать объекты данного типа 2) мн-во опер-й, допуст над этими объектами. Типы делятся на простые и структурные. Простые делятся на стандартные (целый, вещественный) и пользовательские (массивы, записи - record: <имя типа>=Record, enum <имя типа> {переменные}). Каждый из этих типов характеризуется диапазоном представления чисел и размером выделяемой для них памяти. (int – 2байта, float- 4 байта, double – 8байт, char – 1 байт)

Время жизни объектов программы.

Время жизни объекта – это период его существования, т.е. то время работы программы, когда с ним ассоциирована ячейка памяти и значение.

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

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

В языке Си время жизни объекта определяется двумя факторами: местом объявления в программе и классом памяти (auto или static).

Спецификация класса памяти может быть указана при объявлении объекта перед обозначением его типа. Например, переменная, имеющая класс памяти static, может быть объявлена следующим образом: static int k;

В соответствии со своим классом памяти (auto или static) объекты называют автоматическими либо статическими.

Объекты, определенные на внешнем уровне, всегда имеют глобальное время жизни. (Поэтому все функции в Си имеют глобальное время жизни.)

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

Спецификация класса памяти auto объявляет переменную с локальным временем жизни. Если при объявлении переменной на внутреннем уровне спецификация класса памяти опущена, то по умолчанию она подразумевается как auto. Отметим, что спецификация класса памяти auto может использоваться только на внутреннем уровне. Переменные класса памяти auto автоматически не инициализируются, поэтому в случае отсутствия инициализации в объявлении значение переменной класса памяти auto считается неопределенным. Память под переменную класса памяти auto выделяется в стеке.

Объекты с локальным временем жизни – это, в сущности, и есть автоматические объекты, - существуют только внутри блока, в котором они определены. (Напомним, что блок - это не только тело функции, но и любая последовательность объявлений и операторов, заключенная в фигурные скобки.) При выходе из блока память, выделенная объектам типа auto, освобождается, т.е. объекты исчезают. При повторном входе в блок для тех же объектов выделяются новые участки памяти, содержимое которых ни как не зависит от «предыстории».

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

Пример:

//Переменная k имеет локальное время жизни:

//Переменная k имеет глобальное время жизни:

include <stdio.h>

void f1 ()

{

int k = 1;

printf (“k = %3d”, k);

k++;

}

void main ()

{

int i;

for (i = 0; i < 5; i++)

f1() //Вызов функции f1()

}

Результат: k = 1 k = 1 k = 1 k = 1 k = 1

include <stdio.h>

void f2 ()

{

static int k = 1;

printf (“k = %3d”, k);

k++;

}

void main ()

{

int i;

for (i = 0; i < 5; i++)

f2() //Вызов функции f2()

}

Результат: k = 1 k = 2 k = 3 k = 4 k = 5

Область действия объектов программы.

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

Область действия зависит от 2 факторов: 1)от места объявления переменной, 2) по наличию или отсутствию спецификатора extern.

Так, объект с глобальным временем жизни существует («живет») в течение всего времени выполнения программы, однако он доступен только в тех частях программы, на которое распространяется его область действия.

Объект может иметь: глобальную область действия, область действия «файл», локальную область действия.

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

Область действия «файл» означает, что объект доступен только в том файле, в котором он объявлен.

Локальная область действия означает, что объект доступен только в том блоке, в котором он объявлен.

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

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

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

Переменная, объявленная на внутреннем уровне со спецификацией класса памяти extern, является ссылкой на переменную, определенную на внешнем уровне в любом исходном файле программы. Цель внутреннего объявления extern – сделать определение переменной внешнего уровня (как правило, данное в другом файле) доступным именно внутри данного блока.

Механизм локального переобъявления переменной.

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

Пример:

int i = 1; // i определяется на внешнем уровне

void main ()

{ printf (“%d\n”, i); // Увидим: 1

{ int i = 2, j = 3; // i переопределяется

printf (“%3d%3d \n”, i, j); // Увидим: 2 3

{ int i = 0; // i переопределяется

printf (“%3d%3d \n”, i, j); // Увидим: 0 3

}

printf (“%d\n”, i); /* Восстановлено i в охватывающем блоке. Увидим: 2*/

}

}