Область видимости переменных

Последнее обновление: 08.01.2023

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

Переменные бывают глобальными и локальными или автоматическими.

Локальные автоматические переменные

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

#include <stdio.h>

void printn()
{
	int n = 63;
	printf("n=%d \n", n);
}

int main(void)
{
	int a = 2;
	printn();				// n=63
	//n++;		так сделать нельзя, так как n определена в функции printn
	printf("a=%d \n", a);	// a=2
	return 0;
}

Здесь в функции printn определена автоматическая переменная n. В функции main определена автоматическая переменная a. При вне своих функций переменные недоступны. Например, мы не можем использовать переменную n в функции main, так как ее область видимости ограничена функцией printn.

То же самое касается переменных, которые определены во вложенных блоках кода, например, условных конструкциях if..else, switch..case, циклах for,while, do..while. Например:

void printn()
{
	{
		int n = 20;		// локальная переменная
		printf("%d \n", n);
	}
	printf("%d \n", n);	// Ошибка - здесь переменная n не видна
}

Здесь переменная n по прежнему является локальной и автоматической. Но она определена не просто в функции, а в блоке кода внутри функции. И вне этого блока кода даже внутри функции ее нельзя использовать, потому что после завершения блока кода она удаляется.

Глобальные переменные

Глобальные переменные определены в файле программы вне любой из функций и могут использоваться любой функцией из этого файла.

#include <stdio.h>

int n = 5;

void printn()
{
	n++;
	printf("n=%d \n", n);
}

int main(void)
{
	printn();			// n=6
	n++;
	printf("n=%d \n", n);	// n=7
	
	return 0;
}

Здесь переменная n является глобальной и доступна из любой функции. При этом любая функция может изменить ее значение.

Сокрытие переменных

Автоматические переменные, определенные внутри блока кода, могут скрывать внешние переменные с тем же именем:

#include <stdio.h>

int n = 5;

int main(void)
{
	int n = 10;
	printf("n=%d \n", n);		// n=10
	{
		int n = 20;
		printf("n=%d \n", n);	// n=20
	}
	return 0;
}

Здесь определено три переменных с именем n. Автоматическая переменная n, определенная на уровне функции main (int n = 10;) скрывает глобальную переменную n. А переменная n, определенная на уровне блока, скрывает переменную, определенную на уровне функции main.

Статические переменные

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

Например, пусть у нас будет функция со стандартной автоматической переменной:

#include <stdio.h>

void display()
{
	int i = 0;
	i++;
	printf("i=%d \n", i);
}

int main(void)
{
	display();
	display();
	display();
	return 0;
}

Функция display вызывается три раза, и при каждом вызове программа повторно будет выделять память для переменной i, которая определена в функции. А после завершения работы display, память для переменной i будет освобождаться. Соответственно ее значение при каждом вызове будет неизменно:

i=1
i=1
i=1

Теперь сделаем переменную i статической:

#include <stdio.h>

void display()
{
	static int i = 0;
	i++;
	printf("i=%d \n", i);
}

int main(void)
{
	display();
	display();
	display();
	return 0;
}

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

i=1
i=2
i=3

Регистровые переменные

Регистровые переменные фактически являются также автоматическими переменные, но при их определении используется ключевое слово register. Это слово сообщает компилятору, что данная переменная будет интенсивно использоваться в приложении, поэтому ее желательно поместить в регистр процессора, что увеличит быстродействие.

Ключевое слово register применяется к переменным:

register int x = 8;

И к параметрам функции:

void display(register int a)
{
	printf("a=%d \n", a);
}

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

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850