$ tree
.
├── head.cpp
├── head.h
└── main.cpp
0 directories, 3 files
// head.h
#ifndef __HEAD_H__
#define __HEAD_H__
int global_num;
int func();
#endif
// head.cpp
#include <stdio.h>
#include "head.h"
int func(){
global_num = 10;
printf("head func, %d %p\r\n",global_num,&global_num);
}
// main.cpp
#include <stdio.h>
#include "head.h"
int main(int argc, char const *argv[])
{
global_num = 100;
func();
printf("main : %d %p \r\n",global_num,&global_num);
return 0;
}
测试结果:
$ g++ *.cpp
/tmp/ccpCgEuI.o:(.bss+0x0): `global_num'被多次定义
/tmp/ccFO725K.o:(.bss+0x0):第一次在此定义
collect2: error: ld returned 1 exit status
but why ?
提示 全局变量 global_num 重复定义 !!!
static-test
尝试添加 static 关键字 :
// head.h
#ifndef __HEAD_H__
#define __HEAD_H__
// int global_num;
static int global_num;
int func();
#endif
// head.cpp
#include <stdio.h>
#include "head.h"
int func(){
global_num = 10;
printf("head func, %d %p\r\n",global_num,&global_num);
}
// main.cpp
#include <stdio.h>
#include "head.h"
int main(int argc, char const *argv[])
{
global_num = 100;
func();
printf("main : %d %p \r\n",global_num,&global_num);
return 0;
}
$ g++ *.cpp
$ ./a.out
head func: 10 0x55d54c106014
main : 100 0x55d54c106018
发现两个 global_num 变量的地址已经不是同一个了 !
为什么在 head.h 中声明的一个 global_num 变量, 最终在多个 cpp 文件中 include 之后就变成了多个呢 ??
method-1
尝试使用 extern 关键字 :
// head.h
#ifndef __HEAD_H__
#define __HEAD_H__
// int global_num;
// static int global_num;
int func();
#endif
// head.cpp
#include <stdio.h>
#include "head.h"
// 在这里定义变量 global_num
int global_num;
int func(){
global_num = 10;
printf("head func, %d %p\r\n",global_num,&global_num);
}
// main.cpp
#include <stdio.h>
#include "head.h"
// 在其他需要用到该变量的地方使用 extern
extern int global_num;
int main(int argc, char const *argv[])
{
int global_num = 0; // 局部变量在函数内部会被同名全局遍历覆盖
global_num = 100;
func();
printf("main : %d %p \r\n",global_num,&global_num);
return 0;
}
$ g++ *.cpp
$ ./a.out
head func : 10 0x561a83693014
main : 100 0x7fffdad6b394
发现这个时候的 global_num 确实是多个文件都可以访问到的全局变量了 !
method-2
extern 修饰全局变量的另一种用法 :
在 xxx.h 中
extern int global_num;然后在其他的 cpp 中#include "xxx.h"就可以了 int func(); 其实就是等价于extern int func();
在头文件中修饰函数的时候,extern关键字可省略 但是这种方法存在一个问题 :
// head.h
#ifndef __HEAD_H__
#define __HEAD_H__
// int global_num;
// static int global_num;
extern int global_num;
int func();
#endif
// head.cpp
#include <stdio.h>
#include "head.h"
// 在这里定义变量 global_num
int global_num;
int func(){
global_num = 10;
printf("head func : %d %p\r\n",global_num,&global_num);
}
// main.cpp
#include <stdio.h>
#include "head.h" // 直接 include 即可引用到 extern 全局变量
// 在其他需要用到该变量的地方使用 extern
// extern int global_num;
int main(int argc, char const *argv[])
{
int global_num = 0; // 局部变量在函数内部会被同名全局遍历覆盖
global_num = 100;
func();
printf("main : %d %p \r\n",global_num,&global_num);
return 0;
}
test:
$ g++ *.cpp head.h
$ ./a.out
head func : 10 0x55f31800b014
main : 100 0x7ffcf71d8e74
可以看出两个 global_num 的地址是不一样的, 原因是 main 中的局部变量 int global_num=0; 的地址, 可 为什么同名的局部变量没有被全局变量覆盖掉呢 ?
总结
所以:
建议使用 :
// demo.cpp
extern int a = 100;
// 等价于 int a = 100;
// 因为现在编译器默认源文件中的全局变量可以被其他源文件引用
// test.cpp
// 引用 demo.cpp 中的全局变量 a
extern a;