理解C语言中的关键字extern

最近写了一段C程序,编译时出现变量重复定义的错误,本身查看没发现错误。使用Google发现,本身对 extern理解不透彻,我搜到了这篇文章,写得不错。我拙劣的翻译了一下。(原文: http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/)

  我肯定这篇文章对c语言的初学者会有很大的帮助,由于这将使他们更好更熟练的使用c语言。因此就让我先来讲说extern关键字在变量和函数上的应用。最基本的extern关键字扩展了变量和函数的可见度。这可能就是它为何命名为extern的缘由。函数

几乎全部人都知道声明和定义变量(函数)的意义,可是为了这篇文章的完整性,我想弄清楚它们。声明一个变量(函数)只是代表这个变量(函数)存在于程序的某个地方,并无为它们分配内存。可是,声明变量(函数)具备重要做用,那就是说明变量(函数)的类型。所以,当一个变量声明,程序知道变量的类型,在函数声明的状况下,程序知道函数的参数和返回类型。这就是所谓的声明。来到定义,当咱们定义一个变量(函数),除了声明的做用,它也为该变量(函数)分配内存。所以,咱们能够认为声明是定义的子集。从上面的说明,显而易见,变量(函数)能够声明屡次,只能定义一次。翻译

如今回到咱们的主要目标:理解C语言中的关键字extern。我已经解释过声明定义的做用了,由于咱们必须借助它们来理解关键字extern。咱们先来了解一种简单的状况,extern对函数的做用。默认状况下,声明和定义一个函数,都有一个extern的前缀,这意味着在声明和定义函数时,前面不写extern,它也是默认存在的。例以下面的代码。code

int foo(int arg1, char arg2);

声明的函数前面没有extern,但编译器会在前面加上关键字extern,以下内存

extern int foo(int arg1, char arg2);

定义函数的状况和上面同样(函数的定义是指带有函数体)。所以,每当咱们定义一个函数的时候,前面总会有默认的关键字extern。因为声明能够屡次重复,定义只能完成一次,咱们能够看到一个函数的声明能够在多个C/H文件或单个的C/H文件中重复屡次。可是该函数实际只定义了一次(仅在一个文件中)。这样的函数在整个程序中都是可见的,任何文件任何地方均可以调用。(经过函数的声明,编译器在编译时就知道函数定义在哪里)。编译器

第二种状况,extern对变量的做用。如何声明一个变量而不定义它?这是一个理解extern对变量做用的重要问题,答案以下:it

extern int var;

在上面,一个整型变量var被声明(没有定义,没有分配内存)。而且,根据须要,咱们能够声明屡次。编译

如今,如何定义一个变量?答案以下:class

int var;

在这里,声明及定义了一个整型变量var(声明是定义的子集,定义一个变量就包含了声明),这里还为变量var分配了内存。如今,让咱们感到惊讶的是,当咱们定义或声明一个函数时,前面会有默认的extern,但对于变量的状况就不同了。若是变量也和函数同样,那么它们永远不会分配内存,它们仅仅被声明。所以,当咱们想要声明而不定义一个变量就须要加上关键字extern。此外extern将变量的能见度延伸到了整个程序,咱们知道变量声明和定义的地方,能够在整个程序的任何地方使用它们。下面借助几个例子来理解extern变量

int var;
int main(void)
{
   var = 10;
   return 0;
}

分析:程序编译成功,var是一个全局变量(隐势声明)扩展

extern int var;
int main(void)
{
  return 0;
}

分析:程序编译成功,这里var只被声明,其余地方没有使用var,因此没问题。

extern int var;
int main(void)
{
 var = 10;
 return 0;
}

分析:程序编译错误,因为声明了变量var,而没有在其余地方定义,从本质上讲,没有为var分配内存,程序又要给它赋值。

#include "somefile.h"
extern int var;
int main(void)
{
 var = 10;
 return 0;
}

分析:若是文件somefile.h文件中有定义变量var, 程序将会编译成功。

extern int var = 0;
int main(void)
{
 var = 10;
 return 0;
}

分析:猜猜上面的代码可否编译成功?在这里按照C的标准是能够编译经过的。声明一个变量并给它初始化一个值,则该变量的内存将被分配,即该变量被定义。(有的编译器会报告一个警告:warning: 'extern' variable has an initializer)

因此,咱们能够得出结论:

  1. 声明能够屡次,定义只能一次。
  2. 关键字extern用于扩展变量和函数的可见性。
  3. 因为函数默认存在extern,不须要再定义和声明的时候使用extern
  4. 当变量使用extern时,它只是声明没有定义。
  5. 当变量用extern声明而且有初始化时,和变量的定义同样。
相关文章
相关标签/搜索