Поиск по сайту:

Учебник по программированию на C для Linux. Часть 10. Области действия переменных


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

Давайте начнем с кода замены значений, который мы использовали в одном из наших предыдущих руководств:

#include <stdio.h>

void swap (int val1, int val2)
{
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\nSwapped values are: %d and %d", val1,val2);

}

int main()
{
int a=0, b=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(a,b);

return 0;
}

Здесь, в этом фрагменте кода, переменные val1 и val2 имеют локальную область видимости, что означает, что они оживают, когда вызывается функция swap, и умирают, как только вызов swap завершается. Вы просто не можете получить доступ к val1 и val2 до или после вызова функции swap. Точно так же область действия переменных a и b также локальна — локальна для функции main.

Обратите внимание, что эти локальные переменные области также известны как автоматические переменные.

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

#include <stdio.h>

int var;

void swap (int val1, int val2)
{
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\nSwapped values are: %d and %d", val1,val2);

}

int main()
{
int a=0, b=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(a,b);

return 0;
}

По умолчанию глобальным переменным присваивается значение 0. Но это не относится к локальным переменным — вам нужно присвоить им значение, когда они определены, иначе они будут содержать мусорное значение. Например, в следующей программе:

#include <stdio.h>

int var;

int main()
{
int a;

printf("Local variable 'a' currently holds: %d", a);

printf("\n Global variable var currently holds: %d", var);


return 0;
}

Есть высокие шансы, что вы получите ненулевое значение для a. var, с другой стороны, всегда будет вначале равен нулю.

Двигаясь дальше, могут ли быть глобальные и локальные переменные с одинаковыми именами? Ну, да. Хорошо, тогда что следующий фрагмент кода выдаст на выходе:

#include <stdio.h>

int var = 5;

int main()
{
int var = 10;

printf("Local variable 'a' currently holds: %d", var);

printf("\n Global variable var currently holds: %d", var);


return 0;
}

Ну, на выходе будет 10 в обоих случаях. Причина в том, что локальная переменная var переопределит глобальную var. Итак, теперь следующий логический вопрос: как в этом случае получить доступ к глобальной переменной внутри main? К сожалению, ответ НЕТ. На самом деле вам следует избегать подобных ситуаций при работе с языком C.

Далее идет концепция внешних переменных. С точки зрения непрофессионала, используя ключевое слово extern с объявлением любой переменной, вы сообщаете компилятору, что эта переменная уже объявлена/определена где-то в другом месте и просто используется здесь. Например, в следующем фрагменте кода компилятор не знает о существовании var, когда пытается скомпилировать оператор printf внутри функции main.

#include <stdio.h>

int main()
{

printf("\n Global variable var currently holds: %d", var);


return 0;
}

int var = 5;

Вот почему вы получаете ошибку, подобную следующей во время компиляции:

main.c: In function ‘main’:
main.c:14:58: error: ‘var’ undeclared (first use in this function)
printf("\n Global variable var currently holds: %d", var);
^
main.c:14:58: note: each undeclared identifier is reported only once for each function it appears in

Но если вы объявите var как extern здесь, вы увидите, что все работает нормально. Это потому, что компилятор в конечном итоге получает исходное объявление var.

#include <stdio.h>

int main()
{
extern int var;

printf("\n Global variable var currently holds: %d", var);


return 0;
}

int var = 5;

И вы получите правильный вывод:

Global variable var currently holds: 5

Так вот как работает экстерн. Внешние переменные часто используются, когда ваша программа/проект разделена на несколько файлов исходного кода, и вы хотите, скажем, использовать в файле1 переменную, определенную в файле2.

И, наконец, поскольку мы обсуждаем области действия переменных, было бы лучше, если бы мы также обсудили статические переменные. Статические переменные особенные в том смысле, что они сохраняют свое значение даже после выхода из области видимости. Это означает, что они инициализируются только один раз, то есть в первый раз.

static int counter 

Ниже приведен фрагмент кода, который использует статическую переменную для подсчета количества вызовов функции.

#include <stdio.h>

int swap (int val1, int val2)
{
static int counter = 1;
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\n Function called %d times\n", counter);
counter++;
}

int main()
{
int a=9, b=4;

swap(a,b);
swap(a,b);
swap(a,b);

return 0;
}

Вот результат:

 Function called 1 times 

Function called 2 times

Function called 3 times

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

В этом руководстве мы обсудили несколько важных концепций, связанных с областью действия переменных в языке программирования C. Не забудьте создать свои собственные программы, чтобы лучше понять разницу между внешними, статическими, глобальными и локальными переменными. И, как всегда, в случае каких-либо сомнений или вопросов, оставьте комментарий ниже.