定义全局变量时使用static,意味着该变量的作用域只限于定义它的源文件中,其它源文件不能访问。既然这种定义方式出现在头文件中,那么可以很自然地推测:包含了该头文件的所有源文件中都定义了这些变量,即该头文件被包含了多少次,这些变量就定义了多少次。
// head.h
#ifndef _HEAD_H_
#define _HEAD_H_
#include <iostream>
using namespace std;
static int global;
void Func();
#endif // _HEAD_H_
// head.cpp
#include "head.h"
void Func()
{
global = 10;
cout << "Head Func: " << global << "," << &global << endl;
}
// main.cpp
#include "head.h"
int main()
{
cout << "Main Func: " << global << "," << &global << endl;
system("pause");
return 0;
}
输出结果:
在C语言中,extern用在变量或函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”。
在C++中的extern还有一个作用!就是用来指示C或C++函数的调用规范。
比如在C++中调用C库函数,就需要在C++程序中使用extern "C"声明要引用的函数。这是给链接器使用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规范不同,用此来解决名字匹配问题。
// head.h
#ifndef _HEAD_H_
#define _HEAD_H_
#include <iostream>
using namespace std;
int global;
void Func();
#endif // _HEAD_H_
// head.cpp
#include "head.h"
void Func()
{
global = 10;
cout << "Head Func: " << global << "," << &global << endl;
}
// main.cpp
#include <iostream>
using namespace std;
extern int global;
extern void Func();
int main()
{
cout << "Main Func: " << global << "," << &global << endl;
system("pause");
return 0;
}
输出结果:
一般局部变量是存储在栈区的,局部变量的生命周期在其所在的语句块执行结束时便结束了。但如果用static修饰局部变量,那么这个变量就不会存储在栈区而是放在静态数据区,其生命周期会一直持续到整个程序结束
不过需要注意的是:
- 虽然static局部变量的生命周期变长了,但其作用域依然仅限于其所在的语句块
- static修饰局部变量后,该变量只在初次运行时进行初始化,且只进行一次
总结:
在编译的时候,head.cpp会和head.h一起编译, 然后main.cpp也会和head.h一起编译, 但是要注意, 编译器分别编译这两组文件的时候, 变量global会分别分配地址,然后初始值也都为0;
这就意味着, 在head.cpp中如果调用了global, 其初始值为0;假设在head.cpp中global随后被修改为了10, 然后main.cpp中也调用了global,这时global的初始值还是0, 而不是10!