extern可以实现多文件共享同一个变量、const常量、函数。

下面结合几个例子来讲一下extern的相关性质(下述皆为多文件编译):

例1:

//file1.cpp
#include<iostream>
using namespace std; extern int count; int main(){ cout<<count<<endl;
return 0; } //file2.cpp int count=3; ...

将两个文件一起编译,则输出会是3,因为file1使用了在file2中定义的全局变量count,全局变量也叫外部变量,具有外部链接性,意思就是可以被外部文件引用。

注意,当使用extern声明变量时,要求被声明的变量只能在一个文件中被定义,比如再有个file3里面也定义了一个名为count的全局变量,然后跟file1、file2一起编译,那编译器就会报错,因为不知道要引用哪个count,这也被称为单独定义规则。

总而言之,在多文件程序中,可以在一个文件(且只能在一个文件)中定义一个外部变量。使用该变量的其他文件必须使用extern来声明他。(摘自C++ Primer Plus)

例2:

//file1.cpp
#include<iostream>
using namespace std; void f(int x){ if(x>3) return;
extern int count;
count++;
cout<<count<<endl;
f(x+1);
} int main(){
f(1);
return 0;
} //file2.cpp int count=1;
...

上述例子中,file1和file2一起编译,运行后的输出是:

2

3

4

因为file1使用extern声明的count实际上就是file2中的count(同一个存储地址),file1只是声明要引用file2中的count,而不是重新定义一个count,所以即使递归调用函数也不会影响count保留上一次的值。这一点跟用static定义一个内部变量很像,不同的是static定义的内部变量只能初始化一次,而extern声明的变量不能初始化。

例3:

//file1.cpp
#include<iostream>
using namespace std; extern const int x; int main(){
cout<<x<<endl;
return 0;
} //file2.cpp
extern const int x=5;
...

上述例子中,file1和file2一起编译,运行后的输出是5。显然file1通过extern声明引用了在file2中的const常量x。

但是为什么file1和file2都要加extern? 要如何实现多个文件共享一个const常量呢?

因为const声明的常量它的链接性是内部的,默认是不能被其他文件用extern引用的。也就是说例1中说的单定义规则对它并不适用,所以即使在多个文件中定义同名的const常量,也不会有问题。

可以使用extern来覆盖其默认的内部链接性,就像file2中做得那样,并且只能在一个文件中被初始化。

```c++
例4:

//file1.cpp

include

using namespace std;

extern void f(int x);

int main(){

f(2);

return 0;

}

//file2.cpp

include

using namespace std;

void f(int x){

cout<<x<<endl;

}

...


上述例子的输出为2,file1中利用extern引用了file2中的extern。函数的链接性和常规变量类似,故例1中讲的性质对函数都适用,不再赘述。 若想函数只在文件内部可见,可使用static关键字将函数的链接性设置为内部的。

关于C++中extern的简单笔记的更多相关文章

  1. Unity3d中SendMessage 用法简单笔记

    Message相关有3条指令:SendMessage ("函数名",参数,SendMessageOptions) //GameObject自身的ScriptBroadcastMes ...

  2. 【转载】C/C++中extern关键字详解

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

  3. C/C++中extern关键字解析

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

  4. C/C++中extern关键字详解

    转自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html 1 基本解释:extern可以置于变量或者函数前,以标示变 ...

  5. Android_简单笔记一

    入门学习Android的简单笔记(已经安装好了开发环境ADT) 一.关于 AndroidManifest.xml文件 1. android:icon和android:label定义了应用程序安装后显示 ...

  6. C++中extern(转)

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

  7. C++中extern “C”含义及extern、static关键字浅析

    https://blog.csdn.net/bzhxuexi/article/details/31782445 1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C ...

  8. C/C++中extern关键字详解(转)

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

  9. ES6中Map数据结构学习笔记

    很多东西就是要细细的品读然后做点读书笔记,心理才会踏实- Javascript对象本质上就是键值对的集合(Hash结构),但是键只能是字符串,这有一定的限制. 1234 var d = {}var e ...

随机推荐

  1. java中反射知识点总结

      1 package Demo; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Field; 5 impo ...

  2. springMVC执行流程及架构

    目录 springMVC简单执行流程 springMVC框架 注解实现 springMVC简单执行流程 springMVC框架 执行流程: 1.用户发送请求至前端控制器DispatcherServle ...

  3. CentOS7下载配置PostgreSQL的pgAgent运行代理作业

    1.安装PostgreSQL 参考官方文档https://www.postgresql.org/download/linux/redhat/,运行如下命令 yum install https://do ...

  4. redis设计与实现(一)简单动态字符串

    redis是C语言实现的,但redis中的字符串并没有直接用C语言中的字符串表示,而是自己构建了一种简单的动态字符串类型(SDS). 在redis里面,C字符串只用作字面量,用在一些不会修改的地方,e ...

  5. webpack 入门和常用插件的使用

    常用配置参数 module.exports = { context: path.resolve(__dirname, '../'), entry: { app: './src/main.js' }, ...

  6. 渐进增强(progressive enhancement)、优雅降级(graceful degradation)

    渐进增强 progressive enhancement: 针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果.交互等改进和追加功能达到更好的用户体验. 优雅降级 grace ...

  7. mysql新加用户设置权限

    1.开通操作权限和表权限 GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT ON interface.* TO test1@'%' identif ...

  8. 【异常】ERROR in ch.qos.logback.core.joran.spi.Interpreter@159:22 - no applicable action for [charset], current ElementPath is [[configuration][appender][encoder][charset]]

    一.异常信息 Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException at ...

  9. linux设备驱动程序--bus

    linux 中bus驱动解析 总线(bus)是linux发展过程中抽象出来的一种设备模型,为了统一管理所有的设备,内核中每个设备都会被挂载在总线上,这个bus可以是对应硬件的bus(i2c bus.s ...

  10. 接口自动化--unittest

    今天我介绍一个测试框架:不管我们是做接口自动化还是UI自动化,我们都要用的一个框架---unittest unittest是python里面的一个单元测试框架,我们做自动化测试的话,都是要用到这个测试 ...