“外部”的正确解释是什么? C 中的关键字?
在 此页面中,我无法理解为什么示例 3 会抛出错误:
// CODE 1:
extern int var;
int main(void)
{
var = 10;
return 0;
}
有几个答案提到 main 中的 var
是一个局部变量。但为什么它不能同时是一个全局变量呢?下面的代码工作起来很艰难:
// CODE 2:
int var; // global
int main(void)
{
var = 10;
return 0;
}
在多个文件的情况下...
...下面的代码工作:
// CODE 3:
// File 1
extern int var;
int main(void)
{
print("%d",var);
return 0;
}
----------------
// File 2
var = 4;
...而这个代码则不然:
// CODE 4:
// File 1
extern int var;
int main(void)
{
print("%d",var);
return 0;
}
----------------
// File 2
int func(int a) {
extern int var;
var = 3;
return 0;
}
所以我找不到对 extern< 的行为的有意义的解释/code> 关键字。您如何解释/解释该关键字?另外,我应该在代码中更改哪些内容才能使它们按预期工作?
In this page I cannot understand why Example 3 throws an error:
// CODE 1:
extern int var;
int main(void)
{
var = 10;
return 0;
}
There are several answers mentioning that var
inside main is a local variable. But why would it not be a global variable at the same time. This code below works tough:
// CODE 2:
int var; // global
int main(void)
{
var = 10;
return 0;
}
In the case of multiple files...
... the code below works:
// CODE 3:
// File 1
extern int var;
int main(void)
{
print("%d",var);
return 0;
}
----------------
// File 2
var = 4;
... while this one does not:
// CODE 4:
// File 1
extern int var;
int main(void)
{
print("%d",var);
return 0;
}
----------------
// File 2
int func(int a) {
extern int var;
var = 3;
return 0;
}
So I could not find a meaningful explanation to the behavior of the extern
keyword. How do you explain/ interpret that keyword? Also what should I change in the codes to make them work as intended?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 C 语言中,每个定义都是一个声明。有些声明是定义,有些则不是。
您链接到的页面有错误。一是它说“变量或函数的声明只是声明该变量或函数存在于程序中的某个位置,但没有为其分配内存。”事实上,这至少是两个错误。根据 C 2018 6.7 5,“声明指定一组标识符的解释和属性……”这并不一定意味着程序中实际存在具有声明名称的任何对象或函数。例如,如果我们包含
标头,则会声明fputc
函数,但是,如果我们从不使用它,它可能永远不会链接到程序中,因此程序中可能不存在这样的函数,即使在文件可执行文件中也是如此。不是定义的声明仅告诉编译器有关名称的信息(我们称之为标识符);它不传达有关某物是否存在的信息。该句子中的第二个错误是它表示没有为声明的变量或函数分配内存。这是不正确的,因为每个定义都是一个声明。 C 2018 6.7 5 继续“……标识符的定义是该标识符的声明: — 对于一个对象,导致为该对象保留存储; — 对于函数,包括函数体…”例如,
int x = 3;
是x
的声明,也是x<的定义/code>,它会导致为
x
分配内存,但您链接到的页面表示声明不会导致分配内存。所以页面是错误的。关于
extern
以及什么是定义、什么不是定义的规则很复杂,因为 C 是由多个人用它做不同的事情开发的。当 C 被标准化时,委员会必须协调不同的实践。因此,extern
没有单一的规则。关于术语的注释:变量实际上是两件事:标识符(其名称)和对象(存储其值的表示形式的内存)。
在代码 1 中,链接页面的示例 3,
extern int var;
是一个声明,而不是定义。没有定义。如果表达式中使用了具有外部链接的标识符,则程序中必须恰好有一个该标识符的外部定义(由 C 2018 6.9 5 规定)。由于没有外部定义,链接器会抱怨。如果在块内声明标识符,例如形成函数体的
{ … }
,则声明的效果对于该块来说是局部的。如果在任何函数外部声明标识符,则该声明的效果将持续到正在编译的文件的其余部分,除非它们被嵌套声明隐藏。如果
var
在任何函数外部且在main
之前声明,然后我们在main
内部使用该标识符而无需再次声明它,则使用 < code>var 指的是之前的声明。它不会创建或引用名为var
的新本地对象。在源代码中的任何一点,标识符最多指一件事。
var = 4
不是正确的 C 代码,因为它没有分号。如果是var = 4;
,某些编译器可能会在函数外部接受它,但它已经过时了。在现代 C 语言中,它应该有一个类型,例如int var = 4;
。这就是var
的正确定义。如果您的编译器在函数外部接受var = 4;
,您应该知道它正在接受旧代码,并且最好使用开关来告诉编译器需要现代 C 代码。In C, every definition is a declaration. Some declarations are definitions, and some are not.
The page you link to, has mistakes. One is it says that “Declaration of a variable or function simply declares that the variable or function exists somewhere in the program, but the memory is not allocated for them.” Actually, that is two mistakes, at least. Per C 2018 6.7 5, “A declaration specifies the interpretation and attributes of a set of identifiers…” This does not necessarily mean any object or function with the declared name actually exists in the program. For example, if we include the
<stdio.h>
header, thefputc
function is declared, but, if we never use it, it might never be linked into the program, and so no such function might exist in the program, even in the file executable file. A declaration that is not a definition only tells the compiler about the name (which we call the identifier); it does not convey information about whether something exists.A second mistake in that sentence is that it says memory is not allocated for the declared variable or function. This is incorrect because each definition is a declaration. C 2018 6.7 5 continues “… A definition of an identifier is a declaration for that identifier that: — for an object, causes storage to be reserved for that object; — for a function, includes the function body…” For example,
int x = 3;
is a declaration ofx
, and it is a definition ofx
, and it causes memory to be allocated forx
, but the page you link to says a declaration does not cause memory to be allocated. So the page is wrong.The rules regarding
extern
and what is or is not a definition are complicated because C was developed by multiple people doing different things with it. When C was standardized, the committee had to reconcile different practices. As a consequence, there is no single rule forextern
.A note about terminology: A variable is actually two things: an identifier (its name) and an object (the memory that stores a representation of its value).
In your CODE 1, the linked page’s Example 3,
extern int var;
is a declaration that is not a definition. There is no definition. If an identifier with external linkage is used in an expression, there must be exactly one external definition of it in the program (by C 2018 6.9 5). Since there is no external definition, the linker complains.If an identifier is declared inside a block, such as the
{ … }
that forms the body of a function, then effects of the declaration are local to that block. If an identifier is declared outside of any function, the effects of the declaration continue through the rest of the file being compiled, except where they are hidden by a nested declaration.If
var
is declared outside of any function and beforemain
, and then we use that identifier insidemain
without declaring it again, that use ofvar
refers to the previous declaration. It does not create or refer to a new local object namedvar
.At any one point in source code, an identifier refers to at most one thing.
var = 4
is not proper C code because it does not have a semicolon. If it werevar = 4;
, some compilers might accept this outside a function, but it is archaic. In modern C, it should have a type, such asint var = 4;
. That would then be a proper definition ofvar
. If your compiler acceptedvar = 4;
outside a function, you should be aware it is accepting old code, and it would be preferable to use switches to tell the compiler to require modern C code.