当一个工程很大,有多个源文件时,其中一个源文件可能会用到另一个源文件中的变量,或者函数。这时可以把这些变量或函数声明成全局变量,方法就是在一个变量 或函数声明的前面加上extern 单独放在一个头文件中,让其他的源文件包含这个头文件,但是要注意的是可能有很多的 源文件包含了这个头文件。这个时候只能有其中的一个源文件定义该变量或函数 ,否则会造成重复定义。
下面这个例子的运行环境是在 codeblocks 下:
一个 test project 包含了 a.cpp 和 main.cpp 两个源文件和 a.h 一个头文件
a.h 头文件中有如下的声明:
extern char a;
extern void msg();
然后下面是a.cpp 中的内容:
#include <iostream>
#include "a.h"
using namespace std;
char a='A';
void msg(){
cout<<"hello world!\n";
}
以看到其中先包含了头文件并且实现了对 变量 a 和 msg函数的 定义。
最后看一下main.cpp 函数:
#include <iostream>
#include <stdio.h>
#include "a.h"
using namespace std;
//extern char a;
//void msg();
int main(){
cout<<a<<endl;
msg();
return 0;
}
Mian.cpp 文件中包含了 a.h 头文件 然后在 main 函数里直接调用 a 和 msg
以上工程编译运行成功:
extern :
1. extern 类型 变量名;
这就是变量的声明,放在头文件中表示是一个全局变量,让源文件来包含它。对于头文件中的某一个全局变量或函数,一个工程中应该只有一个源文件会定义它,否则会有重复定义的错误。
或者可以直接在源文件中这样声明变量 ,它告诉该文件这个变量会在其他文件中定义,其实你可以在该文件中定义,但这样 extern 显得没有必要 ,不如直接定义。
其实一个工程中的所有文件都是一起编译的,所以一个工程中的所有文件,注意我说的是不加 static 的情况下是不能定义同名变量的,但是如果加了 static 就不一样了,static 的其中一个作用是变量的定义范围是该文件,文件之外就看不到该变量了。这样不同文件就可以定义同名的变量了。
Note : extern 变量类型 变量名= 初始化值 extern 就不起作用了。就是定义了。
2. extern 函数声明
其实在函数声明前加 extern 是多余的,因为不加也是声明,如果在变量前不加 extern ,声明就变成了定义了。
3. extern 函数定义:
extern 只是说明 该函数可以被外部文件使用, 其实 不加 extern ,默认是extern 的。
Static :
1. static 修饰全局变量或函数:
static 修饰全局变量 说明这个全局变量或函数在该文件外部是不可见的
这样一个工程下的不同的文件能够定义名称相同的变量
下面是例子:
还是上面工程的结构:
a.cpp:
#include <iostream>
//#include "a.h"
using namespace std;
static char a='A';
void msg(){
cout<<"hello world!\n";
}
Main.cpp:
#include <iostream>
#include <stdio.h>
#include "a.h"
using namespace std;
char a='B';
int main(){
cout<<a<<endl;
msg();
return 0;
}
c可以看到 main.cpp 和 a.cpp中都定义了 a 但是 a.cpp 中的 a 是static 的,所以 不会冲突。
1. static 修饰局部变量
static 修饰局部变量 会延长局部变量的生命期,本来局部变量在函数被调用时,在栈上分配空间,加上 static 后就变成在堆上分配空间,而且只会初始化一次,下次再调用该函数对应的值就是上次退出时的值,不会再重新初始化(虽然语句还是写着重新初始化,相当于全局变量)。但是注意的是变量的作用范围还是没有变,还是在函数范围内。
下面是例子:
代码:
#include <iostream>
#include <stdio.h>
using namespace std;
void ss(){
static int a=0;
a++;
cout<<a<<endl;
}
int main(){
for(int i=0;i<7;i++)ss();
return 0;
}