6.4 – Введение в глобальные переменные
В уроке «6.3 – Локальные переменные» мы рассмотрели, что локальные переменные – это переменные, определенные внутри функции (или параметры функции). Локальные переменные имеют область видимости блока (видны только внутри блока, в котором они объявлены) и имеют автоматическую продолжительность (они создаются в точке определения и уничтожаются при выходе из блока).
В C++ переменные также могут быть объявлены вне функции. Такие переменные называются глобальными переменными.
Объявление и именование глобальных переменных
По соглашению глобальные переменные объявляются в верхней части файла, ниже включений заголовочных файлов, но выше любого кода. Ниже показан пример определения глобальной переменной:
#include <iostream>
// Переменные, объявленные вне функций, являются глобальными переменными
int g_x {}; // global variable g_x
void doSomething()
{
// глобальные переменные можно видеть и использовать везде в файле
g_x = 3;
std::cout << g_x << '\n';
}
int main()
{
doSomething();
std::cout << g_x << '\n';
// глобальные переменные можно видеть и использовать везде в файле
g_x = 5;
std::cout << g_x << '\n';
return 0;
}
// g_x выходит из области видимости здесь
Приведенный выше пример напечатает:
3
3
5
По соглашению многие разработчики добавляют к идентификаторам глобальных переменных префикс "g" или "g_", чтобы указать, что они глобальные.
Лучшая практика
Рассмотрите возможность использования префикса "g" или "g_" для глобальных переменных, чтобы помочь отличить их от локальных переменных.
Глобальные переменные имеют область видимости файла и статическую продолжительность
Глобальные переменные имеют область видимости файла (также неофициально называемую глобальной областью видимости или областью видимости глобального пространства имен), что означает, что они видны с момента объявления до конца файла, в котором они объявлены. С момента объявления глобальную переменную можно использовать в любом месте файла! В приведенном выше примере глобальная переменная g_x
используется в обеих функциях doSomething()
и main()
.
Поскольку они определяются вне функции, глобальные переменные считаются частью глобального пространства имен (отсюда и термин «область видимости глобального пространства имен»).
Глобальные переменные создаются при запуске программы и уничтожаются при ее завершении. Это называется статической продолжительностью. Переменные со статической продолжительностью иногда называют статическими переменными.
В отличие от локальных переменных, которые по умолчанию не инициализируются, статические переменные по умолчанию инициализируются нулем.
Инициализация глобальной переменной
При желании неконстантные глобальные переменные можно инициализировать:
int g_x; // без явного инициализатора (по умолчанию инициализируется нулем)
int g_y {}; // инициализируется нулем
int g_z { 1 }; // инициализируется значением
Константные глобальные переменные
Как и локальные переменные, глобальные переменные могут быть константными. Как и все константы, константные глобальные переменные должны быть инициализированы.
#include <iostream>
const int g_x; // ошибка: константные переменные необходимо инициализировать
constexpr int g_w; // ошибка: переменные constexpr должны быть инициализированы
const int g_y { 1 }; // глобальная константная переменная g_y, инициализированная значением
constexpr int g_z { 2 }; // глобальная переменная constexpr g_z, инициализированная значением
void doSomething()
{
// глобальные переменные можно видеть и использовать везде в файле
std::cout << g_y << '\n';
std::cout << g_z << '\n';
}
int main()
{
doSomething();
// глобальные переменные можно видеть и использовать везде в файле
std::cout << g_y << '\n';
std::cout << g_z << '\n';
return 0;
}
// g_y и g_z выходят из области видимости здесь
Связанный контент
Мы обсудим глобальные константы подробнее в уроке «6.8 – Глобальные константы и встраиваемые (inline
) переменные».
Предупреждение о (неконстантных) глобальных переменных
У начинающих программистов часто возникает соблазн использовать множество глобальных переменных, потому что их можно использовать без явной передачи их каждой функции, которая в них нуждается. Однако следует вообще избегать использования неконстантных глобальных переменных! А почему, мы обсудим в следующем уроке «6.9 – Почему глобальные переменные – это зло».
Краткое резюме
// Неконстантные глобальные переменные
int g_x; // Определяет неинициализированную глобальную переменную
// (по умолчанию инициализируется нулем)
int g_x {}; // Определяет глобальную переменную, явно инициализированную нулем
int g_x { 1 }; // Определяет явно инициализированную глобальную переменную
// Константные глобальные переменные
const int g_y; // ошибка: константные переменные необходимо инициализировать
const int g_y { 2 }; // определяет инициализированную глобальную константу
// Constexpr global variables
constexpr int g_y; // ошибка: переменные constexpr должны быть инициализированы
constexpr int g_y { 3 }; // определяет инициализированную глобальную константу