了解extern存储类

时间:2017-06-26 03:33:48

标签: c extern

请问有人向我解释下面问题的流程,

#include <stdio.h>

int main(){
   extern int a;
   printf("%d\n",a);
   return 0;
}

int a = 20;

,输出为20.我不确定变量的定义在哪里以及它在哪里被声明?

5 个答案:

答案 0 :(得分:2)

变量 UserName = GameObject.Find("inputUsuarioTextObj").gameObject.GetComponent<Text>().text; Password = GameObject.Find("inputPasswordTextObj").gameObject.GetComponent<Text>().text; 在行中声明并定义为全局变量

a

int a = 20; 行只是告诉extern函数范围main()在另一个地方定义。

在这种情况下,a的使用并不是必需的。您可以在 extern函数之前声明并定义a ,然后main()会熟悉它。

通常,当您想要使用在另一个源文件中定义的变量或函数时(而不是稍后在同一源文件中),您将使用main()。 / p>

答案 1 :(得分:1)

extern在语法上是一个“存储类”关键字。但是没有这样的存储类。 C具有“静态存储”,“动态存储(malloc等)和”自动存储“(局部变量,通常使用堆栈表示)。

如果在块作用域内声明了extern标识符,则表示声明引用了外部定义。如果声明的实体是一个对象,那么它具有静态存储,因为外部对象具有静态存储。它也可以是一个功能;据说没有存储功能。

在C中,有一个称为“联动”的概念。在文件范围和函数的任何函数之外声明的对象可以具有“外部”或“内部”链接。

如果我们在块作用域中有extern,就像在示例程序中一样,可以在文件范围或嵌套作用域中预先声明相同的名称,如下所示:

static int x;

/* ... */

  {
    extern int x;
  }

此处,内部x引用外部x,尽管是“外部”,但由于“静态”,它具有内部链接。

简而言之,extern通常意味着“引用先前的声明,如果没有声明,则将其声明为具有外部链接的标识符”。

“外部”一词指的是两个独立的概念:上述“外部联系”,也指“任何功能之外”的含义,如“外部声明”。令人困惑的是,“外部声明”,如上面的static int x,可以有“内部联系”!

在您的程序中,事情是正确的,因为extern的块范围a声明和后面的int a = 20声明位于不同的范围内,而独立彼此认同。

int a = 20;是一个外部声明,它也是一个外部定义(因为初始化器)。由于在该范围内,a的先前声明不可见,因此它具有外部链接。

那么,a定义在哪里?它在整个翻译单元中被定义为具有外部链接的对象。该翻译单元定义了a。在程序出现声明的每个地方都声明a;它的定义也是一个声明。它在main中声明,也在翻译单元源代码的最后一行中声明。

“声明”是在某些范围内使名称已知的语法。这是一个在程序翻译过程中活跃的概念。 “定义”是在某些翻译单元中提供某些对象或功能的事实。翻译单位仍提供定义,但无需保留有关声明的信息。 (这就是为什么当我们创建库时,我们提供带有声明的头文件!)

main函数的角度来看,该函数并不“关心”定义a的位置。它已声明a,如果使用a,则必须存在具有外部链接的a的外部定义。该定义可以来自任何地方:它可以在同一个翻译单元中,也可以在另一个翻译单元中。

答案 2 :(得分:1)

C编程语言被设计为一次通过,因此编译器只能从上到下处理每一行一次。所以考虑你的计划:

#include <stdio.h>

int main(){
   extern int a;
   printf("%d\n",a);
   return 0;
}

int a = 20;

标识符a被声明两次,并定义一次。

在第4行extern int a;之前,编译器对标识符a一无所知。 声明 extern int a;在函数main中具有块范围,并将标识符a声明为int,并且其存储持续时间为静态和链接是外部。因此,编译器可以编写通过名称a访问全局标识符的代码,作为{em>可以在另一个模块中定义的int变量(外部链接)。这是编译器在5中使用它时在printf行上执行的操作。

最后在第9行,int a = 20;是另一个声明定义。这声明并将a定义为具有静态存储持续时间和外部链接的int

如果您将int a = 20;放在main之前,则声明extern int a;将毫无用处,因为它不会添加任何内容。我倾向于在我的源代码中放置main和其他依赖函数 last ,因此需要最少量的额外声明。

答案 3 :(得分:0)

当你将变量声明为extern时,它意味着变量被声明为全局,你不能在那里初始化变量。因为没有为该变量分配内存它只是声明为变量 您可以在代码中的某个位置定义它。

让我们举个例子..考虑代码

int main()
{
extern int i;
i=10;
printf("%d",sizeof(i));
}

此处出现int 'i' is not defined

错误

因此你需要把它写成:

int main()
{
    extern int i;
    int i=10;
    printf("%d",sizeof(i));
}

如果您的代码: 这是声明

extern int a;

这是定义:

int a = 20;

答案 4 :(得分:0)

存储类extern指定标识符引用的对象的存储持续时间和链接:

存储持续时间设置为 static ,这意味着变量在程序运行的整个时间内都处于活动状态。当您在函数范围内声明该变量时,这在您的示例中很重要,因为在函数范围内,默认存储持续时间将是自动

链接设置为 external ,这意味着同一程序的不同翻译单元可以共享该对象。它具有副作用,即可以接受另一个(文件)作用域中的定义,如示例所示。这是共享性质的逻辑结果,您通常会在使用它的所有翻译单元中声明一个具有外部链接的变量,但只能在一个中定义它。