细说关于extern应用的分析

 extern

  (1)变量

  extern int a;//声明一个全局变量a

  int a; //定义一个全局变量a

  extern int a =0 ;//定义一个全局变量a 并给初值。

  int a =0;//定义一个全局变量a,并给初值

   第四个 等于 第 三个,都是定义一个可以被外部使用的全局变量,并给初值。糊涂了吧,他们看上去可真像。但是定义只能出现在一处。也就是说,不管是int a;还是extern int a=0;还是int a=0;都只能出现一次,而那个extern int a可以出现很多次。

  当你要引用一个全局变量的时候,你就要声明,extern int a;这时候extern不能省略,因为省略了,就变成int a;这是一个定义,不是声明。

  (2)函数

   函数的定义和声明是有区别的,定义函数要有函数体,声明函数没有函数体,所以函数定义和声明时都可以将extern省略掉,反正其他文件也是知道这 个函数是在其他地方定义的,所以不加extern也行。比如:

  int fun(void) { return 0; }//定义了一个全局函数 int fun(void);

  我们对它做了个声明,然后后面就可以用了加不加extern都一样我们也可以把对fun的声明 放在一个头文件里,最后变成这样

  int fun(void);//函数声明,

  所以省略了extern,完整些是extern int fun(void);

  int fun(void) { return 0; }//一个完整的全局函数定义,因为有函数体,extern同样被省略了。

  一个客户,一个要使用你的fun的客户,把这个头文件包含进去,ok,一个全局的声明。没有问题。但是,对应的,如果是这个客户要使用全局变量,那么要extern 某某变量;不然就成了定义了。

  总结下:

  对变量而言,如果你想在本源文件中使用另一个源文件的变量,就需要在使用前用extern声明该变量或者在头文件中用extern声明该变量

  对函数而言,如果你想在本源文件中使用另一个源文件的函数,就需要在使用前用声明该变量,声明函数加不加extern都没关系,所以在头文件中函数可以不用加extern。

  C程序采用模块化的编程思想,需合理地将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求,在模块的划分上主要依据功能。模块由头文件和实现文件组成,对头文件和实现文件的正确使用方法是

  规则1 头文件(.h)中是对于该模块接口的声明,接口包括该模块提供给其它模块调用的外部函数及外部全局变量,对这些变量和函数都需在.h中文件中冠以extern关键字声明;

  规则2 模块内的函数和全局变量需在.c文件开头冠以static关键字声明;

   规则3 永远不要在.h文件中定义变量;

  许多程序员对定义变量和声明变量混淆不清,定义变量和声明变量的区别在于定义会产生内存分配的操作,是汇编阶段的概念;而 声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。

  规则4 如果要用其它模块定义的变量和函数,直接包含其头文件即可。

  许多程序员喜欢这样做,当他们要访问其它模块定义的变量时,他们在本模块文件开头添加这样的语 句: extern int externVar; 抛弃这种做法吧,只要头文件按规则1完成,某模块要访问其它模块中定义的全局变量时,只要包含该模块的头文件即可。

   另:

有两种方法调用外部函数:
    1个是通过包含头文件(如#include "dll_main.h")调用dll_func_add(),
    1个是通过extern 修改函数(extern int exe_func_add()),调用exe_func_add()函数;(不建议)

    说明:
    *函数前面加extern与不加extern的区别
    1-基本解释:
    extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。使用extern修饰某函数时,对该函数的调用是在连接阶段才被处理的。
    Q&A:
    func.cpp
    #include <stdio.h>
    void func(int n) { printf("%d\n");}
    test.cpp
    extern void fun(void)
    int main()
    {fun(); return 0;}
    上面两个文件可以编译链接成功,而且不报警告。但运行结果肯定是从寄存器读出的野数据。如果func函数的参数是作为指针使用....,啊,那就麻烦大了。
    要解决问题,可以直接冲过去改掉就成,但如果程序是个大型项目,有1000个文件,那就。。。。。,所以正确的方法是防患于未然,养成良好的编码习惯才是。这种使用extern修改函数的方法尽量避免使用,

    2)常常见extern放在函数的前面成为函数声明的一部分,那么,C语言的关键字extern在函数的声明中起什么作用?
    A:如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。即下述两个函数声明没有明显的区别:
      extern int f(); 和int f();
     当然,这样的用处还是有的,就是在程序中取代include “*.h”来声明函数,在一些复杂的项目中,强烈推荐在所有的函数声明前添加extern修饰。

posted @ 2014-05-14 11:32  咚咚锵锵  阅读(149)  评论(0编辑  收藏  举报