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

13.3.3. Статические локальные объекты

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

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

#include <iostream> int traceGcd( int vl, int v2 ) { static int depth = 1; cout << "глубина #" << depth++ << endl; if ( v2 == 0 ) { depth = 1; return vl; } return traceGcd( v2, vl%v2 ); }

Значение, ассоциированное со статическим локальным объектом depth, сохраняется между вызовами traceGcd(). Его инициализация выполняется только один раз – когда к этой функции обращаются впервые. В следующей программе используется traceGcd():

#include <iostream>

extern int traceGcd(int, int);

int main() { int rslt = traceCcd( 15, 123 ); cout << "НОД (15,123): " << rslt << endl; return 0; }

Результат работы программы:

глубина #1

глубина #2

глубина #3

глубина #4

НОД (15,123): 3

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

#include <iostream> const int iterations = 2; void func() { int value1, value2; // не инициализированы static int depth; // неявно инициализирован нулем if ( depth < iterations ) { ++depth; func(); } else depth = 0; cout << "\nvaluel:\t" << value1; cout << "\tvalue2:\t" << value2; cout << "\tsum:\t" << value1 + value2; } int main() { for ( int ix = 0; ix < iterations; ++ix ) func(); return 0; }

Вот результат работы программы:

valuel: 0 value2: 74924 sum: 74924 valuel: 0 value2: 68748 sum: 68748 valuel: 0 value2: 68756 sum: 68756 valuel: 148620 value2: 2350 sum: 150970 valuel: 2147479844 value2: 671088640 sum: -1476398812 valuel: 0 value2: 68756 sum: 68756

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]