在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声明变量,作用域扩展到从声明开始,到本文件结束。
   
   例子:

#include <stdio.h>

   int max(int x,int y); //函数提前声明

   int main(int argc,char *argv[ ] )

   {

   int result;

   extern int X; //外部变量声明

   extern int Y;

   result = max(X,Y);

   printf("the max value is %dn",result);

   return 0;

   }

   int X = 10; //定义外部变量

   int Y = 20;

   int max(int x, int y)

   {

   return (x>y ? x : y);

   }

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

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

#include <stdio.h>

   int BASE=2; //变量定义

   int exe(int x); //外部函数提前声明

   int main(int argc, char *agrv[])

   {

   int a=10;

   printf("%d^%d = %dn",BASE,a,exe(a));

   return 0;

   }

   文件b.c的内容:

   #include <stdio.h>

   extern BASE; //外部变量声明

   int exe(int x)

   {

   int i;

   int ret=1;

   for(i=0;i<x;i++)

   {

   ret*=BASE;

   }

   return ret;

   }

利用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的内容:

#include <stdio.h>

 #include "b.h"

 #include "c.h"

 A_class local_post={1,2,3}; //全局变量

 A_class next_post={10,9,8}; //全局变量

 int main(int argc,char *argv[])

 {

 A_class ret;

 print("first point",local_post);

 print("second point",next_post);

 ret=fun(local_post,next_post);

 printf("the vector is (%d,%d,%d)n",ret.x,ret.y,ret.z);

 return 0;

 }

文件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. Sql Server查询同一ID 时间较大的一条数据

  2. VS2010/MFC编程入门之十八(对话框:字体对话框)

    鸡啄米在上一节为大家讲解了文件对话框的使用,本节则主要介绍字体对话框如何应用. 字体对话框的作用是用来选择字体.我们也经常能够见到.MFC使用CFontDialog类封装了字体对话框的所有操作.字体对 ...

  3. zw版【转发·台湾nvp系列Delphi例程】HALCON MoveRectangle2

    zw版[转发·台湾nvp系列Delphi例程]HALCON MoveRectangle2 procedure TForm1.Button1Click(Sender: TObject);var img ...

  4. Hadoop-1.0.4集群搭建笔记

    这篇文章介绍的是简单的配置Hadoop集群的方法,适合实验和小型项目用,正式运行的集群需要用更正规的方法和更详细的参数配置,不适合使用这篇文章. 相关随笔: 用python + hadoop stre ...

  5. [Opencv]图像的梯度与边缘检测(转)

    文章来源:https://blog.csdn.net/on2way/article/details/46851451 梯度简单来说就是求导,在图像上表现出来的就是提取图像的边缘(不管是横向的.纵向的. ...

  6. 学习gulpfile.babel.js随笔

    'use strict' import gulp from 'gulp' //将gulp插件包含进来 import sass from 'gulp-sass' //编译sass文件 import im ...

  7. 指定html转pdf文档

    1.资源 <script type="text/javascript" src="./js/canvg2.js"></script> & ...

  8. JavaScript权威指南--window对象

    知识要点 window对象及其客户端javascript所扮演的核心角色:它是客户端javascript程序的全局对象.本章介绍window对象的属性和方法,这些属性定义了不同的API,但是只有一部分 ...

  9. 辗转相除法 & 裴蜀定理

    2018-03-11 17:39:22 一.辗转相除法 在数学中,辗转相除法,又称欧几里得算法(英语:Euclidean algorithm),是求最大公约数的算法.辗转相除法首次出现于欧几里得的&l ...

  10. MQ是什么 RabbitMQ

    一.rabbitMQ是什么: RabbitMQ,遵循AMQP协议,由内在高并发的erlanng语言开发,用在实时的对可靠性要求比较高的消息传递上. 学过websocket的来理解rabbitMQ应该是 ...