Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 理解外部存储类_C_Extern - Fatal编程技术网

C 理解外部存储类

C 理解外部存储类,c,extern,C,Extern,你能不能请人给我解释一下下面问题的流程 #include <stdio.h> int main(){ extern int a; printf("%d\n",a); return 0; } int a = 20; 输出为20。我不确定变量a在哪里定义,在哪里声明?变量a在以下行中声明并定义为全局变量: int a = 20; extern行只告诉主函数作用域a是在另一个地方定义的 在这种情况下,实际上没有必要使用extern。您可以在main函数之前声明并定

你能不能请人给我解释一下下面问题的流程

#include <stdio.h>

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

int a = 20;
输出为20。我不确定变量a在哪里定义,在哪里声明?

变量a在以下行中声明并定义为全局变量:

int a = 20;
extern行只告诉主函数作用域a是在另一个地方定义的

在这种情况下,实际上没有必要使用extern。您可以在main函数之前声明并定义一个,然后main就会熟悉它


通常,如果要使用在另一个源文件中定义的变量或函数,而不是稍后在同一个源文件中定义的变量或函数,则可以使用extern。

如果将变量声明为extern,则表示该变量声明为全局变量,并且无法在其中初始化该变量。因为没有为该变量分配内存,因此无法将其初始化只是声明为变量 您可以在代码中的某个位置定义它

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

int main()
{
extern int i;
i=10;
printf("%d",sizeof(i));
}
这里您得到一个未定义int'i'的错误

因此,您需要将其写成:

int main()
{
    extern int i;
    int i=10;
    printf("%d",sizeof(i));
}
对于您的代码: 这是一份声明

extern int a;
这就是定义:

int a = 20;
存储类extern指定标识符所指对象的存储持续时间和链接:

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

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

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

如果标识符在块范围内被声明为extern,则表示该声明引用了外部定义。如果要声明的实体是一个对象,那么它具有静态存储,这仅仅是因为外部对象具有静态存储。它也可以是一个函数;函数并不是说有存储空间

在C语言中,有一个叫做链接的概念。在文件范围内的任何函数之外声明的对象和函数可以具有外部链接或内部链接

如果我们在块作用域中有extern,正如您在示例程序中所做的那样,则在文件作用域或嵌套作用域中可以有相同名称的previor声明,如下所示:

static int x;

/* ... */

  {
    extern int x;
  }
这里,内部x指的是外部x,尽管是外部的,但由于静态的原因,它具有内部链接

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

单词external指的是两个独立的概念:前面提到的外部链接和任何功能之外的含义,如外部声明。令人困惑的是,外部声明,如上面的静态int x,可以有内部链接

在您的程序中,情况是正确的,因为a的块作用域外部声明和后面的int a=20(它们位于不同的作用域中)恰好彼此独立地一致

int a=20;是一个外部声明,由于初始值设定项,它也是一个外部定义。因为在该范围内,没有可见的先前声明,所以它获得外部链接

那么,定义了什么?它被定义为具有外部链接的对象,在整个翻译单元中作为一个整体。这个翻译单位就是a的定义。声明出现在程序的每个地方;它的定义也是一种宣言。它在main中声明,也在翻译单元源代码的最后一行中声明

声明是使名称在某些范围内为人所知的语法。这是一个在程序翻译过程中活跃的概念。定义是在某个翻译单元中提供某个对象或功能的事实。翻译后的单元仍然提供定义,但不需要保留有关声明的信息。这就是为什么当我们创建库时,我们会提供包含声明的头文件


从主函数的角度来看,该函数不关心在何处定义。它以这样一种方式声明了a,即如果使用了a,则必须存在具有外部链接的a的外部定义。这个定义可以来自任何地方:它可以在同一个翻译单元中,也可以在另一个翻译单元中 ne pass,因此编译器只能从上到下处理每行一次。因此,考虑到您的计划:

#include <stdio.h>

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

int a = 20;
标识符a声明两次,定义一次

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

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


如果你把int a=20;在main之前,声明extern int a;这是没有用的,因为它没有添加任何内容。我倾向于将main和其他依赖函数放在源代码的最后,这样就只需要最少的额外声明。

Related:当您将变量声明为extern时,就意味着该变量被声明为全局变量。你能解释一下吗?我想你的意思是,声明为extern的变量在其他文件中声明为全局变量,但在我们提供其声明的文件中,它可以是局部变量。声明为extern的变量是全局变量。你可以在你的程序中的任何地方给它下定义,甚至在你的主函数之外。如果你需要这样的东西。你可以阅读yeshwanth kanethkar的《测试你的C技能》一书。或者您可以获得免费的在线pdf版本在C标准中,用于存储持续时间的术语是“静态持续时间”与“线程持续时间”、“自动持续时间”或“分配的持续时间”。同样,名称可见性是“内部链接”与“外部链接”与“无链接”。上的存储类不是静态的,但其存储持续时间是静态的。”这很棘手——有时我可能也会犯粗心大意的错误