全局变量声明和定义分离
写在前面
关键字 | 生命周期 | 作用域 | 在头文件中修饰变量 |
---|---|---|---|
extern | 静态(程序结束后释放) | 整个程序 | 属于声明 |
static | 静态(程序结束后释放) | 仅存在于单个源文件(编译单元) | 属于定义 |
extern
只是声明了这个变量的存在,在.cpp
文件中定义时的全局变量在整个项目中都可以使用static
定义了这个变量,然后头文件分别和两个.cpp
文件合并生成两个.obj
文件,再生成可执行程序,这个变量在两个.cpp
文件都是可见的,并且占用不同的地址空间
详情见下:
extern声明的全局变量
extern int a;//放在.h中,属于声明
int a = 10;//放在.cpp中,属于定义
这里主要探讨关于
extern int a;
放在头文件中的问题//class.h #pragma once #include <iostream> using namespace std; extern int a; int text();
//class.cpp #define _CRT_SECURE_NO_WARNINGS #include "class.h" int a = 10; int main() { text(); cout << "main():" << a << "," << &a << endl; return 0; }
//test.cpp #define _CRT_SECURE_NO_WARNINGS #include "class.h" int text() { cout << "text():" << a << "," << &a << endl; a++; return 0; }
运行结果:
可以看到这里text和main调用的都是同一变量,在不同文件中也可做修改。
也就是说
extern
只是声明了这个变量的存在,在.cpp
文件中定义时的全局变量在整个项目中都可以使用
static修饰的变量
int age = 100;//放在.h中
这中写法会放入符号表并且所有文件可见,同时会产生一个问题,也就是所有文件可见的话在一个项目中不同的文件都可以调用的话就会造成同一个变量的重定义。
static int age = 10;//放在.h中
这种写法不会放入符号表,只有当前文件可见,但当我们在不同文件中进行打印的时候会发现,不同文件对于同一名称的变量的将进行赋值和取地址的时候获得的值也不同,详细见下
这里主要探讨关于
static int age = 10;
放在头文件中的问题//class.h #pragma once #include <iostream> using namespace std; static int age = 100;//所有文件可见,属于定义 void text();
//text.cpp #define _CRT_SECURE_NO_WARNINGS #include "class.h" void text() { cout << "text():" << age << endl; cout << "text():" << &age << endl; age++; cout << "text2():" << age << endl; cout << "text2():" << &age << endl; }
//class.cpp #define _CRT_SECURE_NO_WARNINGS #include "class.h" int main() { text(); cout << endl << endl; cout << "main():" << age << endl; cout << "main():" << &age << endl; age++; age++; age++; age++; age++; cout << "main()2:" << age << endl; cout << "main()2:" << &age << endl; return 0; }
运行结果:
通过这里我们可以看到在不同的
.cpp
中访问到的.h
中被static
修饰的变量的地址都不同,可以理解为是在头文件展开的时候在不同的文件中都会进行一次定义,所以就会造成不同.cpp
中变量的名称相同但是变量的地址不同。
static
定义了这个变量,然后头文件分别和两个.cpp
文件合并生成两个.obj
文件,再生成可执行程序,这个变量在两个.cpp
文件都是可见的,并且占用不同的地址空间