extern关键字会提升变量或者函数的逼格,使得它们可以跨文件被访问。话虽然是这么说,使用这个关键字必须要注意一些东西。
首先,你得在cpp文件里面实现这些全局变量和全局函数,这是最基本的,然后只需要在需要用到这些变量和函数的文件里声明一下,用extern修饰声明,这样弄完之后就可以随意使用这些全局变量和全局函数了。请不要为编译器担心,担心它们找不到这些东西,只要你实现了,不怕编译器找不到。
在别的文件里写一堆的extern声明显得特别不专业,也显得代码十分臃肿,有没有好的做法呢?有的。
我们一般把所有的全局变量和全局函数都放在一个*.cpp文件里面,然后用一个同名的*.h文件包含所有的函数和变量的声明。用法的示例如下:
/*Demo.h*/ #ifndef _DEMO_H_ #define _DEMO_H_ extern int a; extern int b; int add(int a, int b); #endif /** //下面的写法也可以 #pragma once extern int a; extern int b; */
/*Demo.cpp*/ #include "Demo.h" /*这句话写或者不写在本例中都行,不过建议不写*/ /*不写不会出问题,写了有些情况下会出问题,最后有解释*/ int a = 10; int b = 20; int add(int l, int r) { return l + r; }
/*main.cpp*/ #include "Demo.h" #include <iostream> using namespace std; void main() { cout << "a = " << a << ", b = " << b << endl; int c = add(1, 2); printf("c = 1 + 2 = %d \n", c); system("pause"); }
运行结果如下:
这样处理之后只需要到用到的地方加入#include"Demo.h"一句即可,很方便吧!这么干方便了这些变量和全局函数的管理。
下面是关于extern关键字的一些说明:
(1)extern声明外部函数
在A.cpp中使用B.cpp中的函数,需要extern声明。定义的形式类似于:
extern int a;
这里需要注意定义和声明的区别,extern int a = 10;属于定义了。
/*Demo.h*/ #ifndef _DEMO_H_ #define _DEMO_H_ extern int a = 10; extern int b = 20; int add(int a, int b); #endif /** //下面的写法也可以 #pragma once extern int a; extern int b; */
/*Demo.cpp*/ #include "Demo.h" int a = 10; int b = 20; int add(int l, int r) { return l + r; }
/*main.cpp*/ #include "Demo.h" #include <iostream> using namespace std; void main() { cout << "a = " << a << ", b = " << b << endl; int c = add(1, 2); printf("c = 1 + 2 = %d \n", c); system("pause"); }
这么干肯定是编译不通过的,因为存在重定义,#include"Demo.h"这一句是单纯的代码替换,在Demo.cpp和main.cpp里替换之后你自然发现全局变量被定义了两次,肯定会报错。一句话,声明可以拷贝n次,但是定义只能定义一次。
(2)extern声明全局变量
在A.cpp中使用B.cpp中的全局变量,需要extern声明。
extern关键字的作用是告诉编译器,在某个cpp文件中,存在这么一个函数/全局变量。
函数的声明类似于:
extern int sum(int, int);
函数的声明语句中,关键字extern可以省略,因为全局函数默认是extern类型的,因此也就出现了Demo.h中的状况。
虽然用extern声明了变量和函数之后,在别的文件里就随意使用了,但是你也千万别忘了书写变量和函数的实现,否则就会出现无定义,编译无法通过。
还有一件很有趣的事情,如果你将前面的Demo.cpp改为Demo.c的话,编译器会告诉你说找不到变量和函数的定义,怎么办呢?
我们将Demo.h里面的东西改一下写法即可:
/*Demo.h*/ #ifndef _DEMO_H_ #define _DEMO_H_ #ifndef _cplusplus extern "C" { #endif extern int a; extern int b; int add(int a, int b); #ifndef _cplusplus } #endif #endif
/*Demo.c*/ //#include "Demo.h" #include <stdio.h> int a = 10; int b = 20; int add(int l, int r) { #ifndef _cplusplus printf("这是一个c程序!\n"); #endif // !_cplusplus #ifdef _cplusplus printf("这是一个c++程序!\n"); #endif // !_cplusplus return l + r; }
/*main.cpp*/ #include "Demo.h" #include <iostream> using namespace std; void main() { #ifdef _cplusplus cout << "这是一个c++程序" << endl; #endif #ifndef _cplusplus cout << "这是一个c程序" << endl; #endif cout << "a = " << a << ", b = " << b << endl; int c = add(1, 2); printf("c = 1 + 2 = %d \n", c); system("pause"); }
说实话,结果我挺震惊的,在Demo.c文件中定义的函数跑出一个“这是一个c程序”,也没什么,在一个cpp文件中的函数跑出一个“这是一个c程序”,我就很震惊了,原因我也不清楚,不过基本就是上面的解决方案了,最后说一下不在Demo.c包含#include"Demo.h"的原因,因为在extern “C”并不是为C所支持,其实也不算吧!
因为网上说.c文件没有定义_cplusplus而cpp文件定义了_cplusplus,如果真是这样在Demo.c包含#include"Demo.h"也不会出现问题,可是不知道是我的编译器原因还是什么的,c文件和cpp文件都没定义_cplusplus,因此有可能Demo.c包含#include"Demo.h"出现问题,因为为了能在cpp文件中使用,Demo.h文件里我一般要写成#ifndef_cplusplus,此时若Demo.c包含#include"Demo.h",恰好c文件中也没有定义_cplusplus,那么extern “C”就暴露出来了,自然会错。
http://pan.baidu.com/s/1hqnddWS
原文地址:http://blog.csdn.net/lishuhuakai/article/details/45944735