Область действия и область видимости

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

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

Пример

#include <stdio.h>

Void f(void);

Void main(void)

{

Int i;

i=1;

F();

printf(“В функции main значение i равно %d\n”,i);

}

Void f(void)

{

Int i;

i=10;

printf(“В функции f() значение i равно %d\n”,i);

}

Пример показывает, что при вызове функции значение переменной i, объявленной в main() не изменилось.

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

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

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

В языке С есть инструмент, позволяющий управлять ключевыми механизмами использования памяти и создавать гибкие и мощные программы. Этот инструмент – классы памяти. Каждая переменная принадлежит к одному из классов памяти. Эти классы описываются следующими ключевыми словами:

auto – автоматическая; extern – внешняя; static– статическая; register – регистровая.

Примеры:

Static int sum;

Register int plus;

Если ключевого слова перед спецификацией типа локальной переменной при ее объявлении нет, то по умолчанию она принадлежит классу auto. Автоматические переменные имеют локальную область действия. Они известны только внутри блока, в котором они определены. Автоматическая переменная создается (т.е. ей отводится место в памяти программы) при входе в блок функции. При выходе из блока автоматическая переменная пропадает, а область памяти, в которой находилась эта переменная, считается свободной и может использоваться для других целей. Автоматические переменные хранятся в оперативной памяти ЭВМ, точнее, в стеке. Регистровые (register) переменные хранятся в регистрах процессора. Доступ к переменным, хранящимся в регистровой памяти, значительно быстрее, чем к тем, которые хранятся в оперативной памяти ЭВМ. В остальном, регистровые переменные аналогичны автоматическим переменным.

Пример:

Register int quick;

Внешняя переменная (extern) относится к глобальным переменным. Она может быть объявлена как вне, так и внутри тела функции:

Void f(void)

{

extern int j; /* объявление внешней переменной внутри функции */

}

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

int var; /* описана внешняя переменная var */

Void main(void)

{

extern int var; /* объявлена та же внешняя переменная */

}

Func1()

{

extern int var1; /* объявлена внешняя переменная var1 */

/* переменная var также внешняя, хотя она не описана в этом блоке */

}

Func2()

{ /* переменная var внешняя */

/* переменная var1 невидима для этой функции в этом блоке */

}

int var1; /* описание внешней переменной */

Fun3()

{ /* для этой функции var1 внешняя */

int var; /* переменная var описана как локальная и не связана с глобальной переменной var */

/* по умолчанию эта переменная автоматическая */

}

Func4()

{ /* здесь переменная var является внешней глобальной переменной */

auto int var1; /* переменная var1 локальная автоматическая переменная */

}

При описании статических переменных перед описанием типа ставится ключевое слово static.Область действия локальной переменной - вся программа. Место в памяти под локальные переменные выделяется в начале работы программы в разделе глобальных и статических переменных. Однако область видимости локальных статических переменных такая же, как и у автоматических. Значение статической переменной сохраняется от одного вызова функции до другого. Локальные статические переменные инициализируются нулем, если не указан другой инициализатор.

При этом описание с инициализацией static int count = 10; локальной статической переменной countвызывает однократную инициализацию переменной countпри выделении для нее памяти. При последующих вызовах функции, в которой описана эта переменная, инициализации не происходит. Это позволяет использовать такую переменную для счетчика вызова функций.

#include <stdio.h>

/* использование статической переменной */

void trystat(void); /* прототип функции */

Void main(void)

{

Int i;

for(i=1; i<=3; i++)

{

printf(“Call # %d\n”,i);

Trystat();

printf(“Call # %d\n”,i);

Trystat();

}

}

Void trystat(void)

{

int auto_l=1;

static int stat_l=1;

printf(“auto_l=%d stat_l=%d\n”,auto_l++, stat_l++);

}

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

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

Класс памяти Ключевое слово Время существования Область действия
Автоматический auto временно блок
Регистровый register временно блок
Статический локальный static постоянно блок
Статический глобальный static постоянно файл
Внешний extern постоянно программа

Наши рекомендации