Skip to content

6.4 - 全局变量

Key Takeaway
  • 考虑为全局变量添加 “g” or “g_” 前缀以区别于其他变量。
  • 全局变量具有文件作用域和静态存储持续时间
  • 全局变量在程序开始时被创建,并且在程序结束时被销毁——即静态存储持续时间
  • 具有静态存储持续时间的变量称为静态变量(static variables)
  • 静态变量具有默认初始化值 0

在 6.3 - 局部变量 中,我们介绍了局部变量。局部变量是定义在函数中(或函数参数)的变量。局部变量具有块作用域(只在定义它的块中可见),同时具有自动持续时间(在定义时创建,在块结束时销毁)。

C++ 中,变量也可以被声明在函数外面。这些变量称为全局变量。

全局变量的声明和命名

按照惯例,全局变量会被定义在文件的开头,紧接着头文件包含的后面,但是在所有代码的前面。请看下面的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

// Variables declared outside of a function are global variables
int g_x {}; // global variable g_x

void doSomething()
{
    // global variables can be seen and used everywhere in the file
    g_x = 3;
    std::cout << g_x << '\n';
}

int main()
{
    doSomething();
    std::cout << g_x << '\n';

    // global variables can be seen and used everywhere in the file
    g_x = 5;
    std::cout << g_x << '\n';

    return 0;
}
// g_x goes out of scope here

输出结果如下

1
2
3
3
3
5

一般情况下,很多程序员喜欢为全局变量添加前缀 “g” 或 “g_” 以表明它是全局的(global)。

最佳实践

考虑为全局变量添加 “g” or “g_” 前缀以区别于其他变量。

全局变量具有文件作用域和静态存储持续时间

全局变量具有文件作用域(有时候也非正式地称为全局作用域或全局命名空间作用域),也就是说这类变量从声明它的文件开头,到文件结尾都是可见的。一旦声明之后,全局变量就可以在文件的任何地方使用!在上面的例子中,全局变量 g_x 既可以在doSomething() 中使用,也可以在 main()中使用。

因为它们被定义在函数的外面,全局变量通常被认为是属于全局命名空间。

全局变量在程序开始时被创建,并且在程序结束时被销毁——即静态存储持续时间,具有静态存储持续时间的变量称为静态变量(static variables)

局部变量默认是未初始化的,静态变量则不同,它具有默认的初始值 0 。

全局变量初始化

非常量类型的全局变量也可以进行初始化(可选)。

1
2
3
int g_x; // no explicit initializer (zero-initialized by default)
int g_y {}; // zero initialized
int g_z { 1 }; // initialized with value

常量全局变量

和局部变量一样,全局变量也可以是常量。和所有的常量一样,常量全局变量必须被初始化。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

const int g_x; // 错误:const 常量必须初始化
constexpr int g_w; // 错误:constexpr 常量必须初始化

const int g_y { 1 };  // const global variable g_y, initialized with a value
constexpr int g_z { 2 }; // constexpr global variable g_z, initialized with a value

void doSomething()
{
    // global variables can be seen and used everywhere in the file
    std::cout << g_y << '\n';
    std::cout << g_z << '\n';
}

int main()
{
    doSomething();

    // global variables can be seen and used everywhere in the file
    std::cout << g_y << '\n';
    std::cout << g_z << '\n';

    return 0;
}
// g_y and g_z goes out of scope here

相关内容

我们会在6.9 - 使用 inline 变量共享全局常量详细介绍常量全局变量。

关于非常量类型全局变量的提醒

新手程序员通常会尝试定义很多全局变量,因为这样他们就可以不需要传参就能够使用这些变量。不过,通常应该避免使用非常量的全局变量!我们会在6.8 - 为什么非 const 全局变量是魔鬼中进行详细介绍。

小结

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 非常量全局变量
int g_x;                 // 定义未初始化的全局变量(默认初始化为0) 
int g_x {};              // 显示地定义初始化为0的全局变量
int g_x { 1 };           // 显示地初始化全局变量

// Const 全局变量
const int g_y;           // 错误:const 变量必须初始化
const int g_y { 2 };     // 定义并初始化全局常量

// Constexpr 全局变量
constexpr int g_y;       // 错误: constexpr 变量必须初始化
constexpr int g_y { 3 }; // 定义并初始化全局 const 变量