2.extern关键字的总结(未完)

2.1.定义与声明,初始化和赋值

(1)定义:负责创建与名字关联的实体。

//声明变量a(当前文件中), 并且定义a
int a = 5; 

(2)声明:使得名字为程序所知,用别处的定义的名字必须包含声明(比如其他文件的定义)

//声明a,并非定义
extern int a;

(3)声明中给予初始值

//定义a
extern int a = 5;

但是,有例外

1 //错误,不允许在函数内部这样做
2 void Test() {
3     //定义a
4     extern int a = 5;
5 }

(4)初始化:从无到有的过程,先分配空间,然后再填充数据;
       赋值:对已有的对象进行操作。

1 //将a初始化为5
2 int a=5;
3 //将a赋值为6
4 a=6;

2.2.extern的各种用法

(1)extern:可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。

(2)extern修饰变量

一种常见的错误

//在test1.cpp中有如下
int array[6];
//在test2.cpp中有如下
extern *array;

array[]是指向int类型的数组,test2.cpp中的声明是指向int类型的指针,两者区别很大。

一种常见的应用

       extern用在变量声明中常常有这样一个作用,你在*.cpp文件中声明了一个全局的变量,这个全局的变量如果要被引用,就放在*.h中并用extern来声明

(3)extern修饰函数

用来声明函数时的一个问题:

       如果函数提供方单方面修改函数原型,如果缺少参数或者改变了一些函数内部的成员操作,会引发系统错误,但是编译却能通过。一种解决办法让提供方提供在头文件中函数的声明,然后include该头文件。

当作为定义函数的一部分时候:

       如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。

当把全局变量的声明跟定义放在一起的时候:

       因为#include的存在而产生重复定义的链接错误。所以:只在头文件中做声明,真理就是这么简单。当然不使用#include语句,将想要提供给外部接口的函数和变量全部使用extern来修饰也是一种方法。你用么,反正我不用。

(4)extern "C" 

在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况,应该如何解决这种情况呢?

        C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。

使用时注意两点:

       指向extern "C"函数的指针:

1 void(*Test)(int);
2 extern "C" void(*Test_1)(int);
3 //错误,Test和Test_1的类型不同
4 Test = Test_1;

       重载函数与链接指示:

C语言没有重载函数,有了一组C语言函数之后,其同名函数必须为C++函数,否则出错。

(5)extern 与 static 

(6)extern 与 const

posted @ 2019-06-01 14:54  Royzzzzz  阅读(238)  评论(0编辑  收藏  举报