在chinaunix上看见一篇转载的文章,觉得特别好,关于extern使用的解释:

参考链接:http://doc.chinaunix.net/CPP/201206/2248432.shtml

在C语言中,修饰符extern用在变量或者函数的声明前,用来说明"此变量/函数是在别处定义的,要在此处引用".
   
   1. extern修饰变量的声明。举例来说,如果文件a.c需要引用b.c中变量int v,就可以在a.c中声明extern int v,然后就可以引用变量v.这里需要注意的是,被引用的变量v的链接属性必须是外链接(external)的,也就是说a.c要引用到v,不只是取决于在a.c中声明extern int v,还取决于变量v本身是能够被引用到的。这涉及到c语言的另外一个话题--变量的作用域。能够被其他模块以extern修饰符引用到的变量通常是全局变量。还有很重要的一点是,extern int v可以放在a.c中的任何地方,比如你可以在a.c中的函数fun定义的开头处声明extern int v,然后就可以引用到变量v了,只不过这样只能在函数fun作用域中引用v罢了,这还是变量作用域的问题。对于这一点来说,很多人使用的时候都心存顾虑。好像extern声明只能用于文件作用域似的。
   
   2. extern修饰函数声明。从本质上来讲,变量和函数没有区别。函数名是指向函数二进制块开头处的指针。如果文件a.c需要引用b.c中的函数,比如在b.c中原型是int fun(int mu),那么就可以在a.c中声明extern int fun(int mu),然后就能使用fun来做任何事情。就像变量的声明一样,extern int fun(int mu)可以放在a.c中任何地方,而不一定非要放在a.c的文件作用域的范围中。 对其他模块中函数的引用,最常用的方法是包含这些函数声明的头文件。使用extern和包含头文件来引用函数有什么区别呢?extern的引用方式比包含头文件要简洁得多!extern的使用方法是直接了当的,想引用哪个函数就用extern声明哪个函数。这大概是KISS原则的一种体现吧!这样做的一个明显的好处是,会加速程序的编译(确切的说是预处理)的过程,节省时间。在大型C程序编译过程中,这种差异是非常明显的。
   
   3. 此外,extern修饰符可用于指示C或者C++函数的调用规范。比如在C++中调用C库函数,就需要在C++程序中用extern "C"声明要引用的函数。这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规则不同。
   
   二:了解了上面的基本原理,下面深入一下。如下:
   
   内容清单:
   
   1. 用extern声明外部变量
   
   (1)在一个文件内声明的外部变量
   
   (2)在多个文件中声明外部变量
   
   (3)在多个文件中声明外部结构体变量
   
   2. 用extern声明外部函数
   
   3. 总结
   
   1.  用extern声明外部变量
   
   定义:外部变量是指在函数或者文件外部定义的全局变量。外部变量定义必须在所有的函数之外,且只能定义一次。
   
   (1)      在一个文件内声明的外部变量
   
   作用域:如果在变量定义之前要使用该变量,则在用之前加extern声明变量,作用域扩展到从声明开始,到本文件结束。
   
   例子:

  1. #include <stdio.h>
  2.  
  3. int maxint x,int y); //函数提前声明
  4.  
  5. int mainint argc,char *argv[ ]
  6.  
  7. {
  8.  
  9. int result;
  10.  
  11. extern int X; //外部变量声明
  12.  
  13. extern int Y;
  14.  
  15. result = maxX,Y);
  16.  
  17. printf"the max value is %dn",result);
  18.  
  19. return 0;
  20.  
  21. }
  22.  
  23. int X = 10; //定义外部变量
  24.  
  25. int Y = 20;
  26.  
  27. int maxint x, int y
  28.  
  29. {
  30.  
  31. return x>y ? x : y);
  32.  
  33. }

其中,用extern声明外部变量时,类型名可以省略。例如,"extern int X;",可以改写成"extern X;".
   
   小结:这种用方法简单,实用性不大。

(2)      在多个文件中声明外部变量
   
   作用域:如果整个工程由多个文件组成,在一个文件中想引用另外一个文件中已经定义的外部变量时,则只需在引用变量的文件中用extern关键字加以声明即可。可见,其作用域从一个文件扩展到多个文件了。
   
   例子:
   
   文件a.c的内容:

  1. #include <stdio.h>
  2.  
  3. int BASE=2; //变量定义
  4.  
  5. int exeint x); //外部函数提前声明
  6.  
  7. int mainint argc, char *agrv[])
  8.  
  9. {
  10.  
  11. int a=10;
  12.  
  13. printf"%d^%d = %dn",BASE,a,exea));
  14.  
  15. return 0;
  16.  
  17. }
  18.  
  19. 文件b.c的内容:
  20.  
  21. #include <stdio.h>
  22.  
  23. extern BASE; //外部变量声明
  24.  
  25. int exeint x
  26.  
  27. {
  28.  
  29. int i;
  30.  
  31. int ret=1;
  32.  
  33. fori=0;i<x;i++)
  34.  
  35. {
  36.  
  37. ret*=BASE;
  38.  
  39. }
  40.  
  41. return ret;
  42.  
  43. }

利用gcc工具编译gcc a.c b.c –o demo,再运行。/demo,结果为2^10 = 1024.其中,在a.c文件中定义BASE=2,在b.c中引用BASE时,需要用extern关键字声明其为外部变量,否则编译会找不到该变量。
   
   小结:对于多个文件的工程,可以采用这种方法来操作。实际工程中,对于模块化的程序文件,在其文件中可以预先留好外部变量的接口,也就是只采用extern声明变量,不定义变量,也通常在模块程序的头文件中声明,在使用该模块时,只需要在使用时定义一下即可,如上述b.c文件,做好相应的函数接口,留好需要改变BASE值的声明,在需要使用该模块时,只需要在调用的文件中定义具体的值即可。
   
   引用外部变量和通过函数形参值传递变量的区别:用extern引用外部变量,可以在引用的模块内修改其值,而形参值传递的变量则不能修改其值,除非是地址传递。
   
   因此,如果多个文件同时对需要应用的的变量进行同时操作,可能会修改该变量,类似于形参的地址传递,从而影响其他模块的使用,因此,要慎重使用。
   
   (3)      在多个文件中声明外部结构体变量
   
   前面一节中,只是适合一般变量的外部声明,但是对于声明外部结构体变量时,则有些不同,需要加以注意。
   
   例子:
   
   文件a.c的内容:

  1. #include <stdio.h>
  2.  
  3. #include "b.h"
  4.  
  5. #include "c.h"
  6.  
  7. A_class local_post={1,2,3}; //全局变量
  8.  
  9. A_class next_post={10,9,8}; //全局变量
  10.  
  11. int mainint argc,char *argv[])
  12.  
  13. {
  14.  
  15. A_class ret;
  16.  
  17. print"first point",local_post);
  18.  
  19. print"second point",next_post);
  20.  
  21. ret=funlocal_post,next_post);
  22.  
  23. printf"the vector is (%d,%d,%d)n",ret.x,ret.y,ret.z);
  24.  
  25. return 0;
  26.  
  27. }

文件b.h的内容:

C语言extern关键字使用的更多相关文章

  1. C语言学习及应用笔记之六:C语言extern关键字及其使用

    在C语言中,修饰符extern用在变量或者函数的声明前,用来以标识变量或者函数的定义在别的文件中,提示编译器遇到此变量或者函数时,在其它文件中寻找其定义.extern关键字的用法有几种,我们下面对其进 ...

  2. 解决全局变量共享---C语言的extern关键字用法

    在调试程序时,有一个参数需要在多个函数之间传递,因为是作为调试参数,不想将参数引入到函数中. 很自然的想到使用全局变量来表示这个公共参数,工程代码的结构如下: main.c test.c test.h ...

  3. c语言之extern关键字

    1.定义 extern,外面的.外来的意思.那它有什么作用呢?举个例子:假设你在大街上看到一个黑皮肤绿眼睛红头发的美女(外星人?)或者帅哥.你的第一反应就是这人不是国产的. extern就相当于他们的 ...

  4. C语言中关键字auto、static、register、const、volatile、extern的作用

    原文:C语言中关键字auto.static.register.const.volatile.extern的作用 关键字auto.static.register.const.volatile.exter ...

  5. 【C语言】19-static和extern关键字1-对函数的作用

    一.extern与函数 在前面我提到过一句话:如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.o ...

  6. C语言中的 extern 关键字

    今天在 BLE 中看到很多 extern 关键字,现在总结一下: extern 关键字主要用于在一个c文件中要用到另一个c文件中的变量或者函数. example: #extern_base.c ; # ...

  7. C语言的static和extern关键字

    我的博客:www.while0.com 如果A.c要包含B.c里的一个变量或函数,则在A.c中要用extern关键字声明.注意: ①如果是包含的B.c里的函数,则在A.c里声明的时候可以不写exter ...

  8. 【转】C语言正确使用extern关键字

    利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数,下面就结合具体的实例,分类说明一下. 一.引用同一个文件中的变量 #include<stdio.h> int f ...

  9. 【C语言】20-static和extern关键字2-对变量的作用

    一.在Java中,全局变量的定义没有严格的位置规定 全局变量可以定义在类的最前面,也可以定义在类的最尾端,也就说一个方法可以访问在它之后定义的变量. 可以看到,第4行定义的test方法可以访问第8行定 ...

随机推荐

  1. nodejs+express工程 在npm install之后或使用npm install bootstrap命令安装bootstrap之后

    nodejs+express工程 在npm install之后或使用npm install bootstrap命令安装bootstrap之后引入bootstrap文件 如果你的静态资源存放在多个目录下 ...

  2. java fastjson 设置全局输出name最小化

    1.通过自定义Filter实现 https://github.com/alibaba/fastjson/wiki/SerializeFilter public class JackJsonLowCas ...

  3. 前端学习笔记之CSS浮动浅析

    很早以前就接触过CSS,但对于浮动始终非常迷惑,可能是自身理解能力差,也可能是没能遇到一篇通俗的教程. 前些天小菜终于搞懂了浮动的基本原理,迫不及待的分享给大家. 写在前面的话: 由于CSS内容比较多 ...

  4. 20145307陈俊达《网络对抗》Exp4 恶意代码分析

    20145307陈俊达<网络对抗>Exp4 恶意代码分析 基础问题回答 如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪 ...

  5. Linux硬盘扩容(非LVM)

    环境说明: 虚拟机:Centos6 [root@elements ~]# cat /etc/redhat-release CentOS release 6.10 (Final) [root@eleme ...

  6. 分布式之zk的应用场景

    分布式应用系统中,经常会用到zk,比如dubbo注册中心,kafka分布式集群等都用到zk这一工具.除了这些用来做分布式集群外,zk还有那西应用场景事我们可以使用到该工具的呢?所以接下来就是我们要了解 ...

  7. ES7学习笔记——Array.prototype.includes和求幂运算符**

    一直以来,在前端开发时使用的基本都是ES5,以及少量的ES6.3月份换工作面试时,发现一些比较大的公司,对ES6比较重视,阿里的面试官直接问ES7和ES8,对于从未接触过人来说,完全是灾难.由此也显现 ...

  8. 更改idea快捷键方式为eclipse风格

    打开配置窗口 菜单栏中的File-settings 或者快捷键 ctrl+alt+s 设置keymap 在弹出的setting页面中左侧导航中选择Keymap: 在keymaps下拉列表中选择Ecli ...

  9. Shell脚本之无限循环的两种方法

    for #!/bin/bash ;i<;)) do let "j=j+1" echo "-------------j is $j ----------------- ...

  10. c++指向指针的指针与 c++指针作为函数参数传递问题

    一直搞不明白,c++中指针到底是个啥东西,今天遇到到c++,指向指针的指针的问题,突然有点开窍了. 举个例子: int main(int argc, char** argv){ int a[5]={1 ...