其他文件中的外部变量定义
extern variable definition in other file
您好,我有以下 2 个文件
在 a.c
我有
#include <stdio.h>
int i;
static int j;
int main()
{
printf("i = %d\n",i);
printf("j = %d\n",j);
return 0;
}
在b.c
我有
#include <stdio.h>
extern int i=2;
extern int j=5;
在这个例子中,当我 运行 时,我得到的答案是 2,0,但编译器对两个变量都发出警告 initialized and declared ‘extern’
。
b.c 如何能够访问 j
而不会抛出错误,因为 j
的范围仅适用于 a.c
?
a.c
#include <stdio.h>
int i;
static int j;
extern void display();
int main()
{
printf("i = %d\n",i);
printf("j = %d\n",j);
display();
return 0;
}
b.c
#include <stdio.h>
extern int i;
extern int j;
void display()
{
printf ("%d",j);
}
c.c
#include <stdio.h>
extern int i=2;
extern int j=5;
void display()
{
printf ("%d",j);
}
如果编译 a.c 和 b.c GCC 会报错
undefined reference to `j'.
因为程序试图访问未定义在 b.c
范围内的 j
如果你编译 a.c 和 c.c GCC 会像你所说的那样发出警告
warning: âjâ initialized and declared âexternâ
并假定 j 在 c.c 中定义并且不会抛出任何错误。
在您的情况下,如果您删除 b.c 中的赋值,您将不会在编译时发现任何错误,因为在 b.c 中没有访问 j 值的函数。
首先,在将变量声明为 extern 的同时初始化一个变量没有任何意义。这就是您收到编译器警告的原因。如果变量在文件范围内,C 允许它,但一如既往,C 允许很多坏事。
另请注意,使用 extern 几乎总是不好的做法,应该避免。
现在对于代码,i
的行为符合预期,因为两个文件中的 i
都引用相同的变量。另一方面,j
是 static
,因此该变量的范围缩小到本地文件。标准中有一条规则说,所有静态变量都必须初始化为 0,除非程序员明确地初始化它们。所以 j
的值将为 0.
由于 j
是静态的,extern int j;
指的是 "another j somewhere else",因为没有 j
变量对您编写 extern 的文件可见。由于程序未使用 "another j somewhere else",因此该变量将被丢弃。
static
和 extern
在很多方面是彼此相反的。如果您认为将同一个变量同时声明为static 和extern 是有意义的,那么您需要更多地研究static 关键字。
static
数据默认用 0
初始化,如果没有另外说明,这就是为什么你得到 0 作为答案,它与 b.c 模块无关。另外,一个变量不能同时声明 static
和 extern
,这对我来说听起来很矛盾。
当使用 extern
时,您应该只声明一个变量(没有 space 设置为将其保存在内存中),该变量的定义将在其他模块中。 extern
以一种简单的方式告诉编译器,嘿,不要担心这个变量在模块的其他地方定义,所以不要为它设置任何 space。
为什么你的编译器不报错? b.c 是否在您的程序中与 a.c 链接?尝试这样做,看看会发生什么。
您好,我有以下 2 个文件
在 a.c
我有
#include <stdio.h>
int i;
static int j;
int main()
{
printf("i = %d\n",i);
printf("j = %d\n",j);
return 0;
}
在b.c
我有
#include <stdio.h>
extern int i=2;
extern int j=5;
在这个例子中,当我 运行 时,我得到的答案是 2,0,但编译器对两个变量都发出警告 initialized and declared ‘extern’
。
b.c 如何能够访问 j
而不会抛出错误,因为 j
的范围仅适用于 a.c
?
a.c
#include <stdio.h>
int i;
static int j;
extern void display();
int main()
{
printf("i = %d\n",i);
printf("j = %d\n",j);
display();
return 0;
}
b.c
#include <stdio.h>
extern int i;
extern int j;
void display()
{
printf ("%d",j);
}
c.c
#include <stdio.h>
extern int i=2;
extern int j=5;
void display()
{
printf ("%d",j);
}
如果编译 a.c 和 b.c GCC 会报错
undefined reference to `j'.
因为程序试图访问未定义在 b.c
范围内的 j如果你编译 a.c 和 c.c GCC 会像你所说的那样发出警告
warning: âjâ initialized and declared âexternâ
并假定 j 在 c.c 中定义并且不会抛出任何错误。
在您的情况下,如果您删除 b.c 中的赋值,您将不会在编译时发现任何错误,因为在 b.c 中没有访问 j 值的函数。
首先,在将变量声明为 extern 的同时初始化一个变量没有任何意义。这就是您收到编译器警告的原因。如果变量在文件范围内,C 允许它,但一如既往,C 允许很多坏事。
另请注意,使用 extern 几乎总是不好的做法,应该避免。
现在对于代码,i
的行为符合预期,因为两个文件中的 i
都引用相同的变量。另一方面,j
是 static
,因此该变量的范围缩小到本地文件。标准中有一条规则说,所有静态变量都必须初始化为 0,除非程序员明确地初始化它们。所以 j
的值将为 0.
由于 j
是静态的,extern int j;
指的是 "another j somewhere else",因为没有 j
变量对您编写 extern 的文件可见。由于程序未使用 "another j somewhere else",因此该变量将被丢弃。
static
和 extern
在很多方面是彼此相反的。如果您认为将同一个变量同时声明为static 和extern 是有意义的,那么您需要更多地研究static 关键字。
static
数据默认用 0
初始化,如果没有另外说明,这就是为什么你得到 0 作为答案,它与 b.c 模块无关。另外,一个变量不能同时声明 static
和 extern
,这对我来说听起来很矛盾。
当使用 extern
时,您应该只声明一个变量(没有 space 设置为将其保存在内存中),该变量的定义将在其他模块中。 extern
以一种简单的方式告诉编译器,嘿,不要担心这个变量在模块的其他地方定义,所以不要为它设置任何 space。
为什么你的编译器不报错? b.c 是否在您的程序中与 a.c 链接?尝试这样做,看看会发生什么。