Каждая переменная, объявленная в программе, имеет две важнейшие характеристики: время существования и область видимости.
Время существования (время жизни) может быть двух видов:
- локальное – при выполнении блока, в котором переменная объявлена;
- глобальное – при выполнении всей программы.
Область видимости (область действия) также может быть двух видов.
- До конца блока, в котором объявлена переменная. В данном случае под блоком понимается тело функции, составной оператор {}, операторы if, for, while.
- До конца файла, в котором объявлена переменная.
Управлять этими характеристиками можно изменяя место объявления переменной в программе или используя спецификаторы классов памяти auto, register, static, extern.
Автоматическая (auto) переменная имеет локальную область действия и может быть использована только внутри блока, в котором она объявлена. Память для переменной выделяется при входе в блок и освобождается при выходе из него. Это спецификатор по умолчанию и его обычно не указывают явно.
Регистровая (register) переменная отличается от автоматической тем, что хранится в регистровой памяти, работа с которой происходит быстрее, чем с оперативной. Если свободной регистровой памяти нет (её объем довольно мал), то переменная становится автоматической.
Внешняя (extern) переменная является глобальной. Этот спецификатор говорит компилятору, что переменная будет объявлена (без extern) в другом файле.
Статической (static) переменной память выделяется после её объявления и сохраняется до конца выполнения программы. Статические переменные при объявлении по умолчанию инициализируются нулевыми значениями. Кроме того, они являются локальными для файла, т.е. из других файлов программы такая переменная доступна не будет.
register int loc = 100; // локальная переменная loc
{
char ch = 'c';
cout << ch; // выведет c
int restr = 50;
{
int totally_loc;
} // конец области действия totally_loc
} // конец области действия restr и ch из составного оператора
cout << ch; // выведет b
func(0);
system("PAUSE");
} // конец области действия loc и ch из функции main
void func(int param)
{
int loc; // локальная переменная loc, никак не связанная с первой
cout << ch; //выведет a
} // конец области действия param и loc
В приведённой программе на примере переменной ch показано, что в разных блоках могут быть объявлены переменные с одинаковыми именами. В этом случае переменная, объявленная внутри блока «перекрывает» переменную, объявленную выше.
Глобальная переменная ch перекрывается в функции main локальной переменной с таким же именем. А та ещё раз перекрывается переменной, объявленной внутри составного оператора {}.
При этом значение вышеобъявленной переменной никак не меняется при работе с локальной, и после выхода из блока его снова можно будет использовать.