extern、头文件、源文件与编译和链接

21 篇文章 0 订阅

extern、头文件、源文件与编译和链接

关键字:extern 、头文件、源文件编译、全局变量的定义

谈到extern(这里只谈论同一语言编译情况下的extern,不考虑C++与C混合编译情况下的extern,因为extern在这两种情况下的功能是不同的)与头文件,不得不谈编译与链接。extern的作用与头文件基本等同,都是为编译器服务的。但头文件使用更方便一些。尤其是在做一个大的项目,很多函数和全局变量一个个extern到每个cpp文件中既不方便也很混乱,此时一条#include“xxx.h”就可以解决问题。现在的编译器是以源文件(.cpp)为单位进行编译的,编译期间(预编译期间)展开#include包含的语句。

我们在头文件中使用:

#ifndef xxxx  

#define xxxx

...

#endif

来防止重复定义,这里防止重复定义正是防止在编译一个.cpp文件期间发生的因重复包含而造成的全局变量、函数等的重复定义,但它不能防止链接各.obj等文件时出现的重复定义问题。

可能源文件各自编译时没有重复定义的问题,但是链接时出现了重复定义。

典型的例子是在各.cpp文件中共享全局变量的问题:

我们都知道,全局变量一般在.cpp文件中定义,在头文件中声明为extern  。

难道不能在头文件中定义全局变量吗?

答案是肯定的。但是,定义在该头文件中的全局变量,只能被一个.cpp文件包含。就是说,某个.cpp文件包含了这个定义了全局变量的头文件后,其它的.cpp文件就不能再包含该头文件了。如果这样的头文件被多个.cpp文件包含,各.cpp文件编译时没有问题,但是链接时一定出现重复定义的错误。

难道在头文件中定义的全局变量只能被一个.cpp文件使用吗?

答案是否定的。如果你一定要在头文件中定义全局变量并在多个.cpp文件中使用,那么必须:

1. 该头文件只能被唯一一个.cpp文件包含,不能被其它.cpp文件包含

2. 在其它.cpp文件中使用该全局变量时,必须对该全局变量进行extern声明

 

-------------------------------------------

下面给出代码实例,在vs2010上测试通过。

我们定义两个头文件 test_a.h 、 test_b.h 和三个.cpp源文件1.cpp、2.cpp 、3.cpp :

其中test_a.h中以extern声明了一个全局变量 extern int a;而该全局变量定义在3.cpp中:int a =1000。 

test_b.h中定义了一个全局变量:int b =10。test_b.h被唯一包含于3.cpp中。

具体代码如下:

test_a.h

#ifndef _TEST_A_H_

#define _TEST_A_H_

extern int a;

int func_a2();

int func_b2();

int func_a3();

int func_b3();

#endif

 

test_b.h

#ifndef _TEST_B_H_

#define _TEST_B_H_

int b=10;

#endif

 

1.cpp

#include<iostream>

#include"test_a.h"

//这里#include"test_a.h"等同于如下5条语句:

//extern int a;

//extern int func_a2(); 

//extern int func_a3();

//extern int func_b2(); 

//extern int func_b3();

//其中,四个函数之前的extern关键字可以省略。

//可以看到,头文件的功能等同于多个extern,但是它使用起来更方便。

 

extern int b;//此句不能换作#include"test_b.h",因为该头文件已在3.cpp中被包含

using namespace std;

 

int main()

{

cout<<"a测试:"<<a<<endl;

cout<<func_a2()<<endl;

cout<<func_a3()<<endl;

 

cout<<"b测试:"<<b<<endl;

cout<<func_b2()<<endl;

cout<<func_b3()<<endl;

return 1;

}

 

2.cpp

extern int a;//或者换作#include"test.h"

extern int b;//此句不能换作#include"test_b.h",因为该头文件已在3.cpp中被包含

int func_a2()

{

return ++a;

}

 

int func_b2()

{

return  ++b;

}

 

3.cpp

#include"test_a.h"//此句去掉也可以

#include"test_b.h"//此句必须保留

int a =1000;

int func_a3()

{

return --a;

}

 

int func_b3()

{

return  --b;

}

------------------------------------------- 测试结果:a测试:100010011000b测试::101110
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值