面试题答案
一键面试全局变量的作用域和链接属性的联系
- 作用域:全局变量的作用域从声明处开始,到文件结束。如果使用
extern
关键字提前声明,作用域可以扩展到整个文件。 - 链接属性:
- 外部链接:默认情况下,全局变量具有外部链接。这意味着在一个源文件中定义的全局变量可以在其他源文件中通过
extern
关键字引用。例如,在文件a.cpp
中定义int globalVar;
,在b.cpp
中可以通过extern int globalVar;
来使用它。 - 内部链接:如果在全局变量定义前加上
static
关键字,该变量就具有内部链接。此时,变量只能在定义它的源文件内可见,其他源文件无法访问。例如,static int localVar;
,这个变量只能在当前源文件中使用。 - 无链接:对于局部变量,它们具有无链接属性,只在定义它们的代码块内可见。
- 外部链接:默认情况下,全局变量具有外部链接。这意味着在一个源文件中定义的全局变量可以在其他源文件中通过
使全局变量在多个源文件可见且作用域限制在特定模块
要使全局变量在多个源文件中可见,但作用域限制在特定模块,可以使用extern
关键字来声明变量,并在一个源文件中定义它。例如:
- 在
module1.h
中:
// module1.h
extern int moduleGlobal;
- 在
module1.cpp
中:
// module1.cpp
int moduleGlobal = 0;
- 在
main.cpp
中:
// main.cpp
#include "module1.h"
#include <iostream>
int main() {
std::cout << "moduleGlobal: " << moduleGlobal << std::endl;
return 0;
}
不同编译单元中使用该全局变量的注意事项
- 定义只能有一次:在整个项目中,全局变量的定义只能有一次。如果在多个源文件中都定义了同名的全局变量,链接时会出现重复定义错误。
- 声明与定义的区分:使用
extern
关键字进行声明时,只是告诉编译器该变量在其他地方定义,不会分配内存。而定义会分配内存。 - 初始化:尽量在定义全局变量时进行初始化,避免在不同编译单元中初始化顺序的问题。例如,在
module1.cpp
中定义int moduleGlobal = 0;
而不是先声明extern int moduleGlobal;
然后在其他地方初始化。
以上代码示例展示了如何在多个源文件中共享全局变量,同时将其作用域限制在特定模块。